Run Windows PowerShell scripts first at user logon, logoff
Verified with Windows 11 25H2 — updated on July 30, 2026
Supported on: At least Windows Server 2008 R2 or Windows 7
Path in the GPO console
Computer Configuration\Administrative Templates\System\Scripts User Configuration\Administrative Templates\System\Scripts Description
This policy setting determines whether Windows PowerShell scripts are run before non-Windows PowerShell scripts during user logon and logoff. By default, Windows PowerShell scripts run after non-Windows PowerShell scripts. If you enable this policy setting, within each applicable Group Policy Object (GPO), PowerShell scripts are run before non-PowerShell scripts during user logon and logoff. For example, assume the following scenario: There are three GPOs (GPO A, GPO B, and GPO C). This policy setting is enabled in GPO A. GPO B and GPO C include the following user logon scripts: GPO B: B.cmd, B.ps1 GPO C: C.cmd, C.ps1 Assume also that there are two users, Qin Hong and Tamara Johnston. For Qin, GPOs A, B, and C are applied. Therefore, the scripts for GPOs B and C run in the following order for Qin: Within GPO B: B.ps1, B.cmd Within GPO C: C.ps1, C.cmd For Tamara, GPOs B and C are applied, but not GPO A. Therefore, the scripts for GPOs B and C run in the following order for Tamara: Within GPO B: B.cmd, B.ps1 Within GPO C: C.cmd, C.ps1 Note: This policy setting determines the order in which user logon and logoff scripts are run within all applicable GPOs. You can override this policy setting for specific script types within a specific GPO by configuring the following policy settings for the GPO: User Configuration\Policies\Windows Settings\Scripts (Logon/Logoff)\Logon User Configuration\Policies\Windows Settings\Scripts (Logon/Logoff)\Logoff This policy setting appears in the Computer Configuration and User Configuration folders. The policy setting set in Computer Configuration takes precedence over the setting set in User Configuration.
Registry
Software\Microsoft\Windows\CurrentVersion\Policies\System Software\Microsoft\Windows\CurrentVersion\Policies\System Value name: RunUserPSScriptsFirst
Enabled: RunUserPSScriptsFirst = 1
Disabled: RunUserPSScriptsFirst = 0
MDM / Intune (CSP)
./Device/Vendor/MSFT/Policy/Config/ADMX_Scripts/Run_User_PS_Scripts_First ./User/Vendor/MSFT/Policy/Config/ADMX_Scripts/Run_User_PS_Scripts_First Microsoft Learn documentation Mapping data: Microsoft Learn (CC BY 4.0)
Export Builder
BETAConfigure the state, scope and options, then generate .reg, PowerShell, Intune and SCCM outputs — or add the setting to a multi-setting collection.
These exports write the registry — this is not a managed GPO. ⓘ
Applying both scopes creates an ambiguous configuration (computer takes precedence over user). Only do this intentionally.
.reg file
Windows Registry Editor Version 5.00
; Exported from gporais.com
; Policy: Run Windows PowerShell scripts first at user logon, logoff
; State: Enabled
; Scope: Computer (HKLM)
; Supported on: At least Windows Server 2008 R2 or Windows 7
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System]
"RunUserPSScriptsFirst"=dword:00000001 More formats (PowerShell, Intune, SCCM)
PowerShell
# Exported from gporais.com
# Policy: Run Windows PowerShell scripts first at user logon, logoff
# State: Enabled
# Scope: Computer (HKLM)
# Supported on: At least Windows Server 2008 R2 or Windows 7
$path = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System'
New-Item -Path $path -Force | Out-Null
Set-ItemProperty -Path $path -Name 'RunUserPSScriptsFirst' -Value 1 -Type DWord Intune XML
OMA-URI: ./Device/Vendor/MSFT/Policy/Config/ADMX_Scripts/Run_User_PS_Scripts_First
Data type: String
Value:
<enabled/> Intune Remediation
# === Detection script ===
# Exported from gporais.com
# Policy: Run Windows PowerShell scripts first at user logon, logoff
# State: Enabled
# Scope: Computer (HKLM)
# Supported on: At least Windows Server 2008 R2 or Windows 7
function Test-RegistryValue {
param(
[Parameter(Mandatory = $true)][string]$Path,
[Parameter(Mandatory = $true)][string]$Name,
[object]$Expected,
[ValidateSet('String', 'DWord', 'MultiString')][string]$Kind = 'String',
[switch]$Absent
)
try {
$item = Get-ItemProperty -LiteralPath $Path -Name $Name -ErrorAction Stop
} catch {
return $Absent.IsPresent
}
if ($Absent.IsPresent) { return $false }
$actual = $item.$Name
if ($Kind -eq 'DWord') { return ([int64]$actual) -eq ([int64]$Expected) }
if ($Kind -eq 'MultiString') {
$actualValues = @($actual)
$expectedValues = @($Expected)
if ($actualValues.Count -ne $expectedValues.Count) { return $false }
for ($i = 0; $i -lt $expectedValues.Count; $i++) {
if ([string]$actualValues[$i] -ne [string]$expectedValues[$i]) { return $false }
}
return $true
}
return [string]$actual -eq [string]$Expected
}
$checks = @(
(Test-RegistryValue -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System' -Name 'RunUserPSScriptsFirst' -Expected 1 -Kind DWord)
)
if ($checks -notcontains $false) {
Write-Output 'Compliant'
exit 0
}
Write-Output 'Non-compliant'
exit 1
# === Remediation script ===
# Exported from gporais.com
# Policy: Run Windows PowerShell scripts first at user logon, logoff
# State: Enabled
# Scope: Computer (HKLM)
# Supported on: At least Windows Server 2008 R2 or Windows 7
$path = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System'
New-Item -Path $path -Force | Out-Null
Set-ItemProperty -Path $path -Name 'RunUserPSScriptsFirst' -Value 1 -Type DWord SCCM scripts
# Exported from gporais.com
# Policy: Run Windows PowerShell scripts first at user logon, logoff
# State: Enabled
# Scope: Computer (HKLM)
# Supported on: At least Windows Server 2008 R2 or Windows 7
# SCCM Configuration Item guidance:
# Create a Configuration Item of type "Setting: Script".
# Discovery script: use the Detection script below.
# Remediation script: use the Remediation script below.
# Compliance rule: the Discovery script output equals 'Compliant'.
# === Detection script ===
# Exported from gporais.com
# Policy: Run Windows PowerShell scripts first at user logon, logoff
# State: Enabled
# Scope: Computer (HKLM)
# Supported on: At least Windows Server 2008 R2 or Windows 7
function Test-RegistryValue {
param(
[Parameter(Mandatory = $true)][string]$Path,
[Parameter(Mandatory = $true)][string]$Name,
[object]$Expected,
[ValidateSet('String', 'DWord', 'MultiString')][string]$Kind = 'String',
[switch]$Absent
)
try {
$item = Get-ItemProperty -LiteralPath $Path -Name $Name -ErrorAction Stop
} catch {
return $Absent.IsPresent
}
if ($Absent.IsPresent) { return $false }
$actual = $item.$Name
if ($Kind -eq 'DWord') { return ([int64]$actual) -eq ([int64]$Expected) }
if ($Kind -eq 'MultiString') {
$actualValues = @($actual)
$expectedValues = @($Expected)
if ($actualValues.Count -ne $expectedValues.Count) { return $false }
for ($i = 0; $i -lt $expectedValues.Count; $i++) {
if ([string]$actualValues[$i] -ne [string]$expectedValues[$i]) { return $false }
}
return $true
}
return [string]$actual -eq [string]$Expected
}
$checks = @(
(Test-RegistryValue -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System' -Name 'RunUserPSScriptsFirst' -Expected 1 -Kind DWord)
)
if ($checks -notcontains $false) {
Write-Output 'Compliant'
exit 0
}
Write-Output 'Non-compliant'
exit 1
# === Remediation script ===
# Exported from gporais.com
# Policy: Run Windows PowerShell scripts first at user logon, logoff
# State: Enabled
# Scope: Computer (HKLM)
# Supported on: At least Windows Server 2008 R2 or Windows 7
$path = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System'
New-Item -Path $path -Force | Out-Null
Set-ItemProperty -Path $path -Name 'RunUserPSScriptsFirst' -Value 1 -Type DWord Building a multi-setting collection? Add this setting and generate combined .reg / PowerShell / GPO scripts.