PowerShell的测试路径超时



我正试图定期检查域中数百台计算机上文本文件中是否存在特定字符串。

foreach ($computer in $computers) {
$hostname = $computer.DNSHostName
if (Test-Connection $hostname -Count 2 -Quiet) {
$FilePath = "\" + $hostname + "c$SomeDirectorySomeFile.txt"
if (Test-Path -Path $FilePath) {
# Check for string
}
}
}

在大多数情况下,测试连接然后测试路径的模式是有效和快速的。然而,某些计算机ping成功,但Test-Path解析为FALSE大约需要60秒。我不知道为什么,但这可能是域信任问题。

对于这种情况,我希望Test-Path有一个超时,如果超过两秒,则默认为FALSE

不幸的是,相关问题(如何将此PowerShell cmdlet包装为超时函数?(中的解决方案不适用于我的情况。建议的do-while循环在代码块中挂起。

我一直在尝试乔布斯,但似乎即使这样也不会强制退出Test-Path命令:

Start-Job -ScriptBlock {param($Path) Test-Path $Path} -ArgumentList $Path | Wait-Job -Timeout 2 | Remove-Job -Force

这项工作仍然悬而未决。这是我能达到上述要求的最干净的方式吗?除了生成异步活动之外,是否有更好的方法使测试路径超时,这样脚本就不会挂起?

将代码封装在[powershell]对象中,并调用BeginInvoke()异步执行它,然后使用关联的WaitHandle等待它只完成一段时间。

$sleepDuration = Get-Random 2,3
$ps = [powershell]::Create().AddScript("Start-Sleep -Seconds $sleepDuration; 'Done!'")
# execute it asynchronously
$handle = $ps.BeginInvoke()
# Wait 2500 milliseconds for it to finish
if(-not $handle.AsyncWaitHandle.WaitOne(2500)){
throw "timed out"
return
}
# WaitOne() returned $true, let's fetch the result
$result = $ps.EndInvoke($handle)
return $result

在上面的例子中,我们随机睡眠2或3秒,但设置一个2.5秒的超时-试着运行几次看看效果:(

最新更新