Powershell援助

时间:2014-06-18 12:53:59

标签: powershell

我目前正在使用以下PS脚本来检查系统上是否安装了MS补丁。该脚本设置为检查$env:COMPUTERNAME.mbsaPatch_NA.txt文件,并将结果发送到$env:COMPUTERNAME.csv文件。

我现在需要修改此脚本,以便从同一位置(POS)的其他C:\Users\Cambridge\SecurityScans设备提取信息,并将结果发送到$env:COMPUTERNAME.csv filePOS设备列出如下:

172.26.210.1.mbsa  
172.26.210.2.mbsa  
172.26.210.3.mbsa

等等。
我们所有位置(最后一个八位字节)的IP范围是1 - 60。关于如何设置它的任何想法?

脚本:

$logname = "C:\temp\PatchVerify\$env:COMPUTERNAME.csv"
[xml]$x=type "C:\Users\Cambridge\SecurityScans\$env:COMPUTERNAME.mbsa"

#This list is created based on a text file that is provided.
$montlyPatches = type "C:\Temp\PatchVerify\Patches_NA.txt"|
foreach{if ($_ -mat"-KB(?   <KB>\d+)"){$matches.KB}}

 $patchesNotInstalled=$x.SecScan.check | where {$_.id -eq 500} |foreach{`
 $_.detail.updatedata|where {$_.isinstalled -eq "false"}}|Select -expandProperty KBID

 $patchesInstalled =$x.SecScan.check | where {$_.id -eq 500} |foreach{`
$_.detail.updatedata|where {$_.isinstalled -eq "true"}}|Select -expandProperty KBID

"Store,Patch,Present"> $logname

$store = "$env:COMPUTERNAME"


foreach ($patch in $montlyPatches)
{
$result = "Unknown"
if ( $patchesInstalled -contains $patch)
{
  $result = "YES"
}
if ( $patchesNotInstalled -contains $patch)
{
  $result = "NO"
}

"$store,KB$($patch),$result" >>$logname
 }  

1 个答案:

答案 0 :(得分:0)

您可以在网上找到有关创建功能的大量信息,但一个简单的例子是:

Function Check-Patches{
Param($FileName)
    $logname = "C:\temp\PatchVerify\$FileName.csv"
    [xml]$x=type "C:\Users\Cambridge\SecurityScans\$FileName.mbsa"
    The rest of your existing code goes here...

}

Check-Patches "$env:ComputerName"
For($i=1;$i -le 60;$i++){
    Check-Patches "172.26.210.$i"
}

如果你需要我打破任何事情,让我知道,我会进一步解释,但从你已经拥有它看起来你对PowerShell理论有一个很好的把握,只需要知道什么资源可用。

编辑:我更新了我的示例以更好地适应您的脚本,让它接受文件名,然后将该文件名应用于函数中的$ logname和$ x变量。

分解......

首先我们声明我们正在使用Function关键字创建一个Function。接下来是您稍后将用它来调用它的函数的名称,以及一个用于启动构成实际函数的scriptblock的开始大括号。

接下来是Param行,在这种情况下非常简单,只将一个变量声明为输入。这也可以作为Function Check-Patches ($FileName){来完成,但是当你开始进入更高级的功能时只会让人感到困惑,所以我的建议是坚持将参数放在函数的scriptblock中。在大多数情况下,这是您在函数内部首先要做的事情,不包括您为函数编写的任何帮助。

然后我们更新了$logname[xml]$x的行,这些行使用函数获取的$ FileName作为输入。

之后会出现解析补丁日志,输出到CSV以及结束scriptblock的结束大括号和函数的所有代码。

然后我们将它称为ComputerName,并运行For循环。 For循环运行1到60之间的所有内容,对于每个循环,它使用该数字作为文件名的最后一个八位字节,以输入函数并检查这些文件。

对其余代码的一些评论。 $monthlypatches =可以更改为= type | ?{$_ -match "-KB(? <KB>\d+)"}|%{$matches.KB},以便在ForEach循环之前过滤结果,这可能会缩短一段时间。

在$ patchesInstalled和$ patchesNotInstalled行中,您不需要该行末尾的反引号。在脚本块开始之后,对于ForEach循环,您自然会有一个换行符。有了它,如果脚本中断,以后会很难看到,如果后面有任何内容(包括空格),脚本可能会破坏并抛出难以追踪的错误。

最后,你循环$ x两次,然后$ monthlyPatches一次,并对日志文件进行大量的单独写入。我建议创建一个数组,用自定义对象填充它有3个属性(Store,Patch和Present),然后在函数末尾输出。这会稍微改变一下,但是你的函数会输出一个对象,你可以将其输出到Export-CSV,或者稍后你可能希望它做其他的事情,但至少你可以拥有它。为此,我通过一个开关运行$ x来查看是否已经安装了东西,然后通过将该阵列中尚未包含的所有月份补丁设置为“未知”来清除阵列。那会是这样的:

Function Check-Patches{
Param($FileName)
    $logname = "C:\temp\PatchVerify\$FileName.csv"
    [xml]$x=type "C:\Users\Cambridge\SecurityScans\$FileName.mbsa"
    $PatchStatus = @()

    #This list is created based on a text file that is provided.
    $monthlyPatches = GC "C:\Temp\PatchVerify\Patches_NA.txt"|?{$_ -match "-KB(?   <KB>\d+)"} | %{$matches.KB}

    #Create objects for all the patches in the updatelog that were in the monthly list.
    Switch($x.SecScan.Check|?{$_.KBID -in $monthlyPatches -and $_.id -eq 500}){
        {$_.detail.updatedata.isinstalled -eq "true"}{$PatchStatus+=[PSCustomObject][Ordered]@{Store=$FileName;Patch=$_.KBID;Present="YES"};Continue}
        {$_.detail.updatedata.isinstalled -eq "false"}{$PatchStatus+=[PSCustomObject][Ordered]@{Store=$FileName;Patch=$_.KBID;Present="NO"};Continue}
    }

    #Populate all of the monthly patches that weren't found on the machine as installed or failed
    $monthlyPatches | ?{$_ -notin $PatchStatus.Patch} | %{$PatchStatus += [PSCustomObject][Ordered]@{Store=$FileName;Patch=$_;Present="Unknown"}}

    #Output results
    $PatchStatus
}

#Check patches on current computer
Check-Patches "$env:ComputerName"|Export-Csv "C:\temp\PatchVerify\$env:ComputerName.csv" -NoTypeInformation

#Check patches on POS Devices
For($i=1;$i -le 60;$i++){
    Check-Patches "172.26.210.$i"|Export-Csv "C:\temp\PatchVerify\172.26.210.$i.csv" -NoTypeInformation
}