Search code examples
powershellansibleparametersparameter-passingansible-tower

Ansible Tower pass parameter to powershell script


I am trying to pass ansible variables to my powershell script as parameters. While they are successfully being passed, the path of my file is being cut short. For example, when passing a string '/Microsoft SQL Server/files/blah', and printing it in the code, it becomes '/Microsoft'.

Here is my playbook file:

- name: Deploy Report
  hosts: ******
  tasks:
    - name: Run Powershell Script
      script: "../deploy.ps1 -input1 '{{ input1 }}'"
      args: 
        executable: powershell
 

Any help is greatly appreciated


Solution

  • Judging by the documentation of the Ansible script module (and since confirmed to be correct by you):

    • A given script and its arguments are executed via a shell.

    • On Windows that shell appears to be PowerShell (powershell.exe, the Windows PowerShell CLI), and it appears that what follows the script: property is passed to the -Command (-c) parameter.

      • This parameter interprets its argument(s) as arbitrary PowerShell code, which therefore are processed based on PowerShell's syntax rules.
      • As an aside: This means that you're not limited to calling script files, and that you can pass multiple commands, separated with ;

    For that reason, you do not need to specify an executable: argument in order to execute PowerShell scripts on Windows, and the following should suffice (note that I'm using the module's FCQN (Fully Qualified Collection Name), ansible.builtin.script instead of the short name script:, as recommended in the docs):

    - name: Deploy Report
      hosts: ******
      tasks:
        - name: Run Powershell Script
          ansible.builtin.script: "../deploy.ps1 -input1 '{{ input1 }}'"
    

    As for what you tried:

    By specifying powershell as an executable: argument under args:, you ended up nesting two instances of PowerShell: one that is implicitly used for execution, and the other is the one you're calling explicitly.

    • Note that specifying neither -Command (-c) nor -File (-f) before a command in a powershell.exe call implies -Command (-c)

    This nesting is not only unnecessary, but causes the effective loss of the '...' quoting in your script: command line, which explains your symptom.

    The following example demonstrates this - run it from an interactive cmd.exe session (to simulate a no-shell invocation of powershell.exe; if you place -noexit before -c, you can also invoke the command from the Windows Run dialog (WinKey+R) for a true no-shell call):

    powershell.exe -c powershell.exe -c Write-Output 'foo bar'
    

    This doesn't output verbatim foo bar, as one might expect, but outputs foo and bar on separate lines; that is, the '...' enclosure was effectively lost, and what was ultimately executed was
    Write-Output foo bar, i.e, two arguments were passed.

    The reasons are subtle:

    • When PowerShell executes an external program - including its own CLI - it must translate its '...' quoting into "..." quoting behind the scenes, given that Windows CLIs can only be expected to understand the latter form.

      • Note: Unlike on Unix, Windows CLIs must act as their own mini-shell and extracts their arguments from a process-level command-line string.
    • Therefore, when the outer powershell call invokes the inner one, it translates 'foo bar' into "foo bar" behind the scenes.

    • However, powershell.exe considers (unescaped) "..." quoting to merely have syntactic function on the command line, and such quoting is removed before the resulting argument(s) are interpreted as PowerShell code, so that the inner powershell.exe ends up executing Write-Output foo bar

      • If you use "..." quoting to begin with, you can see the problem even with a single call to powershell.exe (again, foo and bar print on separate lines, due to two arguments getting passed):

        powershell -c Write-Output "foo bar"
        

    [1] Notably, this default changed to -File (-f) in pwsh, the PowerShell (Core) 7+ CLI.