How to execute a .bat file from psake? - deployment

I am trying in a powershell psake script to execute a .bat file. Is this possible? Or do I have to do a workaround?

Try the following:
task CallBatch {
exec {cmd.exe /c "path\to\my\testscript.bat"}
}
It is not necessary to wrap the call to cmd.exe in PSake's exec {} function, but if you do it, the build fails if the batch returns anything but 0.
The task below always lets the build fail:
task Return1FromCmd {
exec {cmd.exe /c "#exit 1"}
}

To execute a .bat (or .cmd) from PowerShell:
foo.bat:
#echo off
echo "foo"
foo.ps1:
. .\foo.bat
#or
.\foo.bat
#or
& .\foo.bat
we can then run the script:
D:\dev> .\foo.ps1
"foo"

This works for me:
properties {
$mybat = 'C:\path\tool.bat'
}
task Test -depends ... {
"Bla bla"
Exec { & $mybat }
}
No need to directly mention cmd.exe -- using & in the Exec script block seems to be enough.

Related

How to load variables from a powershell script and access the same in groovy jenkinsfile pipeline variable

I have a requirement where I have to load powershell variables from a powershell script and store the vairable value in a groovy jenkins pipeline variable and use it thereafter to edit the name of an artifact depending on that variable's value.
powershell script: Variables.ps1 (in real scenario this has number of variables but this is just for sample)
$Version = "22.4"
jenkinsfile:
pipeline {
agent any
stages {
stage('TestPowershell') {
steps {
script {
def path = "${env.WORKSPACE}\\Power\\Variables.ps1"
echo path
def versionFromPowershell = powershell(returnStdout: true, script: " . '${path}'; return $Version;")
echo versionFromPowershell
}
}
}
}
}
I get an error when I use this method as below:
groovy.lang.MissingPropertyException: No such property: Version for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:251)
at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:353)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:357)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:333)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:333)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:333)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at WorkflowScript.run(WorkflowScript:26)
In the vannila powershell the script works fine and does the job, not sure why the same syntax doesn't work when invoked via jenkins build. Any help is much appreciated!
Thanks
Shobhit
You cannot interpolate Powershell variables in a Groovy interpreter. Therefore, the script argument to the step method must contain escaped variable syntax characters such that the variable Version is interpreted by Powershell and not Groovy:
def versionFromPowershell = powershell(returnStdout: true, script: " . '${path}'; \$Version;")

Passing credentials variables to powershell script in Jenkins

I am trying to run MATLAB script inside powershell in one of the stages like this
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: "${myID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']])
{
script {
env.VAL_RESULT = powershell(script: "matlab -wait -r \"JUsername='$USERNAME';JPassword='$PASSWORD';modelValidation;\"", returnStatus: true)
if(env.VAL_RESULT == "1" ) {
unstable("Failed")
}
}
}
Trying to do this will give a warning in console like
Warning: A secret was passed to "powershell" using Groovy String interpolation, which is insecure.
Affected argument(s) used the following variable(s): [PASSWORD, USERNAME]
See https://jenkins.io/redirect/groovy-string-interpolation for details.
In-order to solve the warning, I had to encapsulate powershell scripts within single quotes like
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: '${myID}', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']])
{
script {
env.VAL_RESULT = powershell(script: 'matlab -wait -r \"JUsername='$USERNAME';JPassword='$PASSWORD';modelValidation;\"', returnStatus: true)
if(env.VAL_RESULT == "1" ) {
unstable("Failed")
}
}
}
Now the script doesn't exit. I believe that there is something wrong with the way I have used single quotes in JPassword='$PASSWORD'. Can anyone tell me if there is a way to escape single quote?

Jenkinsfile with Docker PowerShell image is getting hanged

