Teamcity powershell runner to remotely run commands on server Teamcity powershell runner to remotely run commands on server powershell powershell

Teamcity powershell runner to remotely run commands on server


This was a mix of small issues, for 1 the user when queried via team city was not resolving the domain correctly so this needed to be added to the username some-user@some-domain. There was also an issue in that the there was some sort of connection limit which was being hit when doing the PSSESSION connection, however if I changed over to Invoke-Command with a script block it worked fine.

If it helps anyone here is the command I ended up with to unzip a remote file, using 7zip command line as the native solution never seemed to work.

$password = ConvertTo-SecureString "%TestServer.Password%" -AsPlainText -Force$credentials = New-Object System.Management.Automation.PsCredential("%TestServer.Username%",$password)$scriptBlock1 = {``    $sevenZip = "%TestServer.ReleasePath%\7za.exe"; `    &$sevenZip x %TestServer.ReleasePath%\web-package.zip -o%TestServer.WebPath% * -aoa; `}Invoke-Command -computername %TestServer.Server% -Credential $credentials -scriptblock $scriptBlock1

One thing to remember is that the username contains the domain as listed above, also the magic quotes are needed to allow the script block to be spread over lines as well as the semi colon to indicate the tasks should be run together.


Invoke-Command works well if the script you have to run on the server is short and you have to wait for it to finish execution.

My issue was that I wanted to start a service on the remote server and just log the stuff within the server and let teamcity build to continue execution. With Invoke-Command, teamcity did execute the process remotely, but kept waiting for that process to finish n return. If you're looking for something that just invokes a long running process on the server and forgets about it, try this:

This solution worked best for me:

1) Place the script to be executed remotely, in a file within the server.. lets say startup.bat

call Powershell.exe -executionpolicy remotesigned -File %1\bin\startup.ps1 

This basically executes another powershell script located in the web server.

Start-Process -WindowStyle hidden java -ArgumentList '-jar', "$APP_HOME\bin\test-api.jar" -PassThru

Make sure that there's a teamcity Build step to deploy these files to the Web server.

2) Create a teamcity Build Step to execute a powershell script file

Sample Powershell Command to be executed by Teamcity:

$SERVER = (Get-Item env:SERVER_NAME).Value$APP_HOME = (Get-Item env:APP_HOME).Value$STARTUP_SCRIPT_PATH = "$APP_HOME\bin\startup.bat"Function Remote-Process {  param(    [string]$ComputerName,    [string]$Cmd  )  echo "Invoking Remote Script.."  $RETURNVAL = ([WMICLASS]"\\$ComputerName\ROOT\CIMV2:win32_process").Create($Cmd)  echo $RETURNVAL}$COMMAND = "$STARTUP_SCRIPT_PATH $APP_HOME"$output = Remote-Process $SERVER $COMMANDecho $OUTPUT

Where APP_HOME is the Absolute path to the folder (on remote serer) where your web app is deployed.

That's about it. This way, you can even execute services and the remote process will not be killed and lets you continue with the build chain.


Just an addition to accepted answer

$scriptBlock = [Scriptblock]::Create(@'  echo 'before'  ipconfig /all  echo 'after''@)Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

source
don't use backquote

Previous makes possible to define %PowerShell.header% and %PowerShell.footer% parameters not to write boilerplate code in TC steps