【问题标题】:Powershell Script for Removing Windows updates (APC_Index_BSOD)用于删除 Windows 更新的 Powershell 脚本 (APC_Index_BSOD)
【发布时间】:2021-03-15 18:00:06
【问题描述】:

寻求一些帮助,找到一种通过 PowerShell 删除 Windows 更新的简单方法,但是我相信我遇到了几个问题。

目标

  1. 根据$data_array 中的数据检查并卸载更新
  2. 暂停 Windows 更新,直到可以按下修补程序或更新
  3. 了解工作如何更好地工作

问题

  1. 我不相信 $data 被发送到 wusa /uninstall /kb:$data /promptrestart 的主要原因是我认为这是来自 Windows 更新独立安装程序的错误在没有包号的情况下引发错误(图 1)
  2. 每项工作都是一次启动,而不是交错进行,我的工作经验非常有限,我不知道从哪里开始进行故障排除。我尝试过使用Get-Job | Retrieve-Job,但似乎没有获得太多关于状态或返回变量的信息
  3. 我想为这些工作命名,以便更具体地了解哪些工作已完成或处于哪个步骤

代码片段

# Updates to Find
$data_array =@('KB5000802','KB5000808','KB5000822','KB5000809')

$commands = @()
# Checks Which update is installed
$commands += {
    $Name = "Check Updates"
    foreach($data in $data_array)
    {
        if(wmic qfe list brief /format:table | Select-String -Pattern $data -CaseSensitive -SimpleMatch)
        {
            $commands+=$data
        }
    }
}

# Uninstall Update
$commands += {
    echo "Uninstalling Found Update of: "$data
    wusa /uninstall /kb:$data /promptrestart
}

# Stops Windows Update
$commands += {
    net stop wuauserv
    net pause wuauserv
    net stop bits
    net pause bits
    net stop dosvc
    net pause dosvc
}

# Runs the Jobs
foreach($command in $commands){
    start-job $command
}

PS 输出

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
39     Job39           BackgroundJob   Running       True            localhost            ...                      
41     Job41           BackgroundJob   Running       True            localhost            ...                      
43     Job43           BackgroundJob   Running       True            localhost            ...                      

图 1

我们将不胜感激任何帮助或指导,并且可以根据需要提供其他信息。

谢谢!

【问题讨论】:

  • 这里使用jobs的目的是什么?通常它们仅在您希望并行完成时使用,但在您的情况下,一切都应该按顺序完成,因此使用作业没有意义。你只是让你的脚本复杂化了。
  • 没有其他原因是我的几个同事试图引导我这样做。如果有更好的方法,我会全力以赴。

标签: arrays powershell


【解决方案1】:

我会通过删除工作内容来简化脚本。除非你真的需要在后台运行,否则只会让事情复杂化。即使需要后台操作,在并行化之前先创建一个有效的线性脚本也会很有帮助。

# Updates to find
$searchUpdates = 'KB5000802','KB5000808','KB5000822','KB5000809'

Write-Host "Checking whether the following updates are installed: $($searchUpdates -join ', ')"

# Checks which updates are installed

$allUpdates = wmic qfe list brief /format:table

$foundUpdates = $searchUpdates | Where-Object { 
    $allUpdates | Select-String -Pattern $_ -CaseSensitive -SimpleMatch }

if( $foundUpdates ) {
    Write-Host "Found the following installed updates: $($foundUpdates -join ', ')"

    # Uninstall the found updates

    foreach( $update in $foundUpdates ) {
        Write-Host "Uninstalling found update of: $update"
        wusa /uninstall /kb:$update /promptrestart

        # TODO: check $LASTEXITCODE to determine whether removal was successful
    }

    Write-Host 'Stopping windows update...'

    net stop wuauserv
    net pause wuauserv
    net stop bits
    net pause bits
    net stop dosvc
    net pause dosvc
}
else {
    Write-Host 'None of these updates are installed.'
}

进一步的变化:

  • 删除了数组子表达式运算符@(),因为逗号分隔的列表已经定义了一个数组
  • 只查询一次wmic 以提高性能
  • 将第一个 foreach 替换为 Where-Object 语句。
  • 为清晰起见重命名了一些变量
  • 添加了更多日志记录,以便您验证中间结果
  • echo 替换为Write-Host,这样以后的访问者可以更轻松地查找文档

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    相关资源
    最近更新 更多