Using invoke-command with a timeout

I use invoke-command to execute a scriptblock on a remote host.
My code looks like:

$my_remote_command = invoke-Command -Session $my_session -ScriptBlock {
Get-ChildItem c:\ *.* -Recurse | select name > c:\myfolder\myfile.txt

I need to stop the script block after 30 second, even if myfile.txt is not yet complete.
How can I set a timeout?

You could kick it as a job.

$Job = Start-Job -ScriptBlock {

    Invoke-Command -ComputerName localhost -ScriptBlock {
        Get-ChildItem c:\scripts\*.* -Recurse | select name | Out-File 'C:\Scripts\myfile.txt'


$Job | Wait-Job -Timeout 10
$Job | Stop-Job

Is there a way to make resolve-dnsname timeout in 1 second? stop-job (or remove-job -force) takes about 4 seconds.

$job = start-job -scriptblock { Resolve-DnsName }
$job | wait-job -timeout 1
measure-command { $job | stop-job }

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 4
Milliseconds      : 148
Ticks             : 41484183
TotalDays         : 4.80141006944444E-05
TotalHours        : 0.00115233841666667
TotalMinutes      : 0.069140305
TotalSeconds      : 4.1484183
TotalMilliseconds : 4148.4183

You can try using the -quicktimeout Parameter of the Resolve-DNSName cmdlet. It does not let you specify a timeout value, but it’s quicker than the default.

-quicktimeout has no effect in this case. Just try any ip without a hostname.

I think if the first post here isn’t updated, it doesn’t appear on the main page.

Oh well. In this case, -dnsonly fixes it.

OK so from what I can see above the solution is to run Invoke-Command within a job, downside is that it will time out the whole lot when the job is stopped.

So in my example I had an actual problem where I wanted to retrieve information about services running on several hundred servers. I didn’t want the Invoke-Command to halt after a specific time but, if there was a server that wasn’t responding, it would timeout for that particular computer so that the batch wouldn’t be waiting for it.

In my case I had one duff server that was making the query take 30 mins to run, with the code below the whole lot runs in about 2.5 mins, less then a tenth of the time.

Basically I’ve just put the start-job within the ICM.

Hopefully someone may find this useful

#Array of Servers
$ComputerName = @('Server01','Server02','Server03')

# service to check

$out=Invoke-Command -computername $ComputerName -ArgumentList $svcName{

    $jbID=Start-Job -ArgumentList $svcName{


        get-service  -DisplayName "$svcName"| foreach-object{
            # get service startmode and time
            $filter="Name='"+$_.ServiceName+"'"; # can't put filter variable into function filter!
            $s=Get-WmiObject -Class Win32_Service -Filter $filter
            $ProcessInfo=Get-WmiObject -Class Win32_Process -Filter "ProcessID='$($s.processid)'" -ea 0
            if($_.Status -eq 'Running'){
            $ht = @{

            $Obj=New-Object -TypeName PSObject -Property $ht



    for ($i2=1; $i2 -le 30; $i2++){
        if((Get-Job $ -notmatch 'Running'){
        sleep -Seconds 1
    $out=Get-Job $ | Receive-Job
    Stop-Job $
    remove-Job $
    Write-Output $out

$out|select pscomputername,DisplayName,lastStarted,ServiceName,LogOnAs,StartMode,ServiceType,Status |ft -a

Just to add to that other thread, which is closed for some reason. Invoke-command has an -asjob parameter already. And with multiple computers, they get run as child jobs that you can check on.

invoke-command comp1,comp2,comp3 { pwd } -asjob

get-job -Includechildjob

And you can see which ones aren’t completed…