25H2 Unattend scripts - RunOnce keys being nuked from ntuser.dat?

Discussion in 'Windows 11' started by aroenai, Nov 24, 2025.

  1. aroenai

    aroenai MDL Novice

    Sep 21, 2009
    47
    1
    0
    #1 aroenai, Nov 24, 2025
    Last edited: Nov 25, 2025
    I'm at my wit's end for trying to figure out what's happening. I have a powershell script that runs in the Specialize pass for autounattend.xml to apply various registry keys to set profile defaults for users by modifying C:\users\default\ntuser.dat on my bootable Windows 11 25H2 media (updated to the November CU with W10UI).

    I've verified all my other modifications are getting applied when OOBE completes, except for a few very strange instances for specific registry keys only. It does not matter what order I put them in, or if I do additional garbage collection.

    "HKU\TempHive\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
    Cannot create a DWORD entry for "TaskbarDa", despite working in a loop for 6 other values.

    "HKU\TempHive\Control Panel\International\User Profile"
    Cannot create a DWORD entry for "HttpAcceptLanguageOptOut"

    "HKU\TempHive\Software\Microsoft\Windows\CurrentVersion\RunOnce"
    I can't seem to create any key no matter the name or contents, after OOBE I get a C:\Users\DefaultUser0 folder created with modification dates on OneDrive related folders and the only entry in ntuser.dat for RunOnce is for OneDrive's background process. If I comment out the section for adding a RunOnce key, no DefaultUser0 folder gets created.

    Hive mounting function for reference:
    Code:
    $regName = "TempHive"
    $regKey = "HKU:\$regName"
    $regDat = Join-Path -Path $env:SystemDrive -ChildPath "Users\Default\NTUSER.DAT"
    
    Function Set-RegistryInfo {
        # Windows Explorer preferences
        $ExplorerAdv = "${regKey}\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
      
        $ExplorerKeys = @(
            # Always show file extensions
            'HideFileExt',
            # Align Taskbar left
            'TaskbarAl',
            # Sync Provider notices in Explorer
            'ShowSyncProviderNotifications',
            # Recommended ads in Start Menu
            'Start_IrisRecommendations',
            # Improve Start and search results
            'Start_TrackProgs',
            # Disable Copilot on Taskbar
            'TaskbarCompanion',
            # Disable Widgets - doesn't add
            'TaskbarDa'
        )
      
        foreach ( $Name in $ExplorerKeys ) {
            # Process the Windows Explorer preference keys
            New-ItemProperty -Path $ExplorerAdv -Name $Name -PropertyType "DWord" -Value 0 -Force
        }
    
        # More functional registry changes
    
        # Opt out of allowing access to language list from websites, not present??
        New-ItemProperty -Path "${regKey}\Control Panel\International\User Profile" -Name "HttpAcceptLanguageOptOut" -PropertyType "DWord" -Value 1 -Force
    
        # More functional registry changes
    
        Get-ChildItem -Filter "profile.ps1" | % {
            Copy-Item -Path $_.FullName -Destination (New-Item -Path "$env:ProgramData\Scripts" -ItemType Directory -Force).FullName
            # Desperate attempt to get it working in case the key didn't actually exist despite what I saw post OOBE...
            $RunOnceKey = ( New-Item -Path "${regKey}\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Force ).PSPath
            # No difference with "-ExecutionPolicy Bypass -File" either
            New-ItemProperty -Path $RunOnceKey -Name "NewProfile" -PropertyType "String" -Value "powershell.exe -WindowStyle Hidden -NoProfile -Command `"Get-Content -LiteralPath '${env:ProgramData}\Scripts\profile.ps1' -Raw | Invoke-Expression;`"" -Force
        }
    }
    
    $regProcess = Start-Process -FilePath "$env:WinDir\System32\reg.exe" -ArgumentList "load HKU\$($regName) $($regDat)" -WindowStyle Hidden -PassThru -Wait
    if ( $regProcess.ExitCode -eq 0 )
    {
        New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS -Scope Global -ErrorAction SilentlyContinue
     
        Set-RegistryInfo
     
        Remove-PSDrive -Name HKU -ErrorAction SilentlyContinue
     
        # Cleanup stale references so the hive can cleanly unmount
        [GC]::Collect()
        [GC]::WaitForPendingFinalizers()
        Start-Sleep -Milliseconds 100
     
        Start-Process -FilePath "$env:WinDir\System32\reg.exe" -ArgumentList "unload HKU\$($regName)" -WindowStyle Hidden -Wait
    }
     
  2. aroenai

    aroenai MDL Novice

    Sep 21, 2009
    47
    1
    0
  3. abbodi1406

    abbodi1406 MDL KB0000001

    Feb 19, 2011
    18,567
    99,728
    340
    I don't know
    but i guess it's better to keep it disabled
     
  4. aroenai

    aroenai MDL Novice

    Sep 21, 2009
    47
    1
    0
    #5 aroenai, Nov 24, 2025
    Last edited: Nov 24, 2025
    (OP)
    Well, it's apparently not UCPD. After disabling it from Specialize, still can't write a RunOnce key to the default profile.

    Code:
    Set-Service -Name UCPD -StartupType Disabled
    Disable-ScheduledTask -TaskName "\Microsoft\Windows\AppxDeploymentClient\UCPD velocity"
    Stop-Service -Name UCPD
    Did confirm that both the service and task are disabled post deployment. Should also be noted that my script does appear in the correct path under C:\ProgramData\Scripts\profile.ps1 as well, just no key in the registry.
     
  5. aroenai

    aroenai MDL Novice

    Sep 21, 2009
    47
    1
    0
    It's still not working with UCPD disabled, any other ideas?
     
  6. sonic9

    sonic9 MDL Member

    Aug 4, 2009
    219
    86
    10
    it's not 25H2 issue, it's already present in 24H2.
    you can't stop the UCPD service as it's a driver , once set as disabled, reboot is required.
    another way, without reboot, as written in topic cited above, is copy reg.exe as reg1.exe then run your command.
     
  7. aroenai

    aroenai MDL Novice

    Sep 21, 2009
    47
    1
    0
    No luck, still can't make changes to RunOnce, or HttpAcceptLanguageOptOut, or HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}\SensorPermissionState for that matter.
     
  8. KleineZiege

    KleineZiege MDL Guru

    Dec 11, 2018
    2,387
    3,107
    90
    But that works, you're setting it up wrong.
    You have to arrange it via first logon in the OEM folder.
    It's a bit tricky, and you have to use the script from Bau/TI M.
    I customized the folder years ago, but then everyone from the warez scene stole the script, Scruba, Pentium, so I don't put anything online anymore.

    Give me your reg keys, I'll adjust it.
    And I'll send you the OEM for the source folder for the image.
     
  9. aroenai

    aroenai MDL Novice

    Sep 21, 2009
    47
    1
    0
    I said in the first post that it's a Powershell script during the Specialize pass, other registry values in the same script are successful. However, it's all automated and I reseal after Audit mode installs apps with a second unattend.xml script (Audit mode modifies the content of unattend.xml to set the pc name, that file's First Logon commands connect to wifi, enable Microsoft Update, start a MU scan, and set the local admin account password to require a change) and Sysprep. If I comment out the Sysprep process and let Audit Mode finish loading the desktop, I can see that none of the problem registry values were set.

    I only have one file that gets copied to sources\$OEM$\$$\Setup\Scripts, and it's a helper Powershell script to find the USB drive with my Unattend folder for the other scripts. Are you saying that C:\Users\Default\ntuser.dat gets keys wiped by some OOBE process and you have to set it in First Logon?
     
  10. sonic9

    sonic9 MDL Member

    Aug 4, 2009
    219
    86
    10
    #12 sonic9, Dec 14, 2025
    Last edited: Dec 15, 2025
    There are differents points :

    1/ TaskbarDa and some other reg keys (those in screenshot in previous post) are protected by UCPD service/driver.
    Bypass method 1 : require reboot to be effective because it's a driver : disable UCPD service/driver.
    Bypass method 2 : doesn't require reboot : copy reg.exe as reg1.exe to apply regtweaks.

    2/ I just tried again : ( Users \ Default \ NTUSER.DAT ) "Control Panel\International\User Profile"
    is indeed cleared/re-created during OOBE/post-sysprep
    Perhaps some others ( need to be dig out )
    EDIT : BTW, modifications ( Users \ Default \ NTUSER.DAT ) done during FirstLogonCommands are kept.
    But, the first user is created before the FirstLogonCommands, so, first user will not have the customizations.

    3/ For "RunOnce" ( Users \ Default \ NTUSER.DAT ) , no problem here.