我有一个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
HotFixID描述InstalledOn
KB3069114安全更新9/21/2015 12:00:00
HotFixID描述InstalledOn
KB3074543安全更新9/21/2015 12:00:00
HotFixID描述InstalledOn
KB3084135安全更新9/21/2015 12:00:00
HotFixID描述InstalledOn
KB3087039安全更新9/21/2015 12:00:00
HotFixID描述InstalledOn
KB3087918安全更新9/21/2015 12:00:00
所以,正如你所看到的--所有的数据都在那里,但是我希望它是表格化的,我一直在努力弄清楚这个部分。
发布于 2015-11-04 18:08:01
您可以创建一个对象,然后将输出导出到csv或.
$array = Import-Csv .\2K8R2Patches.csv -header Patchname
$patches = @()
foreach ($patch in $array) {
$PatchID = $patch -split('-') | Select-String -Pattern "KB"
$HotFix = Get-HotFix -Id $PatchID -ErrorAction 0;
if ($HotFix)
{
$object = New-Object -TypeName psobject -Property @{
HotFixID = $HotFix.HotFixID
Description = $HotFix.Description
InstalledOn = $HotFix.InstalledOn
}
$patches += $object
}
Else
{
$nopatch = New-Object -TypeName psobject -Property @{
HotFixID = $PatchID
InstalledOn = "Not Installed"
Description = "Not Installed"
}
$patches += $nopatch
}
}
$patches |select HotFixID, Description, InstalledOn| Out-File mypath\patch.txt
结果是,如果没有安装KB,它将发出“未安装”令状。
发布于 2015-11-04 18:58:51
好吧,我们从最上面开始.带有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+$"}
更多关于regex匹配的信息位于这个RegEx101链接。
现在我们有了类似于这样的$array
:
KB3087038
KB3069114
KB3074543
KB3084135
KB3087039
KB3087918
太好了,现在我要走一条和你稍微不同的路。我将收集安装在计算机上的所有修补程序,这样我们只需要调用一次命令。当我用您在机器上列出的6KBS进行测试时,只需7.6秒就可以自己查询每个KB (就像您所做的那样),相比之下,列出安装的所有修补程序并根据列表6进行筛选只需1.4秒,然后根据$array
中的列表过滤安装的修补程序,然后处理丢失的KB。
[array]$HotFixes = Get-HotFix | Where{$array -contains $_.HotFixID}
好的,这就是我们有的,现在对于未安装的修补程序。请注意,我指定了$HotFixes
是一个数组,所以即使它只找到一个已安装的修补程序,它也将是一个带有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
https://stackoverflow.com/questions/33528753
复制相似问题