我正在尝试从使用 Invoke-Command 在远程计算机上运行脚本块的 PowerShell 脚本中捕获退出代码。
首先是 BAT 档案:BAT 档案使用变量运行。脚本如下所示:
powershell.exe -noninteractive -noprofile -command "& {E:\Scripts\Check-Services_XXX.ps1 %1 }"
EXIT /B %errorlevel%
PowerShell 脚本如下所示:
param(
[string] $ip #IP address van server
)
$username = "DOMAIN\DOMAIN_USER"
$secpasswdfile = "E:\Location\DOMAINUSER_encrypted_password.txt"
$secpasswd = Get-Content $secpasswdfile | ConvertTo-SecureString
$credentials = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
$soptions = New-PSSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck
Invoke-Command -ComputerName $ip -UseSSL -SessionOption $soptions -Credential $credentials -ScriptBlock `
{
# Start services
Start-Service -InputObject (Get-Service -Name IAS)
# Check services status
$checkservice = (get-service -Name IAS -ErrorAction SilentlyContinue)
if($checkservice.status -ne "Running"){$host.SetShouldExit(1)}
exit
}
问题是 ExitCode 没有被捕获回来,所以当 BAT 档案结束时,它以 0 结束。如果一切都在运行,就会出现这种情况。但是我故意将检查服务部分中的服务名称更改为肯定不存在的名称,但 BAT 档案仍然以 Exitcode 0 结尾
到目前为止已完成:尝试了此解决方案: 使用“invoke-command”捕获命令的回传码 - Powershell 2 但没有奏效:出现以下错误“不等于打开,您无法在会话中运行命令。 session state is Closing" 显然,当它退出错误时,会话已关闭,因此无法获取退出代码
也试过这个:Capture Write-Host output and exit code from Invoke-Command on a Remote System 但结果也一样;没有正确的退出代码(在 BAT 档案中应为 1 而不是 0)
解决方案!
感谢@js2010 和@mklement0;它现在就像一个魅力!
这是 BAT 档案:
powershell.exe -noprofile -File "E:\Scripts\Check-Services_XXX.ps1" "%1" "%2"
EXIT /B %errorlevel%
这是最终为我解决的 PowerShell 代码:
param(
[string] $ip, #IP address of checked server
[string] $service ) #Service name
$username = "DOMAIN\USER"
$secpasswdfile = "E:\Scripts\Credentials\DOMAIN-USER_encrypted_password.txt"
$secpasswd = Get-Content $secpasswdfile | ConvertTo-SecureString
$credentials = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
$soptions = New-PSSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck
$session = New-PSSession -ComputerName $ip -UseSSL -SessionOption $soptions -Credential $credentials
# Start services
Invoke-Command -Session $session -ScriptBlock { Start-Service -Name $using:service }
# Check services status
$checkservice = Invoke-Command -Session $session { Get-Service -name $using:service | where status -eq running }
if (! $checkservice) {
write-output ("Error 1, Service '" $service "' not running or not found.")
exit 1
}
我在将变量传递给远程命令时遇到了一些问题,这个链接帮助了我(https://powershellexplained.com/2016-08-28-PowerShell-variables-to-remote-commands/)
uj5u.com热心网友回复:
您必须在呼叫命令之外运行退出命令。
# check-service.ps1
$result = invoke-command localhost { get-service appxsvc |
where status -eq running }
if (! $result) {
exit 1
}
uj5u.com热心网友回复:
更改您的呼叫powershell.exe
以使用-File
CLI自变量:
powershell.exe -NoProfile -File "E:\Scripts\Check-Services_XXX.ps1" "%1"
EXIT /B %errorlevel%
这样,.ps1
脚本的退出代码被正确地中继为powershell.exe
退出代码。
此外,作为js2010 的回答说明,您需要使用脚本块之外的$host.SetShouldExit(1)
呼叫,因为后者是远程执行的。由于下面解释的原因,它是优选的。Invoke-Command
exit 1
通常来说,一般来说:
没有理由使用
-Command
(-c
) CLI 自变量"& { ... }"
来呼叫代码 - 只需"..."
直接使用。旧版本的CLI 档案错误地建议这& { ... }
是必需的,但这已得到纠正。不仅没有
"& { ... }"
必要,而且总是将退出代码重置为0
.
至于您使用$host.SetShouldExit(1)
退出代码请求退出的使用1
(撇开远程呼叫无效):
- 它通常不被设计为从用户代码中呼叫,如本答案中所述。
有关 PowerShell 中退出代码的一般信息,请参阅此答案。
0 评论