0

我对我编写的脚本有疑问,希望得到一些帮助。请注意,我对 powershell 很陌生。

我编写了一个脚本,该脚本使用包含域上远程计算机的 txt 文件,我似乎在某种程度上正在工作,但如果机器脱机,我会收到错误,然后循环脚本。

$machines
$pcname
Name = 'Machine'
Expression = { $_.PsComputerName }
}

ForEach ($System in $Machines)
{
    #Pings machine's found in text file
    if (!(test-Connection -ComputerName $System -BufferSize 16 -Count 1 -ea 0 -Quiet))
    {
        Write-Output "$System Offline"
    }

Else
   {
     #Providing the machine is reachable 
     #Checks installed programs for products that contain Kaspersky in the name
     gwmi win32_product -Filter {Name like "%Kaspersky%"} -ComputerName $Machines | Select-Object -Property $pcname,Name,Version
   }
}

目前这个运行和输出是这样的:

Machine          Name                                        Version
UKTEST01         Kaspersky Security Center Network Agent     10.1.249 
UKTEST02         Kaspersky Endpoint Security 10 for Windows  10.2.1.23

但是如果机器无法访问,则会出现以下错误:

gwmi : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At C:\Scripts\Powershell\Kaspersky Endpoint Security 10\Script\New folder\Kaspersky Checker working v2.ps1:15 char:9
+         gwmi win32_product -Filter {Name like "%Kaspersky%"} -ComputerName   $Mach ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

然后移动到列表中的下一台机器,然后从头开始重复。

我希望它简单地显示为:

UKTEST03 Offline

并在 txt 文件中的最后一台机器完成后停止。

任何帮助或建议将不胜感激。

4

2 回答 2

1

这是使用 Try/Catch/Finally 块的最佳时机。流程是这样的:尝试这里的代码块,如果遇到错误,取消消息并执行 Catch 块中的内容。

我已经稍微修改了您的代码,因此只需复制整个代码块并将其放入,替换原始代码中的 Else {scriptblock} 即可。

Else
{
 #Providing the machine is reachable 
 #Checks installed programs for products that contain Kaspersky in the name
 Try {Get-WMIObject -Class win32_product -Filter {Name like "%Kaspersky%"} `
   -ComputerName $Machines -ErrorAction STOP | 
      Select-Object -Property $pcname,Name,Version }
 Catch {#If an error, do this instead
        Write-Output "$system Offline }
  }
}

你完成的答案

我已经折叠了您请求的更改,以防止您的脚本在 $machines 而不是 $system 中的每台机器上运行,正如您可能想要的那样。

ForEach ($System in $Machines){
    #Pings machine's found in text file
    if (!(test-Connection -ComputerName $System -BufferSize 16 -Count 1 -ea 0 -Quiet))
    {
        Write-Output "$System Offline"
    }
    Else
    {
     #Providing the machine is reachable 
     #Checks installed programs for products that contain Kaspersky in the name
     Try {Get-WMIObject -Class win32_product -Filter {Name like "%Kaspersky%"} `
       -ComputerName $System -ErrorAction STOP | 
          Select-Object -Property $pcname,Name,Version }
     Catch {#If an error, do this instead
            Write-Output "$system Offline "}
     #EndofElse
     }
#EndofForEach
}
于 2015-03-30T15:12:04.567 回答
1

你可以试试这个:

$machines=... # your machines' names
foreach ($machine in $machines)
{
    trap{"$machine`: not reachable or not running WsMan";continue}
    if(test-wsman -ComputerName $machine -ea stop){
        gcim -Class CIM_Product -Filter 'Name like "%Kaspersky%"' |
            select pscomputername,name,version
    }
}

我正在使用gcim,因为gwmi已弃用。

更正:正确的名称是Kaspersky;我纠正了它。

于 2015-03-31T06:13:51.197 回答