Reputation: 18465
I have a strange issue where TeamCity just hangs whenever i try to do a remote call to one of our test servers.
Currently the build steps are:
- Template files for
- Compile code in
- Package project
- Send package to test servers
- Unzip package on test servers
Now it all works fine up until the last stage, unzipping the package on the remote server. Now I wanted to just run a powershell command to connect up and run the commands then exit. This all works fine if I were using powershell from remote desktop, and the user credentials provided are correct.
An example of what is being run is below:
$password = ConvertTo-SecureString "%PasswordVar%" -AsPlainText -Force
$credentials = New-Object System.Manager.Automation.PsCredential("%UsernameVar%", $password)
etsn -computername %TestServer1Var% -Credential $credentials
When this is called TeamCity just hangs, it has to be manually stopped or it will stay on this step on the agent forever. I have tried not using credentials, I have tried not using etsn and using the full command name, also tried other remote command methods, nothing seems to work.
So is there a way to get TeamCity to actually run the commands? or find out what is causing it to process this step indefinately?
Upvotes: 6
Views: 16397
Reputation: 20986
Just an addition to accepted answer
$scriptBlock = [Scriptblock]::Create(@'
echo 'before'
ipconfig /all
echo 'after'
'@)
Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock
Previous makes possible to define %PowerShell.header%
and %PowerShell.footer%
parameters not to write boilerplate code in TC steps
Upvotes: 0
Reputation: 1753
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 $COMMAND
echo $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.
Upvotes: 0
Reputation: 18465
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.
Upvotes: 8