When working with PowerShell execution policies, you might encounter a scenario where the Set-ExecutionPolicy
command appears to execute successfully for the CurrentUser scope, but subsequent checks with Get-ExecutionPolicy -List
show no change. Here's what's happening under the hood:
# Typical failed scenario
PS C:\> Set-ExecutionPolicy Unrestricted -Scope CurrentUser
PS C:\> Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine Unrestricted
Before proceeding with solutions, let's verify potential causes:
# Check Group Policy settings
Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell" -Name "ExecutionPolicy" -ErrorAction SilentlyContinue
Get-ItemProperty -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\PowerShell" -Name "ExecutionPolicy" -ErrorAction SilentlyContinue
# Check registry permissions (CurrentUser scope)
Test-Path -Path "HKCU:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"
$acl = Get-Acl "HKCU:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"
$acl.Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited -AutoSize
1. Registry Direct Modification
When the standard cmdlet fails, modifying the registry directly often works:
# For CurrentUser scope
Set-ItemProperty -Path "HKCU:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" -Name "ExecutionPolicy" -Value "Unrestricted" -Force
# Verification
Get-ItemProperty -Path "HKCU:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" -Name "ExecutionPolicy"
2. PowerShell Process Elevation
Sometimes the issue stems from insufficient permissions during registry write operations:
# Run PowerShell as Administrator even for CurrentUser scope
Start-Process powershell -Verb RunAs -ArgumentList "-NoExit -Command &{Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force}"
3. Profile Script Workaround
As a temporary measure, you can bypass the execution policy for your session:
# Add to your PowerShell profile
if ((Get-ExecutionPolicy -Scope CurrentUser) -ne "Unrestricted") {
Set-ExecutionPolicy Unrestricted -Scope Process -Force
}
For environments where changes don't persist, consider creating a scheduled task that runs at login:
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -Command "Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force"'
$trigger = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -TaskName "SetPSExecutionPolicy" -Action $action -Trigger $trigger -RunLevel Highest -Force
If the issue persists, examine detailed system events:
# Check PowerShell operational logs
Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 50 |
Where-Object {$_.Id -eq 40962 -or $_.Id -eq 40963} |
Format-List TimeCreated,Message
# Check for registry virtualization
reg query HKCU\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell /v ExecutionPolicy
When attempting to set PowerShell's ExecutionPolicy for the CurrentUser scope, you might encounter situations where the setting doesn't persist. This typically manifests as follows:
PS C:\> Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine Unrestricted
Even after running Set-ExecutionPolicy Unrestricted -Scope CurrentUser
, the CurrentUser scope remains Undefined.
Several factors could prevent ExecutionPolicy from applying to CurrentUser:
- Group Policy restrictions (even if not immediately visible)
- Insufficient permissions in the registry
- Corrupted PowerShell profile
- Registry key ownership issues
Try this step-by-step troubleshooting:
# First, check for effective Group Policies
Get-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell" -ErrorAction SilentlyContinue
Get-Item -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\PowerShell" -ErrorAction SilentlyContinue
# Then attempt to force the setting
Start-Process powershell -Verb RunAs -ArgumentList "Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force"
# Verify the registry key directly
Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" -Name ExecutionPolicy
If the standard approach fails, manually modify the registry:
# Backup the current key first
$regPath = "HKCU:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"
if (!(Test-Path $regPath)) {
New-Item -Path $regPath -Force | Out-Null
}
$current = Get-ItemProperty -Path $regPath -Name ExecutionPolicy -ErrorAction SilentlyContinue
if ($current) {
$backupValue = $current.ExecutionPolicy
}
# Set the value directly
Set-ItemProperty -Path $regPath -Name ExecutionPolicy -Value "Unrestricted" -Type String -Force
# Verify the change
Get-ItemProperty -Path $regPath -Name ExecutionPolicy
If you still can't modify CurrentUser scope, consider these alternatives:
# Use Process scope for current session
Set-ExecutionPolicy Unrestricted -Scope Process
# Or bypass the policy for specific scripts
powershell.exe -ExecutionPolicy Bypass -File ".\script.ps1"
After applying any changes, always verify with:
Get-ExecutionPolicy -List
Get-ChildItem -Path "HKCU:\SOFTWARE\Microsoft\PowerShell\1" -Recurse |
Where-Object {$_.Property -contains "ExecutionPolicy"} |
Select-Object PSPath, Property