Pass bool param to a powershell script in Jenkinsfile multiline parameterised pipeline - powershell

In my Jenkinsfile I have something like:
def addDollar(param) {
return "\$" + param
}
parameters {
booleanParam(
defaultValue: false,
name: 'FORCE_UPGRADE'
)
}
environment {
FORCE_UPGRADE = addDollar(params.FORCE_UPGRADE)
}
stages {
stage('Test') {
steps {
powershell script: ".\\test.ps1 -forceUpgrade ${env:FORCE_UPGRADE}"
}
}
stage('Test Multiline') {
steps {
powershell script: '''
.\\test.ps1 `
-forceUpgrade $env:FORCE_UPGRADE
'''
}
}
}
and the powershell script is
param (
[Parameter(Mandatory=$true)][boolean]$forceUpgrade=$false
)
if($forceUpgrade) {
Write-Host "Forcing upgrade"
}
This jenkins stage Test works as expected but Test Multiline erorrs with ParameterBindingArgumentTransformationException:
Cannot process argument transformation on parameter 'forceUpgrade'. Cannot convert value "System.String" to type "System.Boolean". Boolean parameters accept only Boolean values and
numbers, such as $True, $False, 1 or 0.
I get the same error if I run
.\test.ps1 -forceUpgrade false rather than
.\test.ps1 -forceUpgrade $false
Any ideas how to get the Jenkins Test Multiline stage working? I have a script where i need to pass a number of args, would be ideal to prevent horizontal scrolling using multiline powershell

Change the powershell input to a [string] instead of a [boolean]
[string]$forceUpgrade = $false
you will still be able to use the $forceUpgrade variable as a bool in the conditional in the powershell also.

Related

How to view script output (specifically PowerShell) from a Jenkinsfile?

I'm pretty new to Jenkins, so not totally clear on how to assign/read variables.
I have a jenkinsfile with a couple stages and a bunch of steps. In one of the steps, I want to run a PowerShell script but it isn't accomplishing the intent. The problem is, when I'm in Jenkins and I go to the Console Output to troubleshoot why the PowerShell script isn't working, I don't see any of the output from the powershell script, I just see this:
[Pipeline] {
[Pipeline] powershell (Test PowerShell Script)
[Pipeline] }
Here's a trimmed-down version of my code:
stages {
stage('Stage 1') {
agent { node {
label "Windows"
customWorkspace "D:\\Path"
}}
steps {
dir('Directory') {
withCredentials(
[usernameColonPassword(
credentialsId: 'credential1',
variable: 'BasicCred'
)]
) {
powershell(
label: 'Test PowerShell Script',
returnStdout: true,
script: 'echo Test'
)
}
}
}
}
}
I tried using the code provided in this Jenkins article:
steps {
dir('Directory') {
withCredentials(
[usernameColonPassword(
credentialsId: 'credential1',
variable: 'BasicCred'
)]
) {
def msg = powershell(
label: 'Test PowerShell Script',
returnStdout: true,
script: 'echo Test'
)
println msg
}
}
}
This threw an error:
WorkflowScript: 135: Expected a step # line 135, column 25.
def msg = powershell(
^
I also tried putting it inside a node:
steps {
dir('Directory') {
node {
withCredentials(
[usernameColonPassword(
credentialsId: 'credential1',
variable: 'BasicCred'
)]
) {
def msg = powershell(
label: 'Test PowerShell Script',
returnStdout: true,
script: 'echo Test'
)
println msg
}
}
}
}
But it threw an error that the node is missing a label, and when I tried adding a label it threw another error.
So what's the right way to go about this? I just want to capture the output from the PowerShell script and see it so I can troubleshoot why it isn't working.

Passing secure parameter to PowerShell DSC script from Bicep template

I am using a Bicep template to deploy a virtual machine with a PowerShell DSC script that adds a Log Analytics workspace to the Log Analytics agent. The script uses a secure parameter (workspaceKey1) which is defined in the template and pulled from a key vault. When running the script, I'm getting the following error:
" Performing the operation "Set-TargetResource" on target "Executing the SetScript with the user supplied credential"."},
PowerShell DSC resource MSFT_ScriptResource failed to execute Set-TargetResource functionality with error message: Value does not fall within the expected range."
A simplified version of the script is below.
Configuration MmaMultihoming
{
Param (
[string] $workspaceId1,
[System.Management.Automation.PSCredential] $workspaceKey1,
)
Import-DscResource -ModuleName PSDesiredStateConfiguration;
Import-DscResource -ModuleName xPSDesiredStateConfiguration;
[System.Management.Automation.PSCredential]$workspaceKey1 = New-Object System.Management.Automation.PSCredential ($workspaceKey1.userName, $workspaceKey1.password)
Node localhost {
Script ConfigureWorkspace
{
SetScript =
{
$workspaceId = $Using:workspaceId1;
$workspaceKey = $Using:workspaceKey1;
$mma = New-Object -ComObject 'AgentConfigManager.MgmtSvcCfg';
$mma.AddCloudWorkspace($workspaceId, $workspaceKey);
$mma.ReloadConfiguration();
}
TestScript = { Test-Path "HKLM:\SYSTEM\ControlSet001\Services\HealthService\Parameters\Service Connector Services\Log Analytics - $($Using:workspaceId)"}
GetScript = { #{ Result = (Get-ChildItem "HKLM:\SYSTEM\ControlSet001\Services\HealthService\Parameters\Service Connector Services")} }
}
}
}
The Bicep code is below:
param keyvaultName string = 'keyvault'
param kvResourceGroup string = 'keyvault-rg'
param workspaceId1 string
#secure()
param workspaceKey1 string = kv.getSecret('workspaceKey1')
resource kv 'Microsoft.KeyVault/vaults#2022-07-01' existing = {
name: keyvaultName
scope: resourceGroup(kvResourceGroup )
}
resource DSC_LogAnalytics 'Microsoft.Compute/virtualMachines/extensions#2022-08-01' = {
parent: vm1
name: 'Microsoft.Powershell.DSC'
location: location
properties: {
publisher: 'Microsoft.PowerShell'
type: 'DSC'
typeHandlerVersion: '2.77'
autoUpgradeMinorVersion: true
settings: {
wmfVersion: 'latest'
configuration: {
url: dscScript
script: 'dsc.ps1'
function: 'MmaMultihoming'
}
configurationArguments: {
workspaceId1: workspaceId1
}
privacy: {
datacollection: 'enable'
}
advancedOptions: {
forcePullAndApply: false
}
}
protectedSettings: {
configurationArguments: {
workspaceKey1: {
userName: 'donotuse'
password: workspaceKey1
}
}
configurationUrlSasToken: SaaStoken
}
}
}
I am really quite stuck so would appreciate any ideas people can give.
Thanks!

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?

How to pass a parameter to a powershell script in a jenkins pipeline

How do I pass my variable VAR_A to an embedded powershell script in a jenkins pipeline ?
e.g.
def VAR_A = 'test'
def mystatus = powershell(returnStatus: true, script: '''
Write-Host "My result: '$VAR_A'" '''
withEnv(["VAR_A=test"]) {
def mystatus = powershell(returnStatus: true, script: '''
Write-Host "My result: '$VAR_A'" '''
}
both result with following output
My result: ''
Note : I prefer to define my powershell script in the jenkinsfile to keep things simple.
Try this:
node {
powershell '''
$VAR_A = 'test'
Write-Host "My result: '$VAR_A'"
'''
withEnv(["VAR_A=envtest"]) {
powershell '''
Write-Host "My result is empty: '$VAR_A'"
Write-Host "My env result: '$env:VAR_A'"
'''
}
}
The output is:
My result: 'test'
My result is empty: ''
My env result: 'envtest'
This was tested on Jenkins 2.73.1.
Note that:
$VAR_A = 'test' is declared within the first powershell '''...'''
env: is required to access environment variables (see about_Environment_Variables in the Microsoft Docs)