我正在编写一个PowerShell脚本,该脚本从所有AD服务器读取所有共享并将其输出到csv文件中。同时,脚本保存所有发生的错误,并将它们输出到错误日志中。该脚本将作为每周任务运行。当我运行脚本时,一切都很顺利,直到它到达一个冻结的服务器。在这种情况下,脚本将永远运行,因为它没有得到服务器的答复。
现在,我需要添加某种超时,在服务器在特定时间内没有收到答案后跳过它。我该如何使用现有的代码?
我的代码:
$computers = (Get-Content C:PowerShellSharesserverlist.txt).ForEach({
if(-not [string]::IsNullOrWhiteSpace($_))
{
"$_.domain.com"
}
})
$remoteCode = {
Get-SmbShare | Where-Object Path | Get-Acl |
Select-Object -Property "PSChildName", "Path", "Group", "AccessToString"
}
$results = Invoke-Command -ComputerName $computers -ScriptBlock $remoteCode 2>&1
$errors, $good = $results.Where({$_ -is [System.Management.Automation.ErrorRecord]}, 'Split')
$good | Sort-Object PSComputerName | Select-Object "PSComputerName", "PSChildName", "Path", "Group", @{ Name = "AccessToString"; Expression = { $_.AccessToString -replace("268435456", "FullControl") -replace("-1610612736", "ReadAndExecute")}} | export-csv -path C:PowerShellSharesshares.csv -NoTypeInformation -delimiter ";"
$errors.Exception.Message | Set-Content $error_logfile -Encoding Unicode
注意:这个答案几乎没有用,但在理想的世界里,-OperationTimeout
会按照它的名字来做,正如mklement0中有用的注释所说:
不幸的是,OperationTimeout会话选项并没有如其名称所示:请参阅GitHub问题#15696。实现实际的操作持续时间超时是GitHub提案#5434的主题,该提案建议在
Invoke-Command
中添加-Timeout
参数。
如果您认为这将是PowerShell未来版本的一个很好的实现,请考虑投票支持他的提案
您可以使用 打开超时请参阅 然后,脚本的其余部分是相同的,只是使用 最后,在完成远程连接后,您需要删除PSSessions:PSSessionOption
,其操作超时和New-PSSessionOption
文档的参数部分:-OpenTimeout
确定客户端计算机等待建立会话连接的时间。当间隔到期时,建立连接的命令将失败。-OperationTimeout
确定WinRM在启动连接超时之前等待来自活动连接的阳性连接测试的最长时间。$timeOut = 30000 # => 30 seconds
$psso = New-PSSessionOption -OpenTimeout $timeOut -OperationTimeout $timeOut
$session = (Get-Content C:PowerShellSharesserverlist.txt).ForEach({
if(-not [string]::IsNullOrWhiteSpace($_)) {
try {
New-PSSession -ComputerName "$_.domain.com" -SessionOption $psso
}
catch {
Write-Warning $_.Exception.Message
}
}
})
-Session
代替-ComputerName
用于Invoke-Command
:$results = Invoke-Command -Session $session -ScriptBlock $remoteCode 2>&1
Remove-PSSession $session