Search code examples
powershellansibleescapingpipelinepowershell-7.3

How can I use $_ in a PowerShell scriptblock in Ansible?


I want to execute some PowerShell code on Linux via Ansible without outsourcing it to a file. I am using the following multiline string command, which works great in general, but does not work as expected as soon as I try to access the current pipeline object a. k. a. $_:

- name: MRE
  ansible.builtin.command: |
    pwsh -c "& {
      1..3 | Foreach-Object {
        $_
      }
      exit 1
    }"

The actual output is:

fatal: [host.domain.tld]: FAILED! => changed=true 
  cmd:
  - pwsh
  - -c
  - |-
    & {
      1..3 | Foreach-Object {
        $_
      }
      exit 1
    }
  delta: '0:00:00.639590'
  end: '2023-03-30 14:48:53.343005'
  msg: non-zero return code
  rc: 1
  start: '2023-03-30 14:48:52.703415'
  stderr: ''
  stderr_lines: <omitted>
  stdout: ''
  stdout_lines: <omitted>

As you can see, stdout is empty, but should contain the numbers 1 to 3. If $_ is not just a number, but an object and I try to access an attribute, it gets translated to /usr/bin/python3.attribute. So maybe bash or python are replacing $_ or _ before it reaches PowerShell.

I then tried to escape $_ like \$_, $\_ and \$\_, but without success. How can I use $_ in this example?


Solution

  • As a workaround, you can replace $_ by $PSItem.

    $_ is an alias for $PSItem (read more).