I'm trying to catch the exitcode from a PowerShell script that uses a Invoke-Command to run a scriptblock on a remote machine.
First the BAT file: The BAT file is run with a variable. The script looks like this:
powershell.exe -noninteractive -noprofile -command "& {E:\Scripts\Check-Services_XXX.ps1 %1 }"
EXIT /B %errorlevel%
The PowerShell script looks like this:
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
}
The problem is that the ExitCode is not captured back, so when the BAT file ends, it ends with 0. That would be the case if everything is running. But i deliberately changed the service name in the check service section to something that does not exist for sure, but still it the BAT file ends with Exitcode 0
Done so far: Tried this solution: catching return code of a command with "invoke-command" - Powershell 2 But didn't work: got the following error "is not equal to Open, you cannot run a command in the session. The session state is Closing" Apparently, when it exited with a error, the session was closed, thus couldn't get the exitcode
Also tried this one: Capture Write-Host output and exit code from Invoke-Command on a Remote System But also the same result; no correct exitcode (expected 1 instead of 0 in the BAT file)
CodePudding user response:
You would have to run the exit command outside of invoke-command.
# check-service.ps1
$result = invoke-command localhost { get-service appxsvc |
where status -eq running }
if (! $result) {
exit 1
}
CodePudding user response:
Change your invocation of powershell.exe to use the -File CLI parameter:
powershell.exe -NoProfile -File "E:\Scripts\Check-Services_XXX.ps1" "%1"
EXIT /B %errorlevel%
That way, the .ps1 script's exit code is properly relayed as powershell.exe's exit code.
Additionally, as js2010's answer notes, you'll need to use your $host.SetShouldExit(1) call out of the Invoke-Command script block, given that the latter executes remotely. For the reasons explained below, exit 1 is preferable.
Generally speaking:
There's no reason to use the
-Command(-c) CLI parameter with"& { ... }"in order to invoke code - just use"..."directly. Older versions of the CLI documentation erroneously suggested that& { ... }is required, but this has since been corrected.Not only is
"& { ... }"unnecessary, it invariably resets the exit code to0.
As for your use of $host.SetShouldExit(1) to request exiting with an exit code of 1 (leaving aside that in a remote call it isn't effective):
- It generally isn't designed to be called from user code, as explained in this answer.
For general information about exit codes in PowerShell, see this answer.
