使用 Powershell 检查程序是否安装在多台计算机上
Check If a program is installed on multiple computers using Powershell
我写的脚本有问题,希望得到一些帮助。
请注意我是 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 文件中的最后一台机器完成后停止。
如有任何帮助或建议,我们将不胜感激。
这是使用 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
}
你可以试试这个:
$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
已被弃用。
更正:正确的名称是卡巴斯基;我更正了。
我写的脚本有问题,希望得到一些帮助。 请注意我是 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 文件中的最后一台机器完成后停止。
如有任何帮助或建议,我们将不胜感激。
这是使用 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
}
你可以试试这个:
$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
已被弃用。
更正:正确的名称是卡巴斯基;我更正了。