You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PowerShell中调用的PsExec命令设置超时以避免脚本阻塞

Solution: Add Timeout to PsExec Commands in PowerShell

Hey there, I totally get the frustration of your script getting stuck when users step away mid-install—let's fix that by adding a 2-minute timeout to each PsExec call. The trick here is to launch PsExec as a separate process using PowerShell's Start-Process, then monitor it with a timeout. If it exceeds the 2-minute window, we'll kill the process and keep the script moving.

Here's the revised script with full timeout handling:

$timeoutSeconds = 120 # 2 minutes converted to seconds

foreach ($program in $programlist){ 
    # Add timestamped logging for better tracking
    $logPrefix = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - "
    "$($logPrefix)Starting workflow for $program on $hostikname" | Out-File "$logpath\log.txt" -Append 

    # 1. Copy program to remote machine with timeout
    $copyArgs = "\\$hostikname -u bla\bla -p $plainpwd cmd /c ""pushd $BucketPath & copy $program c:\programdata\"""
    $copyProcess = Start-Process -FilePath "psexec.exe" -ArgumentList $copyArgs -NoNewWindow -PassThru
    if (-not $copyProcess.WaitForExit($timeoutSeconds)) {
        $copyProcess.Kill()
        "$($logPrefix)Copy of $program timed out after $timeoutSeconds seconds; process terminated" | Out-File "$logpath\log.txt" -Append
    } else {
        "$($logPrefix)Successfully copied $program to $hostikname" | Out-File "$logpath\log.txt" -Append
    }

    # 2. Run interactive installer with timeout
    $installArgs = "\\$hostikname -i -u bla\bla -p $plainpwd -h cmd /c ""c:\programdata\$program"""
    $installProcess = Start-Process -FilePath "psexec.exe" -ArgumentList $installArgs -NoNewWindow -PassThru
    if (-not $installProcess.WaitForExit($timeoutSeconds)) {
        $installProcess.Kill()
        "$($logPrefix)Installation of $program timed out after $timeoutSeconds seconds; process terminated" | Out-File "$logpath\log.txt" -Append
    } else {
        "$($logPrefix)Installation of $program completed on $hostikname" | Out-File "$logpath\log.txt" -Append
    }

    # 3. Clean up remote file with timeout
    $cleanupArgs = "\\$hostikname -u bla\bla -p $plainpwd cmd /c ""del c:\programdata\$program"""
    $cleanupProcess = Start-Process -FilePath "psexec.exe" -ArgumentList $cleanupArgs -NoNewWindow -PassThru
    if (-not $cleanupProcess.WaitForExit($timeoutSeconds)) {
        $cleanupProcess.Kill()
        "$($logPrefix)Cleanup for $program timed out after $timeoutSeconds seconds" | Out-File "$logpath\log.txt" -Append
    } else {
        "$($logPrefix)Successfully cleaned up $program on $hostikname" | Out-File "$logpath\log.txt" -Append
    }
}

Key Changes Breakdown:

  • Start-Process: Launches PsExec as an independent process instead of running it directly, which lets us monitor and control its execution. The -PassThru parameter gives us a process object to work with.
  • WaitForExit($timeoutSeconds): This method waits for the process to finish, but stops waiting once the timeout is hit. It returns $true if the process exited on its own, $false if it timed out.
  • Process Termination: If the timeout triggers, we call Kill() to shut down the PsExec process immediately, so the script can proceed to the next step without blocking.
  • Enhanced Logging: Added timestamps to every log entry, making it easy to track exactly when operations started, completed, or timed out.

Quick Notes:

  • If psexec.exe isn't in your system PATH, replace "psexec.exe" with the full path to the executable (e.g., "C:\Tools\PsTools\psexec.exe").
  • Remove the -NoNewWindow parameter if you want PsExec to run in its own separate command window.

内容的提问来源于stack exchange,提问作者Shahar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:34:16