如果失败并显示特定错误消息,请重试 PowerShell 脚本 (.ps1)
Retry PowerShell script (.ps1) if failing with specific error message
我们有一个 PowerShell 构建脚本(Cake 引导程序)偶尔无法 download/restore nuget 包。我将如何创建一个通用的 .ps1 脚本,该脚本可用于调用另一个 .ps1 脚本,如果失败则重试并且输出包含特定字符串(我不想重试如果这是一个构建错误)?
可能的用法示例:
.\ExecuteWithRetry.ps1 -Script "Build.ps1 -target Restore" -OutputTrigger "RemoteException"
创建了一个可以解决问题的脚本。
用法示例:
./Execute-With-Retry.ps1 -RetryDelay 1 -MaxRetries 2 { & ./Build.ps1 -target Restore } -RetryFilter RemoteException
基于this gist from Alex Bevilacqua.
<#
This script can be used to pass a ScriptBlock (closure) to be executed and returned.
The operation retried a few times on failure, and if the maximum threshold is surpassed, the operation fails completely.
Params:
Command - The ScriptBlock to be executed
RetryDelay - Number (in seconds) to wait between retries
(default: 5)
MaxRetries - Number of times to retry before accepting failure
(default: 5)
VerboseOutput - More info about internal processing
(default: false)
RetyFilter - Only retry if retry filter value is contained in the command output
Examples:
./Execute-With-Retry.ps1 -RetryDelay 1 -MaxRetries 2 { & ./Build.ps1 -target Restore } -RetryFilter RemoteException
#>
param(
[Parameter(ValueFromPipeline, Mandatory)]
$Command,
$RetryDelay = 5,
$MaxRetries = 5,
$VerboseOutput = $false,
$RetryFilter
)
$currentRetry = 0
$success = $false
$cmd = $Command.ToString()
do {
try {
$result = & $Command
$success = $true
if ($VerboseOutput -eq $true) {
$Host.UI.WriteDebugLine("Successfully executed [$cmd]")
}
return $result
}
catch [System.Exception] {
$currentRetry = $currentRetry + 1
$exMessage = $_.Exception.Message;
if ($RetryFilter -AND !$exMessage.Contains($RetryFilter)) {
throw $exMessage
}
if ($VerboseOutput -eq $true) {
$Host.UI.WriteErrorLine("Failed to execute [$cmd]: " + $_.Exception.Message)
}
if ($currentRetry -gt $MaxRetries) {
throw "Could not execute [$cmd]. The error: " + $_.Exception.ToString()
}
else {
if ($VerboseOutput -eq $true) {
$Host.UI.WriteDebugLine("Waiting $RetryDelay second(s) before attempt #$currentRetry of [$cmd]")
}
Start-Sleep -s $RetryDelay
}
}
} while (!$success);
我们有一个 PowerShell 构建脚本(Cake 引导程序)偶尔无法 download/restore nuget 包。我将如何创建一个通用的 .ps1 脚本,该脚本可用于调用另一个 .ps1 脚本,如果失败则重试并且输出包含特定字符串(我不想重试如果这是一个构建错误)?
可能的用法示例:
.\ExecuteWithRetry.ps1 -Script "Build.ps1 -target Restore" -OutputTrigger "RemoteException"
创建了一个可以解决问题的脚本。
用法示例:
./Execute-With-Retry.ps1 -RetryDelay 1 -MaxRetries 2 { & ./Build.ps1 -target Restore } -RetryFilter RemoteException
基于this gist from Alex Bevilacqua.
<#
This script can be used to pass a ScriptBlock (closure) to be executed and returned.
The operation retried a few times on failure, and if the maximum threshold is surpassed, the operation fails completely.
Params:
Command - The ScriptBlock to be executed
RetryDelay - Number (in seconds) to wait between retries
(default: 5)
MaxRetries - Number of times to retry before accepting failure
(default: 5)
VerboseOutput - More info about internal processing
(default: false)
RetyFilter - Only retry if retry filter value is contained in the command output
Examples:
./Execute-With-Retry.ps1 -RetryDelay 1 -MaxRetries 2 { & ./Build.ps1 -target Restore } -RetryFilter RemoteException
#>
param(
[Parameter(ValueFromPipeline, Mandatory)]
$Command,
$RetryDelay = 5,
$MaxRetries = 5,
$VerboseOutput = $false,
$RetryFilter
)
$currentRetry = 0
$success = $false
$cmd = $Command.ToString()
do {
try {
$result = & $Command
$success = $true
if ($VerboseOutput -eq $true) {
$Host.UI.WriteDebugLine("Successfully executed [$cmd]")
}
return $result
}
catch [System.Exception] {
$currentRetry = $currentRetry + 1
$exMessage = $_.Exception.Message;
if ($RetryFilter -AND !$exMessage.Contains($RetryFilter)) {
throw $exMessage
}
if ($VerboseOutput -eq $true) {
$Host.UI.WriteErrorLine("Failed to execute [$cmd]: " + $_.Exception.Message)
}
if ($currentRetry -gt $MaxRetries) {
throw "Could not execute [$cmd]. The error: " + $_.Exception.ToString()
}
else {
if ($VerboseOutput -eq $true) {
$Host.UI.WriteDebugLine("Waiting $RetryDelay second(s) before attempt #$currentRetry of [$cmd]")
}
Start-Sleep -s $RetryDelay
}
}
} while (!$success);