PowerShell - How to force timeout Invoke-Command

Viewed 5687

I would like to force-terminate/timeout a PowerShell Invoke-Command remote session after 20 minutes regardless of whether it's busy or idle.

How do I achieve this? Thanks.

2 Answers

Something like :

$job = Start-Job -ScriptBlock { <# Invoke-Command #> }
$job | Wait-Job -Timeout ( 20 * 60 ) | Remove-Job
PS> invoke_command_responsive -Machine pv3040 -Cmd "get-location"

function invoke_command_responsive {
    param(
        [string]$Machine,
        [string]$Cmd
    )
    
    $start_time  = Get-Date
    $start_dir   = better_resolve_path(".")
    $watchdog    = 8 #seconds
    
    [ScriptBlock]$sb = [ScriptBlock]::Create($opt_cmd)              

    $j = Start-Job -ScriptBlock {
        set-location $using:start_dir | out-null
        [ScriptBlock]$sb = [ScriptBlock]::Create($using:cmd)              
        invoke-command -Computer $using:Machine -ScriptBlock:$sb | out-host
    }

    # Wait for Job to Complete or TIMEOUT!
    while($true) {
        if ($j.HasMoreData) {
            Receive-Job $j
            Start-Sleep -Milliseconds 50
        }
        $current = Get-Date
        $time_span = $current - $start_time
        if ($time_span.TotalSeconds -gt $watchdog) {
            write-host "TIMEOUT!"
            Stop-Job $j
            break
        }
        if (-not $j.HasMoreData -and $j.State -ne 'Running') {
            write-host "Finished"
            break
        }
    }
    Remove-Job $j   
}

function better_resolve_path {
    param([string]$path)
    $pathfix = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path)
    return $pathfix
}
Related