Powershell Get-HotFix 查找文本文件中提供的更新

Powershell Get-HotFix find updates supplied in a text file

我正在为 Win 7 x64 ultimate 更新。我有一个文本文件,其中每行键入一个 KBnnnnn 条目。我想要某种 script/loop 来遍历文本文件中的每个条目并在已安装的更新中找到它。如果找到,则附加一个新的文本文件,其中包含 HotFixID、描述、日期等和状态 ='INSTALLED'。如果没有找到,status='NOT INSTALLED'

稍后我想通过模拟循环进程从文本文件中读取每个条目并将其卸载,在屏幕上和另一个文本日志文件中更新状态来选择性地卸载特定的 HotFixes。我是 PowerShell 的新手,尝试使用 WMIC 在 cmd 批处理脚本中创建一个循环,但还没有成功。

你为什么不为此使用 WSUS?这就是它存在的原因。

MS powershellgallery.com 中有适合这种用例的模块。

Find-Module -Name '*WSUS*' | Format-Table -AutoSize

Version Name              Repository Description                                                                                                                               
------- ----              ---------- -----------                                                                                                                               
2.3.1.6 PoshWSUS          PSGallery  PowerShell module to manage a WSUS Server. Support site: https://github.com/proxb/PoshWSUS/                                               
1.1.0   ecs.wsus          PSGallery  This Windows PowerShell module contains ECS.WSUS funtions                                                                                 
0.4.4   PSWsusSpringClean PSGallery  Give your WSUS server a thorough spring cleaning                                                                                          
0.9.0   PSWSUSMigration   PSGallery  Powershell module to help WSUS (Windows Server Update Services) server migration. Support site: https://github.com/reiikei/PSWSUSMigration

I am working on updates for Win 7 x64 ultimate.

那么,您在 Win7 上使用的是什么版本的 PowerShell?

I have a text file in which I have typed KBnnnnn one entry per line.

OK,一个标准文件,可以使用 Import-Csv 或 Get-Content 轻松读取。然而,你为什么要这样做?有一个名为 Get-HotFix 的 cmdlet 专门用于此。

# All Help topics and locations
Get-Help about_*
Get-Help about_Functions

Get-Help about* | Select Name, Synopsis

Get-Help about* | 
Select-Object -Property Name, Synopsis |
Out-GridView -Title 'Select Topic' -OutputMode Multiple |
ForEach-Object { Get-Help -Name $_.Name -ShowWindow }

explorer "$pshome$($Host.CurrentCulture.Name)"

# Get parameters, examples, full and Online help for a cmdlet or function

# Get a list of all functions
Get-Command -CommandType Function | 
Out-GridView -PassThru -Title 'Available functions'

# Get a list of all commandlets
Get-Command -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available cmdlets'

# get function / cmdlet details
Get-Command -Name Import-Csv -Syntax
(Get-Command -Name Import-Csv).Parameters.Keys
Get-help -Name Import-Csv -Full
Get-help -Name Import-Csv -Online
Get-help -Name Import-Csv -Examples

Get-Command -Name Get-Content -Syntax
(Get-Command -Name Get-Content).Parameters.Keys
Get-help -Name Get-Content -Full
Get-help -Name Get-Content -Online
Get-help -Name Get-Content -Examples


Get-Command -Name Get-Hotfix -Syntax
(Get-Command -Name Get-Hotfix).Parameters.Keys
Get-help -Name Get-Hotfix -Full
Get-help -Name Get-Hotfix -Online
Get-help -Name Get-Hotfix -Examples

I want sort of a script/loop

当然可以。

About ForEach

以上每个帮助文件都有循环的例子。

to go through each entry in text file and find it in installed updates.

好的,这很常见。一个 PowerShell 非常初学者的东西,在网络上有很多文章、示例和视频,并显示在帮助 cmdlet、资源等中。

If found append a new text file with HotFixID, Description, date etc., and status='INSTALLED'. If not found, status='NOT INSTALLED'

同样,这里没有什么新的或复杂的,这是很常见的事情,通过 -Append 开关或 Add-Content cmdlet 完成。

Get-Command -Name Add-Content -Syntax
(Get-Command -Name Add-Content).Parameters.Keys
Get-help -Name Add-Content -Full
Get-help -Name Add-Content -Online
Get-help -Name Add-Content -Examples

later I want to selectively uninstall specific HotFixes by simial loop process reading each entry from a text file and uninstalling it,

再说一次,这里没有什么新鲜的或复杂的,这是很常见的事情。您可以通过代码中的比较 block/command 来做到这一点。

About Comparison Operators

updating status on screen and in another text log file.

