I have an Ansible role that executes Powershell scripts. I do this
- name: Set the execution policy to Unrestricted first
win_shell: Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine -Force
tags: always
- name: Start the services
win_shell: C:\Users\Administrator\Desktop\Start_Services.ps1
args:
chdir: C:\Users\Administrator\Desktop\
when: exa_services_state == "started"
tags: always
- name: Stop the services
win_shell: C:\Users\Administrator\Desktop\Stop_Services.ps1
args:
chdir: C:\Users\Administrator\Desktop\
when: exa_services_state == "stopped"
tags: always
- name: Set the execution policy to RemoteSigned
win_shell: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
tags: always
However when the last task executes, I get the following
fatal: [10.227.26.97]: FAILED! => {"changed": true, "cmd": "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force", "delta": "0:00:00.640619", "end": "2022-03-04 05:33:29.496843", "msg": "non-zero return code", "rc": 1, "start": "2022-03-04 05:33:28.856224", "stderr": "Set-ExecutionPolicy : Windows PowerShell updated your execution policy successfully, but the setting is overridden by \r\na policy defined at a more specific scope. Due to the override, your shell will retain its current effective \r\nexecution policy of Unrestricted. Type \"Get-ExecutionPolicy -List\" to view your execution policy settings. For more \r\ninformation please see \"Get-Help Set-ExecutionPolicy\".\r\nAt line:1 char:65\r\n ... ing $false; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope ...\r\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n CategoryInfo : PermissionDenied: (:) [Set-ExecutionPolicy], SecurityException\r\n FullyQualifiedErrorId : ExecutionPolicyOverride,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand", "stderr_lines": ["Set-ExecutionPolicy : Windows PowerShell updated your execution policy successfully, but the setting is overridden by ", "a policy defined at a more specific scope. Due to the override, your shell will retain its current effective ", "execution policy of Unrestricted. Type \"Get-ExecutionPolicy -List\" to view your execution policy settings. For more ", "information please see \"Get-Help Set-ExecutionPolicy\".", "At line:1 char:65", " ... ing $false; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope ...", " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", " CategoryInfo : PermissionDenied: (:) [Set-ExecutionPolicy], SecurityException", " FullyQualifiedErrorId : ExecutionPolicyOverride,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand"], "stdout": "", "stdout_lines": []}
If I go on the node and execute Get-ExecutionPolicy
I see
PS: C:\Users\myuser>Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine RemoteSigned
How can I avoid the error? Thanks!
CodePudding user response:
Your command actually succeeded(!) in principle, as evidenced by the wording of the error message.
If all you want to do is to set the local-machine policy for future sessions, you can simply ignore the error, by enclosing the statement in try
/ catch
; also note the trailing ; exit 0
so as to ensure that exit code 0
is reported back to Ansible:
win_shell: try { Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force } catch { }; exit 0
Note: If you're confident that you're running with elevation (which setting the machine policy requires), an empty catch
block, as above, is probably sufficient.
A robust solution requires a bit more work:
win_shell: try { Set-ExecutionPolicy -Scope LocalMachine allSigned -force } catch { if ($_.FullyQualifiedErrorId -ne 'ExecutionPolicyOverride,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand') { throw } }; exit 0
This selectively ignores the anticipated error while re-throwing any others.
As an aside: It is unfortunate that the situation described by the error message, explained below, is surfaced as an error, let alone as a (statement)-terminating one. This is discussed in GitHub issue #12032, but a decision was made to retain this behavior for the sake of backward compatibility.
What the message is trying to tell you is that your execution policy will not take effect - in your case in the current session - because it is preempted by a less restrictive policy in a scope with higher precedence - see the conceptual about_Execution_Policies help topic.
Unfortunately, the error is also triggered for ad hoc, process-specific overrides (the Process
scope), via the powershell.exe
CLI's -ExecutionPolicy
parameter, so that a command such as the following triggers it:
powershell -ExecutionPolicy Bypass -c Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
That is, the session in which the Set-ExecutionPolicy
command executes has a process-specific execution policy of Bypass
, and because the Process
scope has higher precedence than the CurrentUser
scope, and because the Bypass
policy is less restrictive than RemoteSigned
, the error occurs.
Technically, in that specific session itself the Set-ExecutionPolicy
doesn't take effect (because the process-specific Bypass
overrides it), but it will in future sessions (unless overridden again) - and if the sole intent of the CLI call was to set the persistent execution policy for future sessions, the error is nothing but a confusing annoyance.
I presume you're seeing this error because Ansible is using powershell -ExecutionPolicy Bypass
(or Unrestricted
) behind the scenes when it processes win_shell
commands.