Executing powershell command directly in jenkins pipeline - powershell

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.

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.

Calling PowerShell scripts is now supported with powershell step as announced on Jenkins blog.
The documentation mentions it supports multiple lines scripts.

From version 2.28 of Pipeline Nodes and Processes Plugin, we can directly use 'powershell'.
Eg: powershell(". '.Test.ps1'")

You can use the sh command like this:
sh """
echo 'foo'
# bar
echo 'hello'
"""
Comments are supported in here.

Related

Jenkins Inject Environment variable works with batch command but not powershell

I'm dealing with a very weird anomaly in Jenkins that makes absolutely no sense to me. Essentially Jenkins is behaving differently for a powershell command than for a batch command.
My goal is to pass an environment variable (or parameter) from one Jenkins Job to another. However this variable to be passed is generated during the runtime of the first job.
I made a fake project to test passing variables and I was able to do so by adding a build step to echo out the variable into an env.props file on the node and then used the parameterized trigger plugin to call the next job. I was able to get this to work great in this test scenario but when I tried to implement the same steps in the actual build job (which relies on powershell scripts) it did not work.
After, a lot of trial and error I have found that when I use a windows batch command to echo the variable into a props file and then inject the variable into the job - it works perfect. But when I do the exact same thing with a powershell command it does not inject the variable back in to the job even though I use the exact same line of code. It still writes the variable to the file but Jenkins will not "reinject" this variable back into the job's env variable even though I am using the exact same step to do so.
The command is essentially this:
echo Testvar=Somevalue > C:\Jenkins\env.props
Both sucesffuly write the string to the props file, but when done with a powershell command, Jenkins will not absorb the txt from the run. Almost as if powershell is encoding it in a way that Jenkins cannot read but looks the exact same to me.
Any ideas?
Turns out, it was the encoding!
echo "string" > file.txt
does not produce the same result in batch as powershell.
Switching to
echo "string" | out-file -encoding ASCII file.txt
did the trick.

Jenkins parameter Release versus Staging

I created a freestyle job in Jenkins that I just set up (latest version).
I added parameters to it. One of those is a Options selection for ReleaseType with the options of Staging and Release.
One of the build steps is executing a remote command on the server when the site is uploaded to. It uses the Execute Windows Batch Command build step.
Here is the command line (with things made generic):
sexec myuser#mysite.com -pw=mypassword -cmd="PowerShell -Command ""C:\batch\bvCopyFast.ps1 C:\inetpub\mysite${ReleaseType}\siteLoad C:\inetpub\mysite${ReleaseType}\site""
Basically I am executing a powershell command that uses Robocopy to copy the files from the upload folder to the actual release folder for the site.
As you can see I need to have the ${ReleaseType} replaced with the actual value. The problem is that when this gets executed it isn't doing the substitution. I just uses that literal value in the command and that doesn't work.
If you use the -Command parameter it implies you are going to write raw PowerShell code in between the quotation marks that follow (allow you can call a script as you have).
PowerShell -Command "Get-Date; pause;"
To call a PowerShell script file you should use:
PowerShell -File "Your-Script.ps1 -Parameter1 Argument1 -Parameter2 Argument2"
https://learn.microsoft.com/en-us/powershell/scripting/components/console/powershell.exe-command-line-help?view=powershell-6
I would write a PowerShell script that accepted your root path and the releaseType as arguments and execute that.
Param($rootPath,$releaseType)
{
robocopy "$($rootPath)\$($releaseType)\siteLoad" "$($rootPath)\$($releaseType)\site"
}
I have never used Jenkins so I hope this works as I expect it to!
sexec myuser#mysite.com -pw=mypassword -cmd=""PowerShell -File 'C:\batch\newScript.ps1' -RootPath 'c:\inetpub\mysite' -ReleaseType {ReleaseType}""

How to run Powershell file (having extension .ps1) using jmeter?

