设置Get-process的时间限制

时间:2015-07-29 20:12:54

标签: powershell

长话短说,我们遇到的问题是我们的一些服务器会对它们造成严重影响,我正在寻找一种方法来监控它们,现在我有一个脚本会检查RDP端口以确保它是打开,我想我想使用get-service然后如果它提取任何数据我会返回。

以下是我不知道如何限制在返回false之前等待响应的时间的问题。

[bool](Get-process -ComputerName MYSERVER)

3 个答案:

答案 0 :(得分:2)

您可以将支票作为后台工作:

$sb = { Get-Process -ComputerName $args[0] }

$end = (Get-Date).AddSeconds(5)
$job = Start-Job -ScriptBlock $sb -ArgumentList 'MYSERVER'
do {
  Start-Sleep 100
  $finished = (Get-Job -Id $job.Id).State -eq 'Completed'
} until ($finished -or (Get-Date) -gt $end)

if (-not $finished) {
  Stop-Job -Id $job.Id
}

Receive-Job $job.Id
Remove-Job $job.Id

答案 1 :(得分:2)

虽然我喜欢Ansgars answer有时间限制的工作,但我认为单独的Runspace和异步调用更适合这项任务。

这里的主要区别在于Runspace重用进程内线程池,而PSJob方法启动一个新进程,带来所需的开销,例如OS /内核资源产生和管理子进程,序列化和反序列化数据等。

这样的事情:

function Timeout-Statement {
    param(
        [scriptblock[]]$ScriptBlock,
        [object[]]$ArgumentList,
        [int]$Timeout
    )

    $Runspace = [runspacefactory]::CreateRunspace()
    $Runspace.Open()

    $PS = [powershell]::Create()
    $PS.Runspace = $Runspace
    $PS = $PS.AddScript($ScriptBlock)
    foreach($Arg in $ArgumentList){
        $PS = $PS.AddArgument($Arg)
    }

    $IAR = $PS.BeginInvoke()

    if($IAR.AsyncWaitHandle.WaitOne($Timeout)){
        $PS.EndInvoke($IAR)
    }

    return $false
}

然后用它来做:

$ScriptBlock = {
    param($ComputerName)

    Get-Process @PSBoundParameters
}

$Timeout = 2500 # 2 and a half seconds (2500 milliseconds)

Timeout-Statement $ScriptBlock -ArgumentList "mycomputer.fqdn" -Timeout $Timeout

答案 2 :(得分:1)

这是一个众所周知的问题:https://connect.microsoft.com/PowerShell/feedback/details/645165/add-timeout-parameter-to-get-wmiobject

此处提供了一种解决方法:https://connect.microsoft.com/PowerShell/feedback/details/645165/add-timeout-parameter-to-get-wmiobject

Function Get-WmiCustom([string]$computername,[string]$namespace,[string]$class,[int]$timeout=15)
{
    $ConnectionOptions = new-object System.Management.ConnectionOptions
    $EnumerationOptions = new-object System.Management.EnumerationOptions

    $timeoutseconds = new-timespan -seconds $timeout
    $EnumerationOptions.set_timeout($timeoutseconds)

    $assembledpath = "\\" + $computername + "\" + $namespace
    #write-host $assembledpath -foregroundcolor yellow

    $Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions
    $Scope.Connect()

    $querystring = "SELECT * FROM " + $class
    #write-host $querystring

    $query = new-object System.Management.ObjectQuery $querystring
    $searcher = new-object System.Management.ManagementObjectSearcher
    $searcher.set_options($EnumerationOptions)
    $searcher.Query = $querystring
    $searcher.Scope = $Scope

    trap { $_ } $result = $searcher.get()

    return $result
}

你可以这样调用这个函数:

get-wmicustom -class Win32_Process -namespace "root\cimv2" -computername MYSERVER –timeout 1