我运行一个执行许多WMI查询的脚本 - 但如果服务器没有回答,则cmdlet会挂起。 有没有什么方法可以让这个(或任何其他cmndlet)超时并在X秒过去时退出?
修改
感谢来自mjolinor的提示,解决方案是将其作为-asjob运行并在while循环中设置超时。但是这已经从一个工作中运行(从Start-Job开始)。那么我怎么知道我正在控制正确的工作呢?
这是我已经开始的工作中的代码:
Get-WmiObject Win32_Service -ComputerName $server -AsJob
$Complete = Get-date
While (Get-Job -State Running){
If ($(New-TimeSpan $Complete $(Get-Date)).totalseconds -ge 5) {
echo "five seconds has passed, removing"
Get-Job | Remove-Job -Force
}
echo "still running"
Start-Sleep -Seconds 3
}
PS:我的工作始于Start-Jobs已经处理好了..
答案 0 :(得分:2)
我见过这个问题的唯一两个解决方案是:
将查询作为后台作业运行并为其设置计时器,然后停止/删除运行时间过长的作业。
修复服务器。
答案 1 :(得分:2)
您可以尝试发布here的get-wmiCustom函数。如果get-wmiObject有超时参数会不会很好?让我们upvote this thing。
答案 2 :(得分:2)
很高兴我的Get-WmiCustom功能http://blogs.msdn.com/b/dmuscett/archive/2009/05/27/get_2d00_wmicustom.aspx很有用。
答案 3 :(得分:1)
除了已经说过的,不是防弹解决方案,而是考虑首先ping你的服务器(Test-Connection
),它可以加快执行时间,以防你没有响应的机器。
答案 4 :(得分:0)
使用get-wmiobject创建作业时,将该作业分配给变量,然后该变量可以通过管道传输到get-job for status或receive-job for results
$ThisJob = start-job -scriptblock {param ($Target) Get-WmiObject -Class Win32_Service -ComputerName $Target -AsJob} -ArgumentList $server
$Timer = [System.Diagnostics.Stopwatch]::StartNew()
While ($ThisJob | Get-Job | where {$_.State -imatch "Running"}){
If ($Timer.Elapsed.Seconds -ge 5) {
echo "five seconds has passed, removing"
$ThisJob | Get-Job | Remove-Job -Force
} # end if
echo "still running"
Start-Sleep -Seconds 3
} # end while
$Results = $ThisJob | where {$_.State -inotmatch "failed"} | receive-job
$Timer.Stop | out-null
答案 5 :(得分:0)
我修改了Daniel Muscetta的Get-WmiCustom以支持传递凭证。
我知道这篇文章有点老了,希望这有助于其他人。
# Define modified custom get-wmiobject for timeout with credential from http://blogs.msdn.com/b/dmuscett/archive/2009/05/27/get_2d00_wmicustom.aspx
Function Get-WmiCustom([string]$Class,[string]$ComputerName,[string]$Namespace = "root\cimv2",[int]$Timeout=15, [pscredential]$Credential)
{
$ConnectionOptions = new-object System.Management.ConnectionOptions
$EnumerationOptions = new-object System.Management.EnumerationOptions
if($Credential){
$ConnectionOptions.Username = $Credential.UserName;
$ConnectionOptions.SecurePassword = $Credential.Password;
}
$timeoutseconds = new-timespan -seconds $timeout
$EnumerationOptions.set_timeout($timeoutseconds)
$assembledpath = "\\$Computername\$Namespace"
#write-host $assembledpath -foregroundcolor yellow
$Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions
$Scope.Connect()
$querystring = "SELECT * FROM " + $class
#write-host $querystring
$query = new-object System.Management.ObjectQuery $querystring
$searcher = new-object System.Management.ManagementObjectSearcher
$searcher.set_options($EnumerationOptions)
$searcher.Query = $querystring
$searcher.Scope = $Scope
trap { $_ } $result = $searcher.get()
return $result
}