Modify user registry for all cached users and future new users
2 min readJan 10, 2023
The following PowerShell provides the boilerplate to modify the user hive registry for all accounts that have logged into a PC before as well as applying the same changes to the ‘DEFAULT’ user registry so that any new users that login will also gain those changes.
The script also accounts for user hives that are already currently loaded versus those that aren’t.
# Regex pattern for SIDs
$PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$'
# Get Username, SID, and location of ntuser.dat for all users
$ProfileList = @(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID -and $_.ProfileImagePath -notlike "*defaultuser*"} |
Select-Object @{name="SID";expression={$_.PSChildName}},
@{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}},
@{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}})
#Manually add the DEFAULT profile to the list, too
$ProfileList += ([PSCustomObject]@{SID=".DEFAULT";UserHive="$($env:SystemDrive)\Users\Default\NTUSER.DAT";Username="Default"})
# Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded)
$LoadedHives = @(Get-ChildItem Registry::HKEY_USERS | Where-Object {$_.PSChildname -match $PatternSID -or $_.PSChildName -eq ".DEFAULT"} | Select-Object @{name="SID";expression={$_.PSChildName}})
# Get all users that are not currently loaded
$UnloadedHives = @(Compare-Object $ProfileList.SID $LoadedHives.SID | Select-Object @{name="SID";expression={$_.InputObject}}, UserHive, Username)
# Loop through each profile on the machine
foreach ($item in $ProfileList) {
# Load User ntuser.dat if it's not already loaded
if ($item.SID -in $UnloadedHives.SID) {
Write-Output "$($Item.Username)'s hive isn't loaded. Loading it."
reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
}
$Path = "registry::HKEY_USERS\$($Item.SID)\Software\"
# Do registry related work here.
# Unload ntuser.dat
if ($item.SID -in $UnloadedHives.SID) {
# Garbage collection and closing of ntuser.dat #
Write-Output "$($Item.Username) hive wasn't loaded at the beginning of this script. Unloading it."
[gc]::Collect()
reg unload HKU\$($Item.SID) | Out-Null
}
}