Powershell – Output is truncated in Jenkins job when launching PowerShell script remotely using psexec

continuous integrationJenkinspowershellpsexec

I've created a job in Jenkins to launch a small powershell script on a remote machine using psexec. In my build step, I'm using the powershell plugin and launching the below command:

& "$env:SCRIPTROOT\test_psexec.ps1" -Username $env:USERNAME -Password $env:PASSWORD -Server $env:REMOTESERVER

In the test_psexec.ps1 file, I have the code below:

$filePath = "C:\windows\temp\test_script.ps1"
$server = "server01"
$cmd = "powershell -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $filePath"

Write-Host "Launching powershell on remote system using psexec..."
Write-Host "Command: & $PSScriptRoot\tools\psexec -accepteula -nobanner -u $username -p **** -h \\$server $cmd"

$output = & $PSScriptRoot\tools\psexec -accepteula -nobanner -u $username -p $password -h \\$server $cmd
Write-Host "Script Output: "
Write-Host $output

The test_script.ps1 file contains the following script:

Write-Host "Verifying if server is pending reboot..."

try {
  $regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"
  $regItems = Get-ItemProperty -Path $regKey -ErrorAction SilentlyContinue

  if($regItems) {
    Write-Host "Server has a reboot pending. Rebooting server..."
  } else {
    Write-Host "Server does not have a pending reboot."
  }
} catch {
  Write-Host "Failed to verify pending reboot or unable to restart server."
  Write-Host $_.Message
}

The job executes successfully, but for some reason, the output that I display from psexec in Jenkins only returns one line. I executed another test script on the remote machine with a bunch of text, and it seems to be truncating the output at 256 characters. The Jenkins job output looks similar to what is below:

Started by user Test Account
Building in workspace D:\Jenkins\workspace\test_job
[test_job] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\windows\TEMP\jenkins3570507542870234918.ps1'"
Launching powershell on remote system using psexec...
Command: D:\test_job\tools\psexec.exe -accepteula -nobanner -u testdomain\test_acct -p **** -h \\server01 "powershell" -NoLogo -NonInteractive -ExecutionPolicy Bypass -File C:\windows\temp\test_script.ps1
Connecting to server01...
Starting PSEXESVC service on server01...
Connecting with PsExec service on server01...
Starting powershell on server01...
powershell exited on server01 with error code 0.
Script Output: 
Verifying if server is pending reboot...
Execution successful.
Finished: SUCCESS

If I log onto and launch the script on the remote machine in PowerShell, I get the appropriate output. Also, I am not launching psexec in Jenkins directly as there is other logic around this part of the test_psexec.ps1 script which is irrelevant to this issue.

Does anyone know if I am hitting some sort of buffer limit or know of a setting I can configure to avoid this issue?

Best Answer

The reason why this isn't working for you is because your second script is using Write-Host. The output of Write-Host can't be redirected; so when you execute that script remotely, the output is being lost.

In your case, the best alternative is Write-Out which writes objects to the output stream. This should work fine in this particular case, but be aware that Write-Out has unexpected results when used within a function that needs to return other results to the output stream. (In Powershell returning a value from a function is equivalent to Write-Out.)

Another alternative is Write-Verbose which will write the results to the verbose stream. To see those results, you'll need to either add the -Verbose flag to your script invocation, or you can set $VerbosePreference = $true to set it for your session.

Here's a good article that talks about the pitfalls of Write-Host: http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/