Pass build variables to powershell inline script in Azure DevOps pipeline - powershell

I have set a build variable which I would like to consume in my inline powershell script.
I tried $($myvariable) but this comes out blank.

Pass build variables to powerhshell inline script in Azure DevOps
To get the build variables with inline power shell script, you can try to use following syntax $env:variable:
$env:myvariable
The build variable:
The build result:
Note:At this moment, the value of nested variables (like $(myvariable$(Build.SourceBranchName))) on build variables table are not yet supported in the build pipelines.
Hope this helps.

here's what's working for me:
$(variableName)
for example built-in variable called Build.BuildNumber can be accessed like so:
$(Build.BuildNumber)
full example with format function:
- task: AzurePowerShell#3
displayName: UpdatePrereq
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
ScriptType: InlineScript
Inline: |
${{ format('. $(Build.Repository.LocalPath)\scripts\_helpers.ps1
Update-DeploymentPrereq -resourceGroup {1} -location {3}
Update-Prereq -pathSuffix {0} -pathBase $(Build.Repository.LocalPath) -resourceGroup {1} -buildId $(Build.BuildNumber) -paramFile {2}
Update-DeploymentConcurrency -resourceGroup {1} -buildId $(Build.BuildNumber)',
parameters.buildDir, parameters.resourceGroupName, parameters.paramFile, parameters.location ) }}
azurePowerShellVersion: LatestVersion

If you need to use nested variables you can use something like this:
$name = "CONNECTIONSTRING_$(Agent.MachineName)"
$val = [System.Environment]::GetEnvironmentVariable($name)
And then you get the value of the variable ConnectionString.MACHINENAME

Related

Not able to replace variable values in Azure PowerShell with script arguments to update APIM policies

I have defined my code like this:
param ($apim_service_name, $apprid, $rg_name, $tid, $url)
<set-url>#($"$url/{(string)context.Variables["insured-id"]}")</set-url>
$apimContext = New-AzApiManagementContext -ResourceGroupName $rg_name -ServiceName $apim_service_name
Set-AzApiManagementPolicy -Context $apimContext -Format "application/vnd.ms-azure-apim.policy.raw+xml" -ApiId "echo-api" -OperationId "retrieve-resource" -Policy $PolicyStringRead
In the pipeline variable I have added variables and used in my pipeline templates
My PowerShell script looks like this:
steps:
- task: AzurePowerShell#5
displayName: 'Azure PowerShell script: FilePath'
inputs:
azureSubscription: 'sub-test'
ScriptPath: 'test-policy.ps1'
ScriptArguments: '"$(apim_service_name)" "$(apprid)" "$(rg_name)" "$(tid)" -url $(url)'
azurePowerShellVersion: LatestVersion
Defined variables in variables section of the pipeline
Everything is replacing except the "url"
Is it the two "$" symbols that is affecting to replace the string?
Can anyone help me on how to update this, because it requires first "$" symbol in order to read the value
Thanks #jdweng for suggesting the right solution to the user that resolved the issue.
PS will not substitue variable inside a single quote (only double quote). Use two double quotes to escape single quote : ScriptArguments: "$apim_service_name $apprid $rg_name $tid -url $url"
We can enclose a string in both Single Quotation or the double Quotations but to replace the value in the variable that starts with the dollar sign ($) before sending for the command processing, you have to use only double quotes as given in this MS Doc of PowerShell Quoting Rules.

Azure devOps deployment release setup

If the connection string is setup as a secret variable in the release pipeline.
Is there any way or any one to view the secret variable? If yes, how could we do it?
I write a powershell demo in the YAML file for you(Based on Daniel's idea.), please notice on the pipeline you will be unable to output the value because all of the same value will be captured by the pipeline and all of them will be covered by "***".
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Write-Host $(not_secure)
Write-Host $(secure)
#convert string to based64 string:
$secret = "$(secure)"
$secret = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($secret))
Write-Host $secret
Write-Host "value2" #Whenever the pipeline capture the same value of the secured secret, the pipeline will output '***'. So doing any tricks inside the pipeline can't make the pipeline output this value
Whenever the pipeline capture the same value of the secured secret,
the pipeline will output '***'. So doing any tricks inside the
pipeline can't make the pipeline output this value.
My pipeline output:
My variables:
get_secret_of_pipeline.ps1(run this on your machine.)
$secret = "dmFsdWUy"
$secret = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secret))
Write-Host $secret
Successfully get the value of secret:

##[error]Required: 'ConnectedServiceNameARM' input --- Azure DevOps

