Stop Jenkins job if error occur - powershell

I am running a script on a remote server (windows) using Jenkins:
Invoke-Command -ComputerName myserver -ScriptBlock { D:\DeployScript\myscript.bat } -credential $Cred -ErrorAction Stop
inside this "myscript.bat" i running a psexec command:
psexec -i -h -u myserver\Administrator -p mypassword {mycommands}
how can i tell Jenkins to stop if an error occur on "myscript.bat"
(i must using Psexec because the script require interactive desktop)
Thanks!

In powershell you can get the exit code of the last command using the automatic variable $lastexitcode, so try something like this:
if ($lastexitcode -ne 0) { exit 1 }
or even better:
exit $lastexitcode

Related

Running multiple cmd commands from powershell script as if I was running it in cmd shell

I am trying to create a powershell script which will create a session in a remote machine and run a series of commands. These commands in question are to drop a Mongodb database before deployment of code.
I have the session side working but when I try to run the cmd I get X is not recognized as the name of a cmdlet.
The process I take when I am logged into the remote machine and using cmd is:
'C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe'
use <database>
db.dropDatabase()
This works correctly and I am trying to run those in powershell. They need to be run line by line in order to work.
ps1:
$session = New-PSSession -ComputerName "remoteMachine" -Credential $cred
Enter-PSSession -Session $session
Invoke-Command -ComputerName "remoteMachine" -ScriptBlock {
& 'C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe'
& 'use <database>'
& 'db.dropDatabase()'
}
Exit-PSSession
Get-PSSession | Remove-PSSession
When this is run I am getting the following errors:
The term 'use Assessment' is not recognized as the name of a cmdlet,
The term 'db.dropDatabase()' is not recognized as the name of a cmdlet,
I managed to figure it out by looking through & 'C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe' --help.
Rather than using multiple lines, I put the command on one line like:
Invoke-Command -ComputerName "remoteMachine" -ScriptBlock {
& 'C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe' <database> --eval '<action>'
}
For example:
Invoke-Command -ComputerName "remoteMachine" -ScriptBlock {
& 'C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe' testDatabase --eval 'db.dropDatabase()'
}

Start-Job via Invoke-Command: Job is only available in remote session

I'm trying to start TShark on different servers via following command:
Invoke-Command -Session $remoteSession -ScriptBlock {start-job -ScriptBlock {& 'C:\Program Files\Wireshark\tshark.exe' -b filesize:10000 -b files:5 -w "$tsharkResultDirectory\tshark.pcap"} -Name "TShark"}
The command works and everything is fine. But when I connect to the remote server via e.g. remote desktop, and perform the command Get-Job nothing is returned.
So that means that the beforehand started job only runs in the remote session. Does anybody know if there is a way to start a job in "global" scope. I don't want that TShark stops tracing if I accidentally close my PowerShell window.
Thx
You're correct that the job only exists for the duration of the PowerShell host session, which is why you can't retrieve it when you RDP.
A better approach might be to use the -AsJob switch of Invoke-Command. You can then retrieve the results by running Get-Job on your local machine rather than RDP'ing to the remote host:
Invoke-Command -Session $remoteSession -ScriptBlock { & 'C:\Program Files\Wireshark\tshark.exe' -b filesize:10000 -b files:5 -w "$tsharkResultDirectory\tshark.pcap" } -AsJob -Name "TShark"
Note again that you'll lose the job if you end your local PowerShell session.
I believe the only other way to run a remote job and have it persist is via the *-ScheduledJob commands as they record their results on disk:
PS C:\> get-command *ScheduledJob | Select Name
Name
----
Disable-ScheduledJob
Enable-ScheduledJob
Get-ScheduledJob
Register-ScheduledJob
Set-ScheduledJob
Unregister-ScheduledJob

Powershell remote job getting killed after a few hours

I am running a remote job as part of a deployment which is supposed to run forever (seeding random data) however the process keeps getting killed after only a few hours.. I am figuring some missing remote service flag or something.
I am running the remote job via this powershell command
Invoke-Command -ComputerName DEPLY -Credential $cred -AsJob -ScriptBlock {
C:\Deply\${bamboo.Configuration}\Seed\Seed.exe /y
}
Is there someway to prevent this process from being killed?
So it seems to me there is just an undocumented kill timeout for powershell jobs. I confirmed that my program is not crashing and the remoting service is just killing it after 3-4 hours. Or maybe its an OS thing - I don't know.
I switched to psexec which doesn't mess with the process - here is the command:
psexec \\DEPLY -accepteula -d -u "corp\administrator" -p "xxx" C:\Deply\${bamboo.Configuration}\Seed\Seed.exe /y
You can also launch it via WMI like so:
$process = get-wmiobject -query "SELECT * FROM Meta_Class WHERE __Class = 'Win32_Process'" -namespace "root\cimv2" -computername DEPLY -credential $cred
$results = $process.Create( "C:\Deply\${bamboo.Configuration}\Seed\Seed.exe /y" )
But I can't confirm if a remote process created this way lasts forever. Each test takes 4 hours and Im done messing with this.
RELATED: Launching background tasks in a remote session that don't get killed when the session is removed

Exe file remote Execution

I'm trying to write a script which will patch SQL Instances remotely. Referring this forum, I have framed the following line for executing the .exe remotely on other server:
Invoke-Command -ComputerName $computer -ScriptBlock {
& cmd /c 'D:\SQL_PATCH\SQLServer2012SP2-KB2958429-x64-ENU.exe' /qs /action=patch /allinstances /IAcceptSQLServerLicenseTerms
}
Also tried this as well:
Invoke-Command -ComputerName $computer -ScriptBlock {
& 'D:\SQL_PATCH\SQLServer2012SP2-KB2958429-x64-ENU.exe' -ArgumentList "/qs", "/action=patch", "/allinstances", "/IAcceptSQLServerLicenseTerms"
}
One more peculiar thing with this is, the first command is running fine on the Windows 2012 servers but not on Windows 2008R2 server. I don't know what's the reason behind this.
The following did the trick to what I was looking for:
psexec \\$computer -s -u Adminuser -p AdminPassword E:\SQL_PATCH\SQLServer2012SP2-KB2958429-x64-ENU.exe /quiet /action=patch /allinstances /IAcceptSQLServerLicenseTerms
This piece is working on all the servers irrespective for Windows versions.
Thanks everyone for your valuable suggestions.

psexec parameter is incorrect

I am using psexec to execute a .bat on a system. This will fingerprint the system and return the info back to me. The command I use is:
psexec \\server -u username -p password -s -i -c .\fingerprint.bat
This works with most of the servers, but some of them won't work with the -i switch. Is there a way to say, if this fails, try to do it again without the -i? I am using powershell to execute the script.
$servers = get-content .\input.txt
foreach($server in $servers) {
psexec \\$server -u username -p password -s -i -c .\fingerprint.bat
}
Check the $LastExitCode automatic variable. This gets set when PowerShell invokes an EXE. Whatever exit code the EXE returns gets put in $LastExitCode. I'm pretty sure psexec returns 0 for success and anything else means failure e.g.:
foreach($server in $servers) {
psexec \\$server -u username -p password -s -i -c .\fingerprint.bat
if ($LastExitCode) {
psexec \\$server -u username -p password -s -c .\fingerprint.bat
}
}
This is using a PowerShell trick where if ($LastExitCode) will if evaluate to true if $LastExitCode is anything but 0.