PowerShell限时和超时执行命令或脚本 7


有时候需要执行一条命令,一个函数或者一段脚本,给它设定timeout时间,如果超时了就自动丢弃,返回NULL,否则就返回执行的结果。使用PowerShell中的Job可以非常容易的实现。只需要使用三条命令即可。

  • Start-Job
  • Wait-Job
  • Receive-Job

具体可以参考下面的脚本:

function Invoke-TimeOutCommand()
{
    param(
    [int]$Timeout,
    [ScriptBlock]$ScriptBlock
    )
   $job = Start-Job -ScriptBlock $ScriptBlock
   $job | Wait-Job -Timeout $Timeout
   if($job.State -ne 'Completed')
   {
        Write-Warning 'timeout'
        $job | Stop-Job | Remove-Job
        return $null
   }
   else
   {
     return $job | Receive-Job
   }
}

Invoke-TimeOutCommand -Timeout 10 -ScriptBlock {
ping pstips.net -n 500
}
×用微信扫描并分享
本文链接: https://www.pstips.net/invoke-command-timeout.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

Mooser Lee进行回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

7 条评论 “PowerShell限时和超时执行命令或脚本

  • 哈哈

    PS C:\Users\Administrator> $doit = “ping pstips.net -n 500”
    echo “动作块为: $ScriptBlock”
       $job = Start-Job -ScriptBlock {$doit}
       $job | Wait-Job -Timeout 10
       if($job.State -ne ‘Completed’)
       {
            Write-Warning ‘timeout’
            $job | Stop-Job | Remove-Job
            return $null
       }
       else
       {
         return $job | Receive-Job
       }

    动作块为: ping pstips.net -n 500

    Id Name State HasMoreData Location Command
    — —- —– ———– ——– ——-
    101 Job101 Completed True localhost $doit

    –请问如何才能把变量$doit 传入花括号呢?

      • 哈哈

        $doit = “ping pstips.net -n 500”
           $job = Start-Job -ScriptBlock {
        param($num)
        $num
        } -ArgumentList $doit| Wait-Job -Timeout 10
        —-大神求救:我其实是想把ping命令放进ScriptBlock 里面执行,如果Ping不通超时10秒就返回,按上面的的做法,却是直接返回$num的变量,即仅返回”ping pstips.net -n 500″这个显示,实际上并没有执行ping,请问如何才能执行Ping这个操作呢??

        • Mooser Lee 文章作者

          其实你的重点就是,如何把字符串转换成PowerShell脚本块,并且能够执行返回结果。主要用[Scriptblock]::Create

          $doit = "ping pstips.net -n 5"
             $job = Start-Job -ScriptBlock {
              param($num)
              $numBlock = [Scriptblock]::Create($num)
              $numBlock.Invoke()
          } -ArgumentList $doit| Wait-Job -Timeout 10
          
          PS D:\> $job | Receive-Job
          
          正在 Ping pstips.net [118.123.20.23] 具有 32 字节的数据:
          来自 118.123.20.23 的回复: 字节=32 时间=50ms TTL=52
          来自 118.123.20.23 的回复: 字节=32 时间=50ms TTL=52
          来自 118.123.20.23 的回复: 字节=32 时间=50ms TTL=52
          来自 118.123.20.23 的回复: 字节=32 时间=49ms TTL=52
          来自 118.123.20.23 的回复: 字节=32 时间=88ms TTL=52
          
          • 哈哈

            膜拜,想不到power shell可以这么玩
            另外论坛注册是不是跟别的地方不不样,注册时好像要求输入用户名,并不要密码的。。。

          • 哈哈

            $ScriptBlock=”Copy-Item $remotefile $localfile -force”;
            $Timeout = 4;

            echo “动作块为: $ScriptBlock”
            echo “开始启动job: ”
            Get-Date -Format ‘yyyy-mm-dd HH:mm:ss’
            $job = Start-Job -ScriptBlock {
            param($num)
            $numBlock = [Scriptblock]::Create($num)
            $numBlock.Invoke()} -ArgumentList $ScriptBlock
            $job | Wait-Job -Timeout $Timeout
            if($job.State -ne ‘Completed’)
            {
            echo “[$nowtime]$mdname $hostip 取文件超时timeout”
            $job | Stop-Job | Remove-Job
            echo “回收job完成: ”
            Get-Date -Format ‘yyyy-mm-dd HH:mm:ss’

            测试结果如下:
            Copy-Item \\192.168.2.109\D$\pnp4nagios修改配置文件.txt D:\nagios_collect_log\log\192.168.2.109.pnp4nagios修改配置文件.txt -force
            动作块为: Copy-Item \\192.168.2.109\D$\pnp4nagios修改配置文件.txt D:\nagios_collect_log\log\192.168.2.109.pnp4nagios修改配置文件.txt -force
            开始启动job: 2017-07-22 10:07:06
            [2017-05-22 10:05:59]常州 192.168.2.109 取文件超时timeout
            回收job完成: 2017-07-22 10:07:28

            —现发现超时后,“$job | Stop-Job | Remove-Job”这一段代码运行需要20-30秒,有没有办法更快的回收这个$job呢;