再说一次,这里没有什么新鲜的或复杂的,这是很常见的事情。这就是 Out-File 或 Export-Csv,或 Start-Transcript 或编写您自己的记录器用于和使用进度条的原因。很多文章、博客、视频都知道如何做到这一点。

Script Write-Log PowerShell Logging Function

Get-Command -Name Write-Progress -Syntax
(Get-Command -Name Write-Progress).Parameters.Keys
Get-help -Name Write-Progress -Full
Get-help -Name Write-Progress -Online
Get-help -Name Write-Progress -Examples

I am very new to PowerShell, tried to create a loop in cmd batch scripting using WMIC but no success yet.

好的,这很好。这意味着您应该先花时间学习它,并且有大量免费的 text-based 和 video-based(YouTube 视频、MSDN 视频等)供您使用。它所需要的只是您搜索它,使用它们 as-is 或根据需要进行调整。

'powershell windows hotfix management'

'Beginning PowerShell'

'Intermediate PowerShell'

'Advanced PowerShell'

'PowerShell file and folder management'

'PowerShell hotfix report'

示例脚本

'powershellgallery.com hotfix management'

'wmic find hotfix'

'vbscript wmic hotfix management'

这里的问题是,你为什么直接使用 WMIC 而不是 Powershell?因此,上面的 cmdlet。可以在 .bat/cmd/vbs 文件中使用 WMIC,而无需使用 PowerShell,多年来一直如此。

您说您已经完成了批处理文件编程,很高兴看到您涉足 PowerShell 池,但这并不意味着您不能坚持使用批处理来完成您需要的工作,然后立即将其转换为 PowerShell或更高版本。

根据您的代码评论更新

如果您在 console/ISE/VSCode 中执行此操作,它就像在 cmd.exe

中一样工作
wmic qfe get hotfixid > d:\temp\QfElist.txt 

Get-content -Path 'd:\temp\QfElist.txt' 
<#
Results

KB4537572  

KB4513661  

...
#>

但你本可以这样做并获得更有用的东西

Get-HotFix
<#
# Results

Source        Description      HotFixID      InstalledBy          InstalledOn              
------        -----------      --------      -----------          -----------              
LP70          Update           KB4537572     NT AUTHORITY\SYSTEM  11-Mar-20 00:00:00       
LP70          Update           KB4513661                          09-Sep-19 00:00:00       
LP70          Security Update  KB4515383                          09-Sep-19 00:00:00       
...
#>

将其与文件进行比较同样简单。假设您的文件如下所示。

$KBCheckList = '
KB4537572
KB4513661
KB4515400
' | Out-File -FilePath 'D:\Temp\KBCheckList.txt'

现在读取文件,使用这个

Get-Content -Path 'D:\Temp\KBCheckList.txt'
<#
# Results

KdId
KB4537572
KB4513661
KB4515400
#>

或这个

Import-Csv -Path 'D:\Temp\KBCheckList.txt'
<#
# Results

WARNING: One or more headers were not specified. Default names starting with "H" have been used in place of any missing headers.

H1       
--       
KB4537572
KB4513661
KB4515400
#>

您可以看到差异很小(在视觉上),但 Csv 文件需要一个 header(实际上应该先正确格式化)。将其添加到文件顶部或即时添加

Import-Csv -Path 'D:\Temp\KBCheckList.txt' -Header 'KBID'
<#
# Results

KBID     
----     
KB4537572
KB4513661
KB4515400
#>

以上都是对你的教育。你真的只需要下面两个中的一个,或者类似的。

现在只需使用该文件。循环读取并使用if/then或try/catch语句得到结果

Import-Csv -Path 'D:\Temp\KBCheckList.txt' -Header 'KBID' | 
ForEach {
    $PSItem.KBID
}
<#
# Results

KB4537572
KB4513661
KB4515400
#>

或者只是将文件列表与 cmdlet 的结果进行比较

$QfeData = Get-Hotfix
$KBCheckList = Import-Csv -Path 'D:\Temp\KBCheckList.txt' -Header 'KBID' 
Compare-Object -ReferenceObject $QfeData.HotFixID -DifferenceObject $KBCheckList.KBID
<#
# Results

InputObject SideIndicator
----------- -------------
KB4515400   =>            *** this means that this ID is only in the DifferenceObject which is your file, thus not installed.    
KB4515383   <=           
KB4516115   <=           
KB4517245   <=           
KB4521863   <=           
KB4524244   <=           
KB4524569   <=           
KB4525419   <=           
KB4528759   <=           
KB4537759   <=           
KB4538674   <=           
KB4541338   <=           
KB4551762   <= 
#>