I want to execute .ps1 file in jmeter. I have pass the parameter as in image,but in output facing errors.The filename, directory name, or volume label syntax is incorrect.
Though the filename, directory name are correct.
Here is your problem:
Remove that quotation mark and everything should start working as expected
In general, you are making things overcomplicated.
Why do you need these cmd /c? Why just don't call powershell directly?
Normally powershell is in Windows PATH, there is no need to provide full path to it
So configure your OS Process Sampler as:
Command: powershell
Parameter: D:\Software\apache=jmeter-3.0\apache-jmeter-3.0\bin\TIP.ps1
See How to Run External Commands and Programs Locally and Remotely from JMeter article for more information on invoking 3rd-party processes from your JMeter test.
I know this is an old thread but since the response was not correct for me I found the solution to be this:
Using the OS Process Sampler you need to add as command powershell.exe and as variables exactly the following:
-executionpolicy
bypass
-file
fullpathToYourScript.ps1
This worked perfectly fine for me.

PowerShell script called from within the Jenkins PowerShell build step hangs indefinitely

I have a Jenkins (1.493) project that uses the Jenkins PowerShell build step to execute a PowerShell script. Inside that script I want to invoke another script that is stored inside a file. I have now reduced it to the following:
Script inside Jenkins PowerShell build step:
& "\\stemmer.local\sidevelopment\cvdev\devbase\jenkins\PowerShell\Test.ps1"
Content of Test.ps1:
write-host 'Hello world!'
Whenever this Jenkins project executes, the PowerShell build step hangs indefinitely.
Things I have tried/verified so far:
Adding some output before the invocation of Test.ps1 shows me that the Jenkins PowerShell script is being execute normally up to the point where Test.ps1 is called.
The file Test.ps1 exists and is reachable from the build slave that executes the script. If I alter the file's name, I get the expected error message from PowerShell...
Exchanging the " for ' in the 1st script does not change anything. Also, using dot-sourcing rather than & does not help.
The file Test.ps1 can be executed properly from the powershell itself using the same command line that is being used in the Jenkins PowerShell script.
The execution policy for PowerShell has been set to unrestricted on my development host as well as on the Jenkins build slave.
I've tried replacing the PowerShell build step with a Windows batch command build step that looks like this:powershell.exe -InputFormat None -File "\\stemmer.local\sidevelopment\cvdev\devbase\jenkins\PowerShell\Test.ps1"and played around a little with the parameters of powershell.exe, but the results were - in those cases that were syntactically and otherwise correct as far as I can tell - always the same.
I only found few references to problems that sounded similar, but none of the approaches mentioned elsewhere did help me fix this. I am absolutely puzzled, and wondering whether someone encountered this issue before (and maybe even got a scenario like the one I have in mind running).
Thanks a lot for any input!
Volker
have you tried to set execution policy to bypass ?
Copy the script file locally, then invoke it from within the Jenkins PowerShell plugin - that way it works as expected.

MSBuild in a Powershell Script - How do I know if the build succeeded?

I am writting a build script with Powershell. The scripts performs various operations such as getting the latest source code off the SVN, backups, etc., and builds the solution using MSBuild:
cmd /c C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe "C:\Dev\Path\MyProjct.sln" /p:Configuration=Release
After this instruction, I only want to execute the rest of the script if the compilation succeeded. How can I check this?
The project is a web project, so it's not so easy to check for an output, but I would guess some variables would contain the compilation result. Also since I call msbuild with cmd /c, am I going to be able to access these variables?
Check the value of $LastExitCode right after the call to MSBUILD. If it is 0, then MSBUILD succeeded, otherwise it failed.
BTW there is no need to use cmd /c. Just call MSBUILD.exe directly. We do that in PowerShell build scripts all the time.
To just check for success/failure, use the automatic variable $?.
PS> help about_Automatic_Variables
$?
Contains the execution status of the last operation. It contains
TRUE if the last operation succeeded and FALSE if it failed.
for example:
msbuild
if (! $?) { throw "msbuild failed" }