Win_command | win_shell fails on running a powershell script

I’m facing an issue where running a powershell script via Ansible compared to running it locally behaves differently.

Initially started out using the win_powershell and placing a script block in the task.
Though I was having escaping issues so I switched to doing a win_copy of the script and then simply executing using both win_command and win_shell. Neither works and I’m getting “Win32: 8322 ERROR_DS_RANGE_CONSTRAINT” trying to setup a Active Directory Certificate Service.

“A value for the attribute was not in the acceptable range of values…”

So this is the task:

  - name: Run the script
    win_command: powershell.exe -File C:\Temp\Script.ps1
    args:
       creates: <CSR req file>

Running the exact same command locally works as expected so the script should be fine. Cannot work out what’s different. Tried also using win_powershell and using different executables and also fullpathing it so I know that its the same powershell for Ansible as running it locally.

You’re facing a character escape issue, and the win_command is already using powershell so your command is a little redundant and might not capture the stdout.

Ansible/Python uses backslashes to escape special characters, while powershell uses the backtick `. You will need to escape backslashes in Windows filepaths on the Ansible side of things.

  - name: Run the script
    ansible.windows.win_command: C:\\Temp\\Script.ps1
    args:
       creates: <CSR req file>
# or
  - name: Run the script
    ansible.windows.win_command: C:/Temp/Script.ps1
    args:
       creates: <CSR req file>

It might be easier to have the script be on your ansible controller though and do:

  - name: Run the script
    ansible.builtin.script: Script.ps1
    args:
       creates: <CSR req file>

Lastly, if you need more control over what’s happening with powershell, you could combine the lookup plugin with the win_powershell module:

  - name: Run the script
    ansible.windows.win_powershell:
      script: "{{ lookup('file'), 'Script.ps1' }}"
    arguments:
      - -ExecutionPolicy
      - Bypass
    args:
       creates: <CSR req file>
# or even use templates
# embeded Ansible vars in powershell? Yes, please!
  - name: Run the script
    ansible.windows.win_powershell:
      script: "{{ lookup('template'), 'Script.ps1.j2' }}" 
    arguments:
      - -ExecutionPolicy
      - Bypass
    args:
       creates: <CSR req file>

Unfortunately, with the last two, you might have to escape your backslashes so that the script isn’t garbled before it reaches powershell. Kinda depends on whether Ansible is copying and forwarding the files or actually reading and interpreting them. It’s been a while since I’ve done this, so I can’t recall if the script module or either lookup plugin needs the escapes to work.

1 Like

Ansible/Python uses backslashes to escape special characters, while powershell uses the backtick `. You will need to escape backslashes in Windows filepaths on the Ansible side of things.

You only need to escape the \ if you set the value inside double quotes which OP did not here. For example these values all result in the literal value C:\temp\script.ps1

key: C:\temp\script.ps1
key: 'C:\temp\script.ps1'
key: "C:\\temp\\script.ps1"

Only the double quoted value need to have the backslashes escaped.

Neither works and I’m getting “Win32: 8322 ERROR_DS_RANGE_CONSTRAINT” trying to setup a Active Directory Certificate Service.

Certificate operations require you to authenticate yourself both with the AD CS server to prove you can actually get the certificate from the csr as well as the ability to unlock the DPAPI store to store the private key. You most likely have to run this with become Understanding privilege escalation: become — Ansible Documentation to do the credential delegation and unlock the DPAPI store.

2 Likes

I stand corrected. Though I could have sworn that not quoting a yaml string behaved more like using double quotes than single quotes.