Timeout Get-WMIObject cmdlet
Solution 1
The only two solutions I've seen for this problem are:
Run the queries as background jobs and put a timer on them, then stop/remove the jobs that run too long.
Fix your servers.
Solution 2
You could try the get-wmiCustom function, posted here. Wouldn't it be nice if get-wmiObject had a timeout parameter? Let's upvote this thing.
Solution 3
I've modified Daniel Muscetta's Get-WmiCustom to also support passing credentials.
I know this post is a little old, hopefully this helps someone else.
# 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
}
Solution 4
Glad my Get-WmiCustom function here http://blogs.msdn.com/b/dmuscett/archive/2009/05/27/get_2d00_wmicustom.aspx is useful.
Solution 5
when creating the job using get-wmiobject assign that job to a variable, then that variable can be piped into get-job for status or 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
Related videos on Youtube
Comments
-
Sune almost 2 years
I run a script which performs many WMI-querys - but the cmdlet hangs if the server doesn't answer.. Is there any way I can make this (or any other cmndlet for that matter) timeout and exit if X seconds has passed?
Edit
Thanks to a tip from mjolinor the solution is to run this as -asjob and set a timeout in a while loop. But this is run from within a job already (started with Start-Job). So how do I know I am controlling the correct job?
This is my code from inside my already started 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: My jobs started with Start-Jobs are already taken care of..
-
Sune about 12 yearsThanks! I am running this already in a job (with start-job -scriptpath). Should I still do -asjob from within a start-job?
-
mjolinor about 12 yearsI don't see nesting jobs as being any help. For the timer to work you need to run one job per server. This will add a couple of seconds of overhead to each one to create the job, but you can run multiple jobs at once. You'll need to script a process of keeping x number of jobs running at once, one for each server, and then receiving or canceling the jobs as they finish or their ET gets too long, then removing that job and starting up a new one from the next server in the list.
-
Sune about 12 yearsThe get-wmiobject query is just one of many things I do in my job, but the job hangs if get-wmiobject doesn't answer in proper time.. I will try to do a get-wmiobject -asjob and wait until the job is finished to continue. Maybe not the best practice but I see no other way.
-
noam about 11 yearsIt is very useful. Thank you for making that.