powershellazure-powershellazure-yaml-pipelines

Azure Yaml to Powerhell value being lost in parameter


I have an Azure Pipeline that is calling a PowerShell file using @AzureCLI@2 but at the top of the script I appear to be losing a value passed in which is the directory I want to load a file from.

If I perform this Task in Yaml:

- powershell: Get-ChildItem -Path ${{ parameters.artifactFolder }} -recurse

I can see outputs as such:

    Directory: C:\a\2\s\firewall\Parameters\output\myDir


Mode                 LastWriteTime         Length Name                                                                 
----                 -------------         ------ ----                                                                 
-a----         6/20/2023   1:30 PM        3804260 parameters.json     

The next Yaml task:

- task: AzureCLI@2
  displayName: Remove Resource Locks
  inputs:
    azureSubscription: ${{ parameters.serviceConnection }}
    scriptType: 'ps'
    scriptLocation: 'scriptPath'
    ScriptPath: '${{ parameters.artifactFolder }}/powershell/fw.removeLocks.ps1'
    arguments: >
      -firewallOutputFolder "${{ parameters.artifactFolder }}"
      -action "Remove"
    workingDirectory: '$(System.DefaultWorkingDirectory)'  

Passes in the directory. With the PowerShell script, the following code is at the start of the file:

    [parameter(Mandatory = $true)][string] $firewallOutputFolder,
    [ValidateSet("Create", "Remove")]
    [parameter(Mandatory = $true)][string] $action
    
    try 
    {
    
        # Either remove or create locks for Firewall and FW Policy
        Write-Host "First WH......................"
        Write-Host $firewallOutputFolder
        Write-Host "$($firewallOutputFolder)\Parameters\output"
    
    
        $folder = $firewallOutputFolder
    
        # Loop output files i.e. deployment files
        $fwFiles = Get-ChildItem $firewallOutputFolder -Directory
        foreach($fwFile in $fwFiles)
        {
            $fwParameters = "$($firewallOutputFolder)\$($fwFile.name)\parameters.json"
}
    }

The outputs from the first batch of write-host:

First WH......................

\Parameters\output

The value being passed in is now empty/null

Does anyone have any suggestions as to why the value is vanishing?


Solution

  • Your PowerShell script is missing the param(...) enclosure around your individual parameter declarations - see the conceptual about_Functions help topic.

    Therefore:

    # Parameter declarations must be enclosed in param(...)
    param(
      [Parameter(Mandatory)]
      [string] $firewallOutputFolder
      ,
      [Parameter(Mandatory)]
      [ValidateSet('Create', 'Remove')]
      [string] $action
    )
    
    # ...
    

    Unfortunately, forgetting param(...) effectively results in quiet failure:

    Therefore, your script doesn't declare any parameters at all, which means that not only does it not enforce mandatory arguments, but happily accepts any number of (positional) arguments, which are then only reflected in the automatic $args variable.


    This quiet failure due to what should arguably be a syntax error is unfortunate.
    GitHub issue #10614 asks that such cases either be prevented syntactically or at least generate a warning.