如何为PowerShell函数设置超时?

如何为PowerShell函数设置超时?,powershell,timeout,Powershell,Timeout,我有一个脚本,它正在提取呼叫中心中许多机器的磁盘空间信息。但是,有时此函数花费的时间太长。我需要为该函数创建一个超时,但一直无法执行。我尝试过使用start job,但老实说,我不完全理解它,所以我没有得到想要的结果 try { $timeoutSeconds = 30 $code = { param($currentPCname, $activeDriveTypes) // Function which takes computer name as input an

我有一个脚本,它正在提取呼叫中心中许多机器的磁盘空间信息。但是,有时此函数花费的时间太长。我需要为该函数创建一个超时,但一直无法执行。我尝试过使用start job,但老实说,我不完全理解它,所以我没有得到想要的结果

try {
    $timeoutSeconds = 30
    $code = {
      param($currentPCname, $activeDriveTypes)
// Function which takes computer name as input and outputs the ComputerName,DeviceID, Size, Freespace and DriveType (3 = local)
      function get-FDS { 
        [cmdLetBinding()]
        Param([string]$hostName)
        Get-WmiObject Win32_LogicalDisk -ComputerName $hostName | 
        Where-object {$_.DriveType -in $activeDriveTypes} | 
        select-Object @{Name="ComputerName";Expression={$hostName}}, @{Name="Date";Expression={Get-Date}}, DeviceID, Size, Freespace, DriveType
      } 
      get-FDS($currentPCname) -errorAction stop
    }
    $processTime = measure-command { 
      $j = Start-Job -ScriptBlock $code -Arg $currentPCname, $activeDriveTypes 
      if (Wait-Job $j -Timeout $timeoutSeconds) { $tempData = Receive-Job $j }
      $jobState = $j.state
      Remove-Job -force $j
    }
    if ($jobState -ne 'Completed') {
        $pcTurnedOn = $false
        $errorMessage = "ERROR talking to $currentPCname : Query timed-out"
        $query = "CALL sp_fds_insert_log(" + $currentRunID + ", '" + $errorMessage + "', '" + $scriptName + "');"
        $cmd = new-object mysql.data.mysqlclient.mysqlcommand($query, $conn) 
        $cmd.executenonquery()
    }
} catch {
    $pcTurnedOn = $false
    $errorMessage = "ERROR talking to $currentPCname : $_"
    $query = "CALL sp_fds_insert_log(" + $currentRunID + ", '" + $errorMessage + "', '" + $scriptName + "');"
    $cmd = new-object mysql.data.mysqlclient.mysqlcommand($query, $conn) 
    $cmd.executenonquery() 
}
上面代码的要点是,如果下面的行调用$code段

$processTime = measure-command { 
  $j = Start-Job -ScriptBlock $code -Arg $currentPCname, $activeDriveTypes
  if (Wait-Job $j -Timeout $timeoutSeconds) { $tempData = Receive-Job $j }
  $jobState = $j.state
  Remove-Job -force $j
}

需要30秒以上,即$timeoutSeconds,将调用最后一个IF语句,如果上面的行由于某种原因无法工作,则将调用catch语句,如果它在30秒内工作,则不会调用任何内容

如果作业在达到超时之前完成,
Wait job
将返回作业本身-如果超过超时,则不会返回任何内容:

$timeout = 2
$job = Start-Job { Start-Sleep -Seconds 3 }
$done = $job |Wait-Job -TimeOut $timeout
if($done){
    # It returned within the timeout 
}
else {
    # Nothing was returned, job timed out
}

Start Job
立即返回作业对象,因此当您执行
Measure命令{$j=Start Job…}
时,所需时间不会超过几毫秒。我明白,问题不在于$processTime结果,因为这很容易解决,我现在很难接受的是让作业最多运行30秒,然后终止它@MathiasR.JessenI已经修复了那部分,有没有关于暂停的想法@MathiasR.JessenThank你这个哥们儿很有帮助:)