Why Your Group Policy Startup Script Isn’t Running (Even Though the GPO Looks Correct)

A Group Policy Object can look perfectly correct in Group Policy Management while a startup script never runs on one particular computer. The script may work manually, gpupdate /force may finish without an error, and the same user may receive other settings elsewhere—yet the expected files or registry changes never appear.

That was the situation in my Active Directory lab. A PowerShell startup script deployed wallpapers successfully to most machines but did nothing on one PC. The fault was not PowerShell or file permissions. The computer object was outside the scope of the GPO’s link.

The symptoms

  • The script succeeds when run manually as an administrator.
  • Other PCs receive the same script correctly.
  • gpupdate /force completes without explaining the missing startup script.
  • No expected files, log entries or configuration changes appear after a reboot.
  • The GPO is visible in GPMC but missing from the computer’s applied-policy results.

The key concept: user and computer policy are separate

A single GPO can contain both Computer Configuration and User Configuration, but Windows evaluates those halves in different scopes.

ConfigurationEvaluated forTypical examples
Computer ConfigurationThe computer account and its OU pathStartup scripts, software deployment, security settings, scheduled tasks
User ConfigurationThe signed-in user and their OU pathDrive maps, folder redirection, desktop preferences, logon scripts

A script configured beneath Computer Configuration does not apply merely because the signed-in user is in an OU that receives the GPO. The computer account must fall beneath a site, domain or OU where the GPO is linked, and it must pass inheritance, security and WMI filtering.

The actual fault in my lab

The startup script had been placed inside a GPO that mainly handled folder redirection and mapped drives. Because that policy was designed around user settings, it was linked to user OUs such as Mortals and OlderPCs.

The affected computer lived here:

OU=Computers,
OU=NetherRealm,
DC=order,
DC=realm

Nothing in that computer’s parent path linked the GPO. Windows therefore ignored the Computer Configuration portion entirely. The script was never attempted, so troubleshooting the script itself could not solve the problem.

Start with gpresult

Run an elevated Command Prompt or PowerShell window on the affected PC:

gpresult /scope computer /r

Look under Applied Group Policy Objects. In the failed case, the expected GPO was absent:

Applied Group Policy Objects
-----------------------------
Default Domain Policy

If the policy is missing here, establish why the computer is out of scope before altering PowerShell, execution policy or share permissions.

Generate the detailed HTML report

The summary view only tells part of the story. Create a detailed Resultant Set of Policy report:

mkdir C:\Temp -ErrorAction SilentlyContinue
gpresult /scope computer /h C:\Temp\gpresult-computer.html /f
Start-Process C:\Temp\gpresult-computer.html

The report shows applied and denied policies, security groups, WMI filtering and the settings Windows evaluated. A GPO listed as denied is different from one that was never in the computer’s scope.

Check the GPO in this order

1. Confirm the computer’s real OU

In Active Directory Users and Computers, enable View → Advanced Features, open the computer object and inspect its Object tab. Do not assume the PC is in the default Computers container or the OU suggested by its name.

From a machine with the Active Directory PowerShell module, you can also use:

Get-ADComputer -Identity "RACING-RIG" |
    Select-Object DistinguishedName

2. Confirm where the GPO is linked

In Group Policy Management, find the domain and OU path containing the computer. A GPO shown under Group Policy Objects merely exists; it must also be linked somewhere relevant. Check that the link itself is enabled.

3. Check inheritance

Inspect parent OUs for blocked inheritance and review whether an enforced parent link changes the final result. Avoid using Enforced simply to make a test pass; understand the intended policy design first.

4. Check security filtering and delegation

The computer account must have permission to read and apply the GPO. If Authenticated Users has been removed, confirm that the intended computer group has both Read and Apply Group Policy. Group-membership changes may require a computer restart before the machine obtains a new token.

5. Check the WMI filter

A WMI filter can exclude a machine by operating-system version, hardware or another query. The HTML gpresult report is usually the quickest way to see whether the filter evaluated as false.

6. Confirm Computer Configuration is enabled

On the GPO’s Details tab, check GPO Status. A policy configured as Computer settings disabled cannot deliver a startup script even when its link and filtering are otherwise correct.

Use a dedicated computer GPO

I moved the startup task into a clearly named computer policy and linked it to the computer OU:

