Get-WMIObject Cmdlet With Timeout

I am running a script that does a lot of WMI requests, but the cmdlet hangs if the server is not responding. Is there any way I can do this (or any other point for that matter), time out and exit if X seconds have passed?


Thanks to a tip from mjolinor, the solution is to run this as a -sjob and set a timeout in the while loop. But this is done from work already done (started with Start-Job). So how do I know that I am in control of the correct operation?

This is my code from my already running work:

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 tasks started with Start-Jobs, which have already been taken care of ..


source to share

6 answers

The only two solutions I've seen for this problem are:

  • Run queries as background jobs and put a timer on them and then stop / delete jobs that are running too long.

  • Correct the servers.



You can try the get-wmiCustom function by posting here . Wouldn't it be nice if get-wmiObject had a timeout parameter? Let's upvote this thing .



In addition to what was said, not a bulletproof solution, but consider pinging your servers ( Test-Connection

) first, it can speed up execution times if you don't have responder machines.



The slick Get-WmiCustom function here is helpful.



when creating a job using get-wmiobject assigns this job to a variable, then this variable can be passed to 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




I modified Daniel Muscetta Get-WmiCustom to support credential passing.

I know this post is a little old, hope it helps someone else.

# Define modified custom get-wmiobject for timeout with credential from
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

        $ConnectionOptions.Username = $Credential.UserName;
        $ConnectionOptions.SecurePassword = $Credential.Password;

    $timeoutseconds = new-timespan -seconds $timeout 

    $assembledpath = "\\$Computername\$Namespace"
    #write-host $assembledpath -foregroundcolor yellow

    $Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions 

    $querystring = "SELECT * FROM " + $class 
    #write-host $querystring

    $query = new-object System.Management.ObjectQuery $querystring 
    $searcher = new-object System.Management.ManagementObjectSearcher 
    $searcher.Query = $querystring 
    $searcher.Scope = $Scope

    trap { $_ } $result = $searcher.get()

    return $result 




All Articles