我在这里做的是生成PRTG在运行脚本时可以解析的XML输出。该脚本旨在确定最后一次Windows更新安装的时间。它适用于所有远程服务器,但是当它在本地计算机上运行时,它没有获得正确的$值。它最终为null,而不是整数。我假设我在这里遗漏了一些关于Invoke-Command如何在本地服务器和远程服务器上工作的东西。有人会介意我告诉我哪里犯了错误吗?
{{1}}
答案 0 :(得分:0)
首先,您不应该为本地系统执行 Invoke-command 。您可以对结果进行验证。
其次,要在本地调用,您需要在本地系统的TrustedHosts列表中添加本地系统的IP /主机名,这是没有意义的。
我在代码中使用 wmi-object 对 Win32_Computersystem 进行了验证,该代码应执行此操作要紧的。
$ErrorActionPreference = "Stop"
#Get a list of servers
$servers = Get-ADComputer -SearchBase 'DC=<removed>,DC=int' -Filter {OperatingSystem -NotLike "Windows Server 2003*"} | Sort Name | Select -ExpandProperty Name
$value = ""
#This is the start of the XML output that PRTG will be parsing when the code runs
Write-Host "<prtg>"
#Loop through all servers and attempt to get a value for last windows update install.
foreach($server in $servers) {
Write-Host "`t<result>`n`t<channel> $server </channel>"
try {
$LocalNetwork=Get-WmiObject Win32_Computersystem;
## IF its a local system, then it will go inside IF
if($LocalNetwork.Name -eq ($server.trim()))
{
$props = @{
LastDetect = Get-ItemProperty -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Detect’ -Name LastSuccessTime | select -ExpandProperty LastSuccessTime
LastInstall = Get-ItemProperty -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Install’ -Name LastSuccessTime | select -ExpandProperty LastSuccessTime
}
$stringdato = $props.LastInstall;
$DATO = ([datetime]::ParseExact($stringdato, "yyyy-MM-dd HH:mm:ss", $null))
$today = (Get-Date)
$timeout = ($today - $DATO)
$value = $timeout.Days
}
## If its a remote system, it will go inside else and will do invoke
else {
Invoke-Command -ComputerName $server -ScriptBlock {
$props = @{
LastDetect = Get-ItemProperty -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Detect’ -Name LastSuccessTime | select -ExpandProperty LastSuccessTime
LastInstall = Get-ItemProperty -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Install’ -Name LastSuccessTime | select -ExpandProperty LastSuccessTime
}
$stringdato = $props.LastInstall;
$DATO = ([datetime]::ParseExact($stringdato, "yyyy-MM-dd HH:mm:ss", $null))
$today = (Get-Date)
$timeout = ($today - $DATO)
$value = $timeout.Days
}
}
}
catch {
# set value to 999 if there is a problem, for PRTG's error threshold.
$value = 999
}
Write-Host "`t<value>$value</value>"
Write-Host "`t<CustomUnit>days</CustomUnit>`n`t<LimitMaxError>90</LimitMaxError>`n`t<LimitMaxWarning>60</LimitMaxWarning>`n`t<LimitMode>1</LimitMode>`n`t</result>`n"
}
Write-Host "</prtg>"
注意:我没有完成每一步,我只是在 foreach 循环中保留了验证。希望它有所帮助。
答案 1 :(得分:0)
添加$value
作为ScriptBlock
cmdlet的Invoke-Command
的最后一条语句。 $value
的值应存储在$result
。
...
$result = Invoke-Command -ComputerName $server -ScriptBlock {
...
$timeout = ($today - $DATO)
$value = $timeout.Days
$value # <---- ADD THIS LINE
...
我认为它与PowerShell远程处理的序列化过程有关(可能是&#34;自动序列化&#34;已分配的最后一个变量)。 &#34;通常&#34;如果要从PowerShell脚本块返回值,则可以调用变量,如&#34; $ var&#34;。因此,$var
的内容将沿着管道发送。有关详细信息,请参阅此thread的答案。
作为替代方案,您还可以在脚本中添加以下行:
return $value
OR:
$value # <----- sent the content of $value down the pipeline
return
希望有所帮助