24

Is it possible to call a PowerShell command directly in the pipelines groovy script? While using custom jobs in Jenkins I am able to call the command with the PowerShell Plugin. But there is no snippet to use this in the groovy script.

I also tried sh() but it seems that this command does not allow multiple lines and comments inside the command.

Rod Kimble
  • 1,302
  • 3
  • 18
  • 44

4 Answers4

34

To call a PowerShell script from the Groovy-Script:

  • you have to use the bat command.
  • After that, you have to be sure that the Error Code (errorlevel) variable will be correctly returned (EXIT 1 should resulting in a FAILED job).
  • Last, to be compatible with the PowerShell-Plugin, you have to be sure that $LastExitCode will be considered.
  • I have notice that the 'powershell' is now available in pipeline, but since it have several issues I prefer this variant. Still waiting it works stabil. I actually have an issue with the 'dontKillMe' behavior.

Since Jenkins 2.207 with Powershell plugin 1.4, I have replace all my calls with the official powershell pipeline command. I do now recommend to use it. Note that you must predent \$ErrorActionPreference='Stop'; to your Script if you want it to abort on Write-Error because of an Issue with the powershell plugin.

For that porpuse I have written a little groovy method which could be integrate in any pipeline-script:

def PowerShell(psCmd) {
    psCmd=psCmd.replaceAll("%", "%%")
    bat "powershell.exe -NonInteractive -ExecutionPolicy Bypass -Command \"\$ErrorActionPreference='Stop';[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;$psCmd;EXIT \$global:LastExitCode\""
}

[EDIT] I have added the UTF8 OutputEncoding: works great with Server 2016 and Win10.[/EDIT] [EDIT] I have added the '%' mask[/EDIT]

In your Pipeline-Script you could then call your Script like this:

stage ('Call Powershell Script')
{
    node ('MyWindowsSlave') {
        PowerShell(". '.\\disk-usage.ps1'") 
    }
}

The best thing with that method, is that you may call CmdLet without having to do this in the Script, which is best-praxis.

Call ps1 to define CmdLet, an then call the CmdLet

PowerShell(". '.\\disk-usage.ps1'; du -Verbose")
  • Do not forget to use withEnv() an then you are better than fully compatible with the Powershell plugin.
  • postpone your Script with . to be sure your step failed when the script return an error code (should be preferred), use & if you don't care about it.
elou
  • 1,242
  • 15
  • 21
  • Thanks for this, it's helped me out a lot. How would you escape " in the command so that it shows up properly? For example, passing: .Split(":") results in the command being evaluated as .Split(:) – Adam Apr 30 '18 at 19:50
  • `"` should be masked for groovy and batch: `PowerShell("Write-Output \\\"hereXamXI\\\".Split(\\\"X\\\")")` do the thing for me. I prefer to replace `"` by `'`: `PowerShell("Write-Output 'hereXamXI'.Split('X')")`. Regards – elou May 02 '18 at 10:11
  • Is there a trick to getting arguments for CmdLet working with this solution? – Naxin Jan 22 '19 at 05:13
  • @Naxin you have several ways to bypass Parameters: (1) Use [Groovy substitution](https://stackoverflow.com/questions/28572080/how-to-access-parameters-in-a-parameterized-build) with ${PIPELINE_VAR} (be carefull with spaces) (2) Use [Powershell susbstitution with environment variables](https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#withenv-set-environment-variables) (be carefull with masking $). Note this also apply to the native powershell command. – elou Jan 22 '19 at 15:26
27

Calling PowerShell scripts is now supported with powershell step as announced on Jenkins blog.

The documentation mentions it supports multiple lines scripts.

Ludovic Ronsin
  • 794
  • 8
  • 11
  • 1
    Hi, not sure if I'm a bit late on this issue, I noticed that the powershell support by default use the -NoProfile plugin, do you know is there a way around this? I can't seem to run my pipeline as I need access to the powershell profile. – jacmurphy50 Mar 08 '18 at 12:48
  • How to run a PowerShell script file .ps1 using the `powershell` step? – tarekahf Dec 24 '21 at 07:39
1

From version 2.28 of Pipeline Nodes and Processes Plugin, we can directly use 'powershell'.

Eg: powershell(". '.Test.ps1'") 
Chinthaka
  • 966
  • 1
  • 13
  • 42
-9

You can use the sh command like this:

sh """
    echo 'foo'
    # bar
    echo 'hello'
"""

Comments are supported in here.

Christopher
  • 1,103
  • 1
  • 6
  • 18
  • that works on one of my windows nodes but not the other. Is there something you need to do to the OS to enable it? – Peter Kahn May 05 '17 at 01:45
  • the sh command will start a bash session, also with windows slave, which is not a PowerShell environment. You can try `sh 'where ps.exe'` or `sh 'echo $SHELL'` in your Pipeline. See : [link](https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#code-sh-code-shell-script) Note that `ps.exe`must be install on the windows slave. – elou Jun 02 '17 at 06:43