When the Docker powershell gets invoked from a jenkinsfile it keeps executing and the job doesn't gets terminated.
pipeline {
agent {
docker {
image 'mcr.microsoft.com/azure-powershell'
args "--mount type=bind,src=/opt,dst=/opt -i -t --entrypoint=''"
}
}
stages {
stage('PwShell') {
steps {
powershell(returnStdout: true, script: 'Write-Output "PowerShell is mighty!"')
}
}
}
}
jenkin-job-hang
As you have not provided any log details it's tough to pin point the error as why it is stuck. Generally, for Jenkins declarative pipeline like the following -
pipeline {
agent {
docker { image '...abc.com' }
}
stages {
stage('Test') {
steps {
sh 'node --version'
}
}
}
}
When the Pipeline executes, Jenkins will automatically start the specified container and execute the defined steps within it:
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
[guided-tour] Running shell script
+ node --version
v14.15.0
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
And since you are stuck in the PowerShell line in the steps, it means the steps is not correctly set.
If you check this Microsoft PowerShell Support for Pipeline document then you will find that by default returnStdout returns the standard output stream with a default encoding of UTF-8. And Write-Output cmdlet returns an output stream.
You should be able to solve your problem by following the changing your PowerShell line as the code snippet shown below.
steps {
def msg = powershell(returnStdout: true, script: 'Write-Output "PowerShell is mighty!"')
println msg
}
Check this example section of the same above mentioned document for more detailed operations on the PowerShell steps.
I would also suggest to read this Using Docker with Pipeline document for more information.

Not able to run an exe in jenkins pipeline using powershell

I am trying to execute a process which is written in c# through jenkins pipeline during the build and deployment process.
It is a simple executable which takes 3 arguments, when it gets called from jenkins pipeline using a powershell function it doesn't write any logs which are plenty within the code of this exe, also it does not show anything on the pipeline logs as to what happened to this process. Whereas the logs output is clean before and after the execution of this process i.e. "Started..." & "end" gets printed in the jenkins build log.
When i try to run the same exe on a server directly with the same powershel script it runs perfectly fine. Could you please let me know how can i determine whats going wrong here or how can i make the logs more verbose so i can figure out the root cause.
Here is the code snippet
build-utils.ps1
function disable-utility($workspace) {
#the code here fetches the executable and its supporting libraries from the artifactory location and unzip it on the build agent server.
#below is the call to the executable
Type xmlPath #this prints the whole contents of the xml file which is being used as an input to my exe.
echo "disable exe path exists : $(Test-Path ""C:\Jenkins\workspace\utils\disable.exe"")" // output is TRUE
echo "Started..."
Start-Process -NoNewWindow -Filepath "C:\Jenkins\workspace\utils\disable.exe" -ArgumentList "-f xmlPath 0" #xmlPath is a path to a xml file
echo "end."
}
jenkinsfile
library {
identifier: 'jenkins-library#0.2.14',
retriever: legacySCM{[
$class: 'GitSCM',
userRemoteConfigs: [[
credtialsId: 'BITBUCKET_RW'
url: <htps://gitRepoUrl>
]]
]}
}
def executeStep(String stepName) {
def butil = '.\\build\\build-utils.ps1'
if(fileExists(butil))
{
def status = powershell(returnStatus: true, script: "& { . '${butil}'; ${stepName}; }")
echo status
if(status != 0) {
currentBuild.Result = 'Failure'
error("$StepName failed")
}
}
else
{
error("failed to find the file")
}
}
pipeline {
agent {
docker {
image '<path to the docker image to pull a server with VS2017 build tools>'
lable '<image name>'
reuseNode true
}
}
environment {
#loading the env variables here
}
stages {
stage {
step {
executeStep("disable-utility ${env.workspace}")
}
}
}
}
Thanks a lot in advance !
Have you changed it ? go to Regedit [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System Set "EnableLUA"= 0

how to pass variable from powershell script to an other step?

I use Jenkins and pipeline Jenkinsfile with a Windows agent. I want set a veriable from powershell in a 1st step and use this value in a 2nd step after.
my pipeline is:
def MSVERSION
pipeline {
stages {
stage('Clean workspace') {
steps {
deleteDir()
}
}
stage('package') {
steps {
script {
def stdout = powershell(returnStdout: true, script: '''
$MSVERSION="1234"
write-host "MSVERSION is $MSVERSION"
''')
println stdout
}
}
}
stage('deploy') {
steps {
script {
bat 'echo MSVERSION is ${MSVERSION}'
}
bat 'echo MSVERSION is ${MSVERSION}'
}
}
}
}
but my result is:
MSVERSION is 1234
MSVERSION is ${MSVERSION}
MSVERSION is ${MSVERSION}
EDIT
I find a workaroud but is not my question today:
in powershell I write a var.propertie file:
set-Content -path "var.properties" -Value "MSVERSION=$($VERSION)"
and in my script I read this var.properties file:
properties = readProperties file: 'var.properties'
echo "MSVERSION is ${properties.MSVERSION}"
bat 'echo MSVERSION is ${MSVERSION}'
does not do string interpolation, but this does:
bat "echo MSVERSION is ${MSVERSION}"