我有一个csv文件,我解析它以获取用于在用户在独立环境中应用它们后查询是否存在修补程序的KB信息。我已成功地使查询工作(大部分时间),但我希望更清晰的输出。
代码很基本:
$array = Import-Csv .\2K8R2Patches.csv -header Patchname
foreach ($patch in $array){
$PatchID = $patch -split('-') | Select-String -Pattern "KB"
$HotFix = Get-HotFix -Id $PatchID -ErrorAction 0;
if ($HotFix)
{
Get-HotFix -Id $PatchID | Format-Table HotFixID, Description, InstalledOn -AutoSize | Out-File -Append .\PatchInstalled.txt
}
if (-Not ($HotFix))
{
Write-Host "Patch" $PatchID "is NOT installed" | Out-File -Append .\PatchInstalled.txt
}
}
对于已安装的修补程序,输出文件如下所示:
HotFixID说明InstalledOn
-------- ----------- -----------
KB3087038安全更新9/21/2015 12:00:00 AM
HotFixID说明InstalledOn
-------- ----------- -----------
KB3069114安全更新9/21/2015 12:00:00 AM
HotFixID说明InstalledOn
-------- ----------- -----------
KB3074543安全更新9/21/2015 12:00:00 AM
HotFixID说明InstalledOn
-------- ----------- -----------
KB3084135安全更新9/21/2015 12:00:00 AM
HotFixID说明InstalledOn
-------- ----------- -----------
KB3087039安全更新9/21/2015 12:00:00 AM
HotFixID说明InstalledOn
-------- ----------- -----------
KB3087918安全更新9/21/2015 12:00:00 AM
正如你所看到的那样 - 数据就在那里,但我希望它更具表格性,而且我不知道是不是想弄清楚那部分。
答案 0 :(得分:2)
答案 1 :(得分:2)
好的,让我们从顶部开始......一个包含1列且没有标题的CSV文件不是CSV,它是一个带有身份危机的文本文件。我们只需使用Get-Content
代替。
$array = Get-Content .\2K8R2Patches.csv
好的,所以我们有一个字符串数组,以某种方式分隔连字符,并在那里包含一个KB#。你使用Select-String
的管道做了什么,但它就像用渔网捕捉棒球一样:它会起作用,但有更好的方法可以做到。实质上发生的是你将每个字符串分成一个字符串数组,然后将这些字符串过滤掉包含字母' kb'以该顺序。 Where
语句会做得更好(当找不到KB时,您的方法会传递空白,Where
语句不会这样做),我们可以优化RegEx匹配更好地避免在字符串中某处可能包含字母KB的任何字符串。让我们得到一个我们想要查找的KB数组,这样我们就可以在括号中包含get-content
命令,将它分开输出就像你一样是,并管道我们Where
声明!是的,那将是好的,我们只是阅读我们真正想要的信息。
$array = (Get-Content .\2K8R2Patches.csv) -split "-" | Where{$_ -match "^KB\d+$"}
有关位于this RegEx101 link的正则表达式匹配的更多信息。
所以我们现在$array
看起来像这样:
KB3087038
KB3069114
KB3074543
KB3084135
KB3087039
KB3087918
很好,现在我要采取的路径与你的路径略有不同。我要收集计算机上安装的所有修补程序,这样我们只需要调用一次命令。当我使用您在我的计算机上列出的6 KB进行测试时,用7.6秒查询它上面的每个KB(就像您所做的那样),相比之下列出所有已安装的修补程序的1.4秒并过滤掉列表6.然后我们根据$array
中的列表过滤安装的那些,然后我们将处理丢失的KB。
[array]$HotFixes = Get-HotFix | Where{$array -contains $_.HotFixID}
好的,那就是我们拥有的,现在用于未安装的修补程序。请注意,我指定$HotFixes
是一个数组,所以即使它只找到1个已安装的修补程序,它也会是一个包含1个项目的数组(如果没有找到,则为空数组)。这很重要,因此我们可以为每个未安装的修补程序向该阵列添加更多项目。因此它很好地输出我将为每个未安装的修补程序创建对象,并且每个对象将具有我们将从我们具有的修补程序输出的属性:HotFixID,Description, InstalledOn
$array | Where{$HotFixes.HotfixID -notcontains $_} | ForEach{$HotFixes += New-Object PSObject -Property @{
'HotFixID' = $_
'Description' = 'Not Installed'
'InstalledOn' = ''
}}
现在,我们已经导入了所有修补程序,如果我们导出为CSV,则可以很好地输出以便在Excel中查看(在调整列宽之后)。
$Hotfixes | Export-CSV .\2K8R2Hotfixes.csv -NoTypeInformation
Invoke-Item .\2K8R2Hotfixes.csv