Home > Software engineering >  Can you have a function in an inline powershell script in a Azure pipeline YAML file?
Can you have a function in an inline powershell script in a Azure pipeline YAML file?

Time:11-19

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

  - task: AzureCLI@2
    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?

CodePudding user response:

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 first before you can call them, i.e., in your source code you must place the function definition before any statements that call it.

As of this writing, the relevant conceptual help topic, about_Functions, doesn't make that clear, unfortunately. GitHub docs issue #8370 suggests remedying that.


To spell the solution out for your code:

 - task: AzureCLI@2
    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"

  • Related