##[error]Required: 'ConnectedServiceNameARM' input
This is in Azure DevOps using YAML inline script.
Need help with what to enter to fix this error? I am really new at YAML. This is a inline YAML and what tried seems to break the YAML script. The ConnectedServiceNameARM is just the Azure Subscription name? My service connection in azure devops has a working azure subscription name so I am wondering what is wrong?
Also need this YAML code to run so that the output file is placed in agent/_work/_tasks folder and not the artifacts folder. How would I move the file from the _tasks/Powershell folder to something that can be copied to share?
trigger:
- main
pool:
name: 'CloudUiPath001'
demands:
- agent.name -equals UiPathAgent01
steps:
- task: AzurePowerShell#3
displayName: 'Azure PowerShell script: InlineScript'
inputs:
ScriptType: InlineScript
Inline: |
$filePath='C:\Program Files (x86)\UiPath\Studio'
$dir=(New-Object -com scripting.filesystemobject).getFolder($filePath).ShortPath
$ProjectFilePath= "$(System.DefaultWorkingDirectory)/_TESTREPO7/project.json"
$ExecutableFilePath=$dir+"\UiPath.Studio.CommandLine.exe"
$OutputFilePath=".\$(Get-Date -Format 'yyyy-MM-dd-HH-mm-ss')-Workflow-Analysis.json"
#This was an attempt to write the filename to a pipeline variable: Feel free to continue on this path if possible
Write-Host "##vso[task.setvariable variable=jsonFilePath]$OutputFilePath"
Write-Output "$(Get-Date -Format 'HH:mm:ss') - STARTED - Workflow Analyzer CLI Script"
$Command = "$ExecutableFilePath analyze -p $ProjectFilePath"
Invoke-Expression $Command | Out-File -FilePath $OutputFilePath
Write-Output "$(Get-Date -Format 'HH:mm:ss') - COMPLETED - Workflow Analyzer CLI Script"
azurePowerShellVersion: LatestVersion
How do I fix his error within a INLINE YAML script. I am new to YAML and when I tried to enter a input I got errors.
##[error]Required: 'ConnectedServiceNameARM' input
According to your AzurePowerShell task definition, you don’t seem to specify the azureSubscription field.
steps:
- task: AzurePowerShell#5
displayName: 'Azure PowerShell script: InlineScript'
inputs:
azureSubscription: 'xxx'
ScriptType: InlineScript
Inline: xxx
azurePowerShellVersion: 'LatestVersion'
You can click the Settings shown in the figure below to specify the subscription.
About Azure PowerShell task, please refer to this document for details.
to go around this error change from task: AzurePowerShell#5 to pwsh:
- pwsh: |
InlineScript
displayName: 'Azure PowerShell script: InlineScript'

Get secret value from azure key vault in variable in powershell script

I need to set secret value from azure key vault into a variable to be used in further task. I tried below script but it gives error: Could not find the modules: 'Az.Accounts' with Version: ''.
I understand that I can use variable directly but it needs to be set to a common variable since I am building generic pipeline
Script I tried:
- task: AzurePowerShell#4
inputs:
azureSubscription: 'SUB1'
ScriptType: 'InlineScript'
Inline: |
$secret = Get-AzKeyVaultSecret -VaultName '$(KeyVaultName)' -Name $(sqlServerAdminUsername)
$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
try {
$SqlServerUsername = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
} finally {
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
}
azurePowerShellVersion: 'LatestVersion'
pwsh: true
condition: and(succeeded(), eq(variables['EnvironmentType'], 'Dev'))
Check out this similar issue.
Fixes can be:
Try switching to version 3 and 5 of Powershell task and run.
Run the Powershell V4 task in Linux hosted Agents instead of Windows.
Run this powershell screipt from Azure CLI task.

How to get output from Azure Devops Powershell YAML

I have a yaml pipeline, using the task Azure Powershell Task
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-powershell?view=azure-devops
The script already has task output as follows:
$output = ConvertTo-Json -InputObject #{
resourceName = "aseName"
resourceGroupName = "ResourceGroupName"
} -Compress
Write-Output "##vso[task.setvariable variable=output;]$output"
In the subsequent task, within the same job. I need to use use it as {output.resourceName}. Typically from the designer it is possible to get it out the same way as I want. But with YAML I could not figure it out.
Any pointers?
just reference it like any other variable:
$(output)
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-in-script
As a side note, which might save others some time in the future. When you create a new stage and want to reference your variable, you should also add "isOutput=true" when you're setting the variable:
Write-Output "##vso[task.setvariable variable=output;isOutput=true]$output"
And when referencing the Output variable in YAML, call the variable as such:
- stage:
displayName: someName
variables:
output: $[stageDependencies.<stageName>.<jobName>.outputs['<stepname>.output']]
jobs:
- job: SomeName
steps:
- task: SomeTask