如何让powershell忽略遗留命令的失败?
所有powershell模块都支持-ErrorAction
,但这不适用于NET STOP
等传统命令
NET STOP WUAUSERV
echo $?
true
我想尝试停止服务,如果服务已经停止,请继续。重现这一点的简单方法是尝试两次停止服务。
我尝试过的事情
$ErrorActionPreference = "SilentlyContinue"
NET STOP WUAUSERV
NET STOP WUAUSERV
echo $LASTEXITCODE
尝试使用AND和OR操作符
和
NET STOP WUAUSERV || $true
NET STOP WUAUSERV || $true
echo $LASTEXITCODE
或
NET STOP WUAUSERV && $true
NET STOP WUAUSERV && $true
echo $LASTEXITCODE
我也尝试过重定向错误
NET STOP WUAUSERV 2>nul
NET STOP WUAUSERV 2>nul
echo $LASTEXITCODE
根据similar question的建议,我也尝试了
cmd.exe /C "NET STOP WUAUSERV"
如何使这个遗留命令具有幂等性?
答案 0 :(得分:2)
对于许多常见任务,正确的答案是使用已存在的本机PowerShell命令。
对于此特定示例,正确的路径是使用Stop-Service
cmdlet,它将优雅地处理您的条件。
如果您必须使用旧版工具,请参阅此StackOverflow答案:Powershell: Capture program stdout and stderr to separate variables
.exe没有在PowerShell输出管道上放置传统值供您评估,因此尝试比较$true
没有任何用处。另见:Windows PowerShell Rethinking the Pipeline
此外,$ErrorActionPreference
对旧版.EXE无效。 (而-ErrorAction
特定于PowerShell命令。)
答案 1 :(得分:2)
要在PowerShell中静默错误/ stderr输出,请使用2> $null
,而不是2> NUL
。
$ErrorActionPreference
的值不应对调用外部实用程序(控制台应用程序)(例如net.exe
,但是 - {{ 3)}从Windows PowerShell v5.1 / PowerShell Core v6.0.0-beta.9开始 - 如果值为'Stop'
,2> $null
(实际上,任何流重定向2
,错误流)当前触发PowerShell错误。不幸的是,自Windows PowerShell v5.1 / PowerShell Core v6.0.0-beta.9起,PowerShell 不支持控制操作符&&
和||
。 ;但是,即使它们在这里你也不需要它们(你不会在$true
或$false
中使用它们。
无论stderr输出是否被静音:
$LASTEXITCODE
包含最近执行的外部实用程序的退出代码。
执行外部实用程序后,如果$?
为$True
,则$LASTEXITCODE
为0
,否则为$False
。
关于PowerShell的错误处理的全面讨论 - 关于PowerShell本机命令和外部实用程序 - give your thumbs up here。
答案 2 :(得分:0)
My other answer讨论了一般从外部可执行文件处理stderr输出/退出代码。
至于幂等方式停止服务(确保服务处于停止状态):
Matthew Wetmore's helpful answer建议使用PowerShell的Stop-Service
cmdlet,其中 应该是幂等的:它会停止服务,如果它正在运行,或者是一个no-op if它已经处于停止状态。
-NoWait
开关(PSv5 +),如我this answer所示。 如果您suggest here Stop-Service
确实存在问题(我不知道任何问题),您可以补充使用net.exe
Get-Service
cmdlet确保服务停止,同时仍检测错误情况:
$svc = 'wuauserv'
if ((Get-Service $svc).Status -ne 'Stopped') {
net stop $svc
if ($LASTEXITCODE) { Throw "Failed to stop service $svc."}
} else {
Write-Verbose -Verbose "(Service $svc is already stopped.)"
}