How can I pass a parameter to a PowerShell-Inline-Task?
Or how can I access the parameter in a PowerShell-Inline-Task?
I know that there is the "$env"-Variable, and that I can read variables, but how is this done with parameters?
Tested from my side, I use parameters in PowerShell-Inline-Task as the following.
The name of the parameter is "paratest", the type is string, the default value of it is one and also it has another value "two".
I get and output the value of the parameter in the PowerShell task using ${{ }}.
parameters:
- name: paratest
type: string
default: one
values:
- one
- two
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: 'Write-Host "The value of parameter paratest is ${{parameters.paratest}}"'
Before I run the pipeline, I can choose the value of the parameter "paratest".
Then I can see the value of this parameter in the PowerShell task.
For more info about parameters, you can refer to Runtime parameters.
It does not support that: PowerShell#2 - PowerShell v2 task
arguments - Arguments string. Optional. Use when targetType =
filePath.
Specifies the arguments passed to the PowerShell script. Arguments can
be ordinal parameters or named parameters. For example, -Name someName
-Path -Value "Some long string value".
arguments is not used when targetType is set to inline.
consider using logging commands: Set variables in scripts, SetVariable: Initialize or modify the value of a variable
Related
I have below code in yaml file:
trigger:
branches:
include:
- maventest
pool:
vmImage: ubuntu-latest
steps:
- task: PowerShell#2
inputs:
filePath: './1.ps1'
Below is 1.ps1 file
$user1=#($(user))
Write-Host $(user)
write-host $user1[0]
As I can pass the value of variable inside while run pipeline but user is not getting from variable.
I had also used the $(env:user) but it didn't get value from variable.
From your YAML sample, the cause of the issue is that the pipeline variable is not able to directly expand in PowerShell file.
To solve this issue, you can pass the pipeline variable to ps file via argument of PowerShell task.
Here is the example:
Ps file sample:
param($user)
$user1=#($user)
Write-Host $user
write-host $user1[0]
Pipeline sample:
steps:
- task: PowerShell#2
inputs:
filePath: './1.ps1'
arguments: '-user $(user)'
Result:
I have one variable group in ADO library which store different paths and some other variables.
In my main "master" pipeline I use it as below:
variables:
- group: myGroupName
- name: nameOfMyVariable(from variables group) or JustAnyName
- value: $[variables.nameOfMyVariable] or $[variables.JustAnyName]
then in job in the first Stage (for testing, there is only one stage and job for now) I'm trying to using template yaml:
jobs:
- template: my-template.yaml
parameters:
path: $(nameOfMyVariable) or $(JustAnyName)
then in my-template.yaml I have this code:
parameters:
- name: path
type: string
default: ''
jobs:
- job: BuildSomething
steps:
- task: CopyFiles#2
inputs:
Contents: |
${{ parameters.path }}
TargetFolder: '$Build.ArtifactStagingDirectory)'
....
Rest is not that important as it just can't find files to copy and when I try to print parameters.path with echo I get error :
syntax error: invalid arithmetic operator(error token is ".nameOfMyVariable").
I do not know how to fix it so I can access variables from variable group in some of my templates. Do I need to use ##vso[task.setvariables] or something else?
If you want use variable from variable group it is enough to just include this group
variables:
- group: myGroupName
And then use variable by name $(nameOfMyVariable)
In your example it seems you try unnecessary try to declare this variable again in first yaml example.
This example is additionally incorrect because you are addings dash directly before 'value' keyword and it may cause undefined behaviour.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#specify-variables
Just like Kontekst says, when it comes to variable groups, you don't need to declare the variable names and values in your yaml. Once you declare the variable groups in your yaml, you could use the variables from the groups directly.
And if you are using parameters against templates, for your scenario, I suppose that you could declare the parameters in your main yaml, and input the parameter value into your template. (and you don't have to use the variable groups)
My main yaml as below.
trigger:
- none
pool:
vmImage: ubuntu-latest
parameters:
- name: pathmain
displayName: Source Path
type: string
default: README.md
values:
- azure-pipelines.yml
- README.md
jobs:
- job:
steps:
- script: echo ${{ parameters.pathmain }}
- template: test-template.yml
parameters:
path: ${{parameters.pathmain}}
My test-template as below.
parameters:
- name: path
displayName: Source Path
type: string
jobs:
- job: BuildSomething
steps:
- task: CopyFiles#2
inputs:
Contents: |
${{ parameters.path }}
TargetFolder: '$Build.ArtifactStagingDirectory'
I want to be able to invoke the Counter expression within a template but I am unsure how to do so; my current template yml file looks like this:
parameters:
- name: major
type: string
default: '1'
- name: minor
type: string
default: '0'
steps:
- task: PowerShell#2
displayName: Set NuGet package version
inputs:
targetType: 'inline'
script: |
$isMain = ('$(Build.SourceBranch)' -eq 'refs/heads/main')
$minor = ${{ parameters.minor }}
$revision1 = $[counter($minor, 1)]
Write-Host $revision
exit 0
But I get:
The term '$[counter' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I am guessing there is way I can invoke the function via Powershell.
The reason for me wanting to do this in the template as opposed to passing it in as a parameter from the consumer of the template is because seemingly parameters are not evaluated when passed into a template.
Evaluating Azure Devops Expressions within Powershell
Just as Daniel said that:
The powershell script you're trying to run is getting finalized
during compile time. This line: $revision1 = $[counter($minor, 1)]
cannot possibly work. You are trying to take the results of a
powershell script expression and use it in a YAML function.
That is reason why it is not work for you.
And personally think you can go the easier way, just define the variable in the main YAML file:
azure-pipelines.yml:
variables:
- name: minor
value: 0
- name: revision1
value: $[counter(variables['minor'], 0)]
stages:
- stage: Run
jobs:
- job:
steps:
- template: Template.yml
And we could use the the Counter in the template directly:
Template.yml:
steps:
- task: PowerShell#2
displayName: Set NuGet package version
inputs:
targetType: 'inline'
script: |
Write-Host '$(revision1)'
The test result:
I have Azure DevOps build pipeline yml that has parameters, variables defined and at the same time I have an external tool that kicks of the jobs in the yml including passing in some parameters. At first I thought the parameters in the yml and incoming parameters should be the same, so I lined up all the names to match. Only to find out that the incoming parameters through REST API is actually a variable!
parameters:
- name: machineList
type: string
default: any
then I have variable declared like so
variables:
testsettingsjson: ${{ parameters.machineList }}
From the REST API that get's passed in and when I query the request coming in, calling the get build data api, I see
"parameters" : "{ \"machineList\" : \"machine1\" }"
Now trying to use the variable it works in some places and not in others.
- script: |
echo "Output variable values"
echo "ML json : '$(testsettingsjson)'"
echo "ML json : '$(machineList)'"
echo "ML json variables : '${{ variables.machineList }}'"
the output I see for the above is :
Output variable values
ML json : any
ML json : machine1
ML json variables:
So $(machineList) works, I thought.
- task: PowerShell#2
displayName: 'Read ML input value'
inputs:
targetType: filePath
filePath: ./ReadMachineList.ps1
continueOnError: true
env:
TESTSETTINGSJSON: $(machineList)
When I read TESTSETTINGSJSON using $env:TESTSETTINGSJSON from the powershell script above, the value is "any"!
I am super confused. What am I doing wrong?
Only to find out that the incoming parameters through REST API is
actually a variable!
This is as expected. The parameters you specify in the request body of the rest api actually represents the variable. If you want to replace the runtime parameter, you should use templateParameters instead.
$json= #'
{
"templateParameters": {
"machineList": "machine1"
}
}
Solved it. To make it work, I first structured my solution working with 3 separate set of "variables", here's an example.
parameters:
- name: MachineList
type: string
default: any
variables:
${{ if ne(variables['machineList'], '') }}:
machinelist: $(machineList)
${{ if ne(parameters.MachineList, 'Any') }}:
machinelist: ${{ parameters.MachineList }}
MachineList is the input to the pipeline.
machineList is the input value from Power Automate (or REST API).
machinelist is the local variable in yml.
Now in the rest of the yml, I can use $(machinelist) switching between the values for the pipeline versus the REST API.
I want to perform some actions (publish) on an array of string which are passed as parameter.
The thing is, this parameter is dynamic :
# pipeline.yml
- job: MyJob
pool:
[...]
steps:
- pwsh: |
$affected = ['app-one', 'app-two'] # Here I hardcoded the array but in my real code this is set dynamically
Write-Host "##vso[task.setvariable variable=affected;isOutput=true]$affected"
name: setAffected
displayName: 'Settings affected'
- template: ./build.yml
parameters:
affected: $[ dependencies.Affected.outputs['setAffected.affected'] ] # Here I pass the array of string to the template
# build.yml
parameters:
affected: ''
jobs:
- job: Build
condition: succeeded('Affected')
dependsOn: Affected
pool:
[...]
variables:
affected: ${{ parameters.affected }}
steps:
- ${{each app in $(affected)}}:
- pwsh: |
Write-Host "${{app}}"
- ${{each app in parameters.affected}}:
- pwsh: |
Write-Host "${{app}}"
Neither of ${{each app in $(affected)}} or ${{each app in parameters.affected}} work...
How can I manage to execute some actions on each of my array item?
Thanks
Within a template expression, you have access to the parameters
context that contains the values of parameters passed in.
Additionally, you have access to the variables context that contains
all the variables specified in the YAML file plus the system
variables. Importantly, it doesn't have runtime variables such
as those stored on the pipeline or given when you start a run.
Template expansion happens very early in the run, so those variables
aren't available.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops