Declarative Jenkins with WithCredentials and Powershell - jenkins

stage('Deployment') {
steps {
withCredentials([string(credentialsId: 'Test', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
powershell '$pass = ConvertTo-SecureString -AsPlainText "${PASSWORD}" -Force'
powershell '$SecureString = "${pass}"'
powershell '$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "${USERNAME}","${SecureString}"'
powershell 'New-PSSession -ComputerName 192.123.123.123 -Credential "${MySecureCreds}"'
}
powershell 'Copy-Item "${ARTIFACT_PATH}" -Destination "${DESTINATION_PATH}" -ToSession -Recurse -Force'
powershell 'Start-Process "iisreset.exe" -NoNewWindow -Wait'
powershell 'Remove-Website -Name WebCareRecord'
powershell 'Remove-WebAppPool WebCareRecord'
powershell 'Get-WebBinding -Port 85 -Name WebCareRecord | Remove-WebBinding'
powershell 'Start-Process "iisreset.exe" -NoNewWindow -Wait'
powershell 'New-WebAppPool -Name WebCareRecord'
powershell 'Set-ItemProperty "${POOL_PATH}" managedPipelineMode 0'
powershell 'Set-ItemProperty "${POOL_PATH}" managedRuntimeVersion ""'
powershell 'New-WebSite -Name WebCareRecord -Port 85 -PhysicalPath "${PHYSICAL_PATH}" -ApplicationPool WebCareRecord'
powershell 'Start-Process "iisreset.exe" -NoNewWindow -Wait'
}
}
I am trying to get the Jenkins credentials ID, secure it and use the same credentials to login into the remote server. After login to the remote server, copy the artifact from jenkins server to remote server. For this I am getting error
org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: Credentials 'Test' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected.

There might be multiple problems, I've going through similar process now and feeling the pain to get it correctly in powershell within groovy, so this is what I've noticed so far:
You are creating a $pass variable in one powershell step, and then trying to access it in another powershell step, I don't think it will work that way, as another step might launch in different powershell session and that powershell variable is no longer there.?
I would try something like this:
stage('Deployment') {
steps {
withCredentials([string(credentialsId: 'Test', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
powershell """
\$pass = ConvertTo-SecureString -AsPlainText $PASSWORD -Force
\$SecureString = \$pass
"""
}
}
}
So first of all you use multiline syntax """ so the different powershell statements are in the same session, and those variables are available across powershell commands.
Second, you escape powershell variables \$pass and \$SecureString, so groovy does not try to expand them, and you don't escape variables where you are actually referring to groovy variables like $PASSWORD.
Note that $PASSWORD does not have to be in quotes, since powershell parameters can accept strings without quotes, but if this was used in a method you should put it into quotes SomePowershellMethod("$GROOVYVAR").
In general I suggest to echo every variable while troubleshooting, to see if you are getting what you are expecting.

I like short and precise answer.
Use following :
stage('Deployment') {
steps {
withCredentials([usernamePassword(credentialsId: 'UatServer', passwordVariable: 'passVar', usernameVariable: 'userVar')]) {
powershell '''
$passVar = ConvertTo-SecureString "$($ENV:passVar)" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ("$ENV:userVar", $passVar)
$session = New-PSSession -ComputerName x.x.x.x -Credential $credential
Invoke-Command -Session $session -ScriptBlock {hostname}
'''
}
}
}

Related

Jenkins parameter value not resolving for a bat command

I am trying to resolve a parameter inside a windows path, so can we do that.
def Job_Name=params.Job_Name
pipeline {
agent none
options {
skipDefaultCheckout()
}
stages {
stage("Export_Package"){
agent {
label 'xxxxx'
}
steps{
bat 'E:\\sashome\\SASPlatformObjectFramework\\9.4\\ExportPackage -user "xxxxx" -password "xxxxxx" -host "xxxxxxx.com" -port "1234" -package "E:\\sasconfig\\Lev1\\SASApp\\SASEnvironment\\SASCode\\Jobs\\Devops_EportJobs\\"${Job_Name}".spk" -objects "/Shared Data/Jenkins" -subprop "${Job_Name}".subprop'
}
}
}
}
Can we call "${Job_Name}" like this inside the path?? If not, can someone please let me know how to accomplish the same. I just want to pass the Job_Name inside the path, so that I don't have to hard code the job_Name.spk and can keep it dynamic. Whatever Job_name I will pass on the Parameter it should pick that and resolve the same before .spk
Please help me if possible.
Read groovy string basics:
https://groovy-lang.org/syntax.html
Basically, you're wrapping your argument with single quotes when you should be using double quotes. Then when using double quotes, escape all the double quotes within the argument itself:
bat "E:\\sashome\\SASPlatformObjectFramework\\9.4\\ExportPackage -user \"xxxxx\" -password \"xxxxxx\" -host \"xxxxxxx.com\" -port \"1234\" -package \"E:\\sasconfig\\Lev1\\SASApp\\SASEnvironment\\SASCode\\Jobs\\Devops_EportJobs\\\"${Job_Name}\".spk\" -objects \"/Shared Data/Jenkins\" -subprop \"${Job_Name}\".subprop"
From reading the comment, it seems this is what you are looking for (removed literal quotes around Job_Name variable):
bat "E:\\sashome\\SASPlatformObjectFramework\\9.4\\ExportPackage -user \"xxxxx\" -password \"xxxxxx\" -host \"xxxxxxx.com\" -port \"1234\" -package \"E:\\sasconfig\\Lev1\\SASApp\\SASEnvironment\\SASCode\\Jobs\\Devops_EportJobs\\${Job_Name}.spk\" -objects \"/Shared Data/Jenkins\" -subprop ${Job_Name}.subprop"

How to escape password in Jenkins Pipeline

In my pipeline script I want to execute the following sh command including a password (e.g. 123$ABC) with special characters:
withCredentials([sshUserPrivateKey(credentialsId: 'id', keyFileVariable: 'keyFile', passphraseVariable: '', usernameVariable: 'user')]) {
sh "ssh -i $keyFile ${user}#${virtualMachine} -C \"CONTAINER_NAME=${dockerContainerName} DOCKER_TAG=${dockerImageTag} JASYPT_MASTER_PASSWORD='${JASYPT_MASTER_PW}' docker-compose -f /tmp/docker-compose-jenkins.yml up\""
}
How must the command look like to obtain the special characters in my password?
I have the same issue, the possible solution is to decode the password variable, something like:
def encodedPassword = URLEncoder.encode("$JASYPT_MASTER_PW",'UTF-8')
and then use the encodedPassword variable instead of JASYPT_MASTER_PW
Let's try

Jenkins get Environment variable form calling shell script

In a Jenkinsfile, I am trying to set an environment variable by using withCredentials to call a shell script to return a list of data. I want to use this environment variable to populate a drop-down list.
environment {
withCredentials([
usernamePassword(
credentialsId: "aws-creds",
usernameVariable: "AWS_ACCESS_KEY_ID",
passwordVariable: "AWS_SECRET_ACCESS_KEY"
)
]) {
AWS_DATA = sh 'aws ec2 describe-security-groups --region my-region | grep "xxxx" | sort -u | cut -d\" -f4'
}
}
Any help appreciated.
Thanks,
B

Is there a PowerShell variable that can be checked to see if you the script is running in the Azure cloud shell?

Something similar to $IsLinux or $IsWindows.
From your description, I am not sure how did you run your script. If you use Start-Job to run the PowerShell script as a background job, you could use Get-Job to see the State.
Start-Job -FilePath ./GetDate.ps1
Get-Job
This is an old, but I had the same question and found this environment variable that works for my purposes. I'm not sure if there's another "official" way though.
PS> $env:AZUREPS_HOST_ENVIRONMENT
cloud-shell/1.0
I would suggest running a command in a try/catch that is specific to cloud shell, if that is what you are looking for?
try {
$sessioninfo = Get-CloudDrive
if ($sessioninfo) {
Write-Host "Running in Cloud Shell mode..." -ForegroundColor Green
$path = ($home + "/clouddrive/" + "report" + "-$(get-date -Format yyyyddMM_hhmmtt).csv")
}
}
catch {
Write-Host "Running in local PowerShell session mode..." -ForegroundColor Yellow
$path = "C:\localpath\report"+"-$(get-date -Format yyyyddMM_hhmmtt).csv"
}

PowerShell workflow doesn't work in Jenkins?

I have a script in PowerShell. It's running from Jenkins via a PowerShell step. Without Jenkins all works fine. But when I build it with Jenkins, I got nothing... no errors, just nothing. What's wrong? Jenkins can't use PowerShell workflow?
Simple example:
workflow config {
Param([string[]]$servers, $MaxEnvSize, $MaxMemPerShell)
$servers = $servers.Trim()
foreach -parallel -throttlelimit 50 ($server in $servers) {
if (Test-Connection -ComputerName $server -Quiet -Count 1) {
inlinescript {
try {
Invoke-Command -ComputerName $using:server -ea Stop -ScriptBlock {
Param($MaxEnvSize, $MaxMemPerShell)
Set-Item WSMan:\localhost\MaxEnvelopeSizekb -EA Stop -Value $MaxEnvSize
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB -EA Stop $MaxMemPerShell
Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB -EA Stop $MaxMemPerShell
#Restart-Service winrm
} -ArgumentList $using:MaxEnvSize , $using:MaxMemPerShell
} catch {
"$using:server : $Error[0].Exception"
}
}
} else {
Write-Output "$server no ping"
}
}
}
config -Servers $env:servers -MaxEnvSize 16454 -MaxMemPerShell 5192
By default jenkins will use 32-bit powershell. Powershell workflow is supported only in 64-bit powershell. trigger powershell script using C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe which will redirect to 64-bit powershell.

Resources