order.realm
└── NetherRealm
    └── Computers
        └── GPO link: Computer Configs

Separating computer and user settings is not a technical requirement, and mixed GPOs are supported. I prefer separate policies because their intended scope is obvious, troubleshooting is faster and disabling one side cannot accidentally affect unrelated settings.

Refresh policy and perform a real restart

After correcting the link or filtering, refresh the computer policy:

gpupdate /target:computer /force

A successful refresh does not retroactively rerun a startup script. Restart the computer so it passes through a genuine computer-startup cycle:

Restart-Computer

A restart is a better test than shutting down and powering on when Windows Fast Startup is enabled, because Restart performs a full boot path.

Check Group Policy event logs

If the GPO now applies but the script still fails, move to the client event logs:

Event Viewer
└── Applications and Services Logs
    └── Microsoft
        └── Windows
            └── GroupPolicy
                └── Operational

Filter the log around the most recent boot. Look for processing failures, inaccessible domain controllers, denied policies and extension errors. At this stage the distinction matters: policy scope answers whether Windows tried to deliver the setting; event and script logs explain what happened after it tried.

Network timing and SYSVOL access

A computer startup script may run before the network is fully ready. Confirm that the machine can resolve the domain controller and read the script through SYSVOL:

Test-Path "\\order.realm\SYSVOL\order.realm\scripts"
Resolve-DnsName seido.order.realm
nltest /dsgetdc:order.realm

If the script genuinely requires the network during boot, consider the policy Always wait for the network at computer startup and logon. Enable it deliberately: synchronous processing can increase startup and sign-in time, particularly for laptops away from the domain.

Add logging to the script

A startup script runs outside the interactive user’s desktop, so failures can be invisible. Write a local transcript or simple timestamped log from the beginning:

$LogFolder = "C:\ProgramData\OrderRealm"
$LogFile   = Join-Path $LogFolder "StartupScript.log"

New-Item -Path $LogFolder -ItemType Directory -Force |
    Out-Null

"$(Get-Date -Format o) Starting as $(
    [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
)" | Out-File $LogFile -Append

try {
    # Script work goes here

    "$(Get-Date -Format o) SUCCESS" |
        Out-File $LogFile -Append

    exit 0
}
catch {
    "$(Get-Date -Format o) ERROR: $($_.Exception.Message)" |
        Out-File $LogFile -Append

    exit 10
}

This confirms whether the script actually started, which identity executed it and where it stopped. Without a log, a policy-scope failure and a PowerShell runtime failure can look identical.

A practical diagnostic sequence

  1. Run gpresult /scope computer /r.
  2. If the GPO is absent, check the computer OU, link, inheritance, security filtering, WMI filter and GPO status.
  3. Generate the HTML report to distinguish absent, applied and denied policies.
  4. Correct the scope and run gpupdate /target:computer /force.
  5. Restart the computer to trigger the startup script.
  6. If the GPO applies but the outcome is missing, inspect GroupPolicy/Operational and the script’s own log.
  7. Only then investigate PowerShell logic, permissions and external dependencies.

Related RealmLabs guides

Also check for redundant Group Policy Preferences file copies

A startup script can be configured correctly and still coexist with an old, broken Group Policy Preferences → Files item. I later found exactly this situation: the active wallpaper script was already running from SYSVOL, while a legacy preference item was also trying to copy the same script into C:\ProgramData.

The stale item failed with 0x80070003 and pushed the Group Policy Files processing time to roughly 20 seconds. Removing the redundant preference item reduced that processing step to well under a second.

So when a startup-script problem appears to be fixed but logon, Explorer or unrelated applications still feel slow, generate a Resultant Set of Policy report and inspect the client-side extension timings rather than checking only whether the script itself ran.

gpresult /h C:\Temp\gp.html /f

Final result

Once the computer GPO was linked to the correct OU, gpresult showed it under Applied Group Policy Objects and the startup script ran at the next restart. The script had never been broken; Windows had correctly ignored a Computer Configuration setting that was outside the computer account’s policy scope.

The lasting lesson is to troubleshoot Group Policy from the client outward. First prove that the computer received the GPO. Then prove that the relevant extension processed it. Only after those two checks should you spend time debugging the script itself.