Search code examples
powershellexecutionpolicy

PowerShell, only run Set-Execution if it is not already set?


I have a script that tries to run these...

Set-ExecutionPolicy -scope CurrentUser RemoteSigned -Force -ea silent
Set-ExecutionPolicy RemoteSigned -Force -ea silent

But I get this error:

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 Bypass. Type "Get-ExecutionPolicy
-List" to view your execution policy settings.

So I tried this:

if ($(Get-ExecutionPolicy) -ne "RemoteSigned") {
    Set-ExecutionPolicy -scope CurrentUser RemoteSigned -Force -ea silent
    Set-ExecutionPolicy RemoteSigned -Force -ea silent
}

But I get the same error (I thought this might skip the if body if I tried this.

I then tried

Set-ExecutionPolicy -Scope MachinePolicy Unrestricted

but I get this error:

Cannot set execution policy. Execution policies at the MachinePolicy or UserPolicy scopes must be set through Group
Policy.

But I don't use policies or anything AD related on my home system.

Get-ExecutionPolicy -list

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine    RemoteSigned

How can I run the Set-Execution if the policy is not set, and skip that if it is not set?


Solution

  • The default scope is LocalMachine if you don't specify one. The message appears because CurrentUser takes priority over LocalMachine. One way to check is:

    # [optional] temporarily suppress execution policy warnings
    $E = $ErrorActionPreference
    $ErrorActionPreference = 'SilentlyContinue'
    
    if ((Get-ExecutionPolicy -Scope LocalMachine) -ne "RemoteSigned") {
      # will always error if CurrentUser scope is set already
      Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
    }
    
    if ((Get-ExecutionPolicy -Scope CurrentUser) -ne "RemoteSigned") {
      Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
    }
    
    $ErrorActionPreference = $E
    

    The warning can't be suppressed normally since it's written directly to the console for some reason.


    Alternatively, you can set only the CurrentUser scope. If you're not using group policy, then there are only three scopes to worry about. The highest one takes priority (setting lower ones will show the warning):

    1. Process: Set for only the current process Set-ExecutionPolicy RemoteSigned -Scope Process
    2. CurrentUser: Set for only the current user: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
    3. LocalMachine: Set for all users: Set-ExecutionPolicy RemoteSigned

    For more information, check out about_Execution_Policies