[SOLVED] Can you have a function in an inline powershell script in a Azure pipeline YAML file?

Issue

I want to be able to simplify some inline powerscript in an AzureCLI task using a function, similar to the following:

  - task: [email protected]
    displayName: "My Task"
    inputs:
      scriptType: pscore
      scriptLocation: inlineScript
      inlineScript: |
        Do-Something "hello" "world"
        Do-Something "goodbye" "world"

        function Do-Something { 
          Param
          (
            [Parameter(Mandatory=$true, Position=0)]
            [string] $Hello,
            [Parameter(Mandatory=$true, Position=1)]
            [string] $World
          )

          Write-Host "$Hello $World"
        }

However this fails with the following error:

+ Do-Something "hello" "world"
+ ~~~~~~~
+ CategoryInfo          : ObjectNotFound: (Do-Something:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CommandNotFoundException
##[error]Script failed with exit code: 1

Is this possible? If so, what am I doing wrong?

Solution

Mathias R. Jessen provided the crucial pointer:

The use of Azure is incidental to your problem, which stems from a fundamental PowerShell behavior:

  • Unlike other languages, PowerShell performs no function hoisting, …

  • … which means that you must declare your functions before you can call them, i.e., in your source code you must place the function definition before any statements that call it.

The relevant conceptual help topic, about_Functions, historically didn’t make that clear, unfortunately, but this has since been corrected. Offline help of existing PowerShell installations would need to be updated manually to see the change.


To spell the solution out for your code:

 - task: [email protected]
    displayName: "My Task"
    inputs:
      scriptType: pscore
      scriptLocation: inlineScript
      inlineScript: |
        # First, declare the function.
        function Do-Something { 
          Param
          (
            [Parameter(Mandatory=$true, Position=0)]
            [string] $Hello,
            [Parameter(Mandatory=$true, Position=1)]
            [string] $World
          )

          Write-Host "$Hello $World"
        }

        # Now you can call it.
        Do-Something "hello" "world"
        Do-Something "goodbye" "world"

Answered By – mklement0

Answer Checked By – Senaida (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *