Powershell/Private/RegistryKey/Set-UserRegistryLoadState.ps1
|
function Set-UserRegistryLoadState { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateSet("Unload", "Load")] [System.String]$op, [Parameter(Mandatory = $true)] [ValidateSet("classes", "root")] [System.String]$hive, [Parameter(Mandatory = $true)] [ValidateScript( { Test-Path $_ })] [System.String]$ProfilePath, # User Security Identifier [Parameter(Mandatory = $true)] [ValidatePattern("^S-\d-\d+-(\d+-){1,14}\d+$")] [System.String]$UserSid, [Parameter()] [System.Int32]$counter = 0 ) begin { switch ($hive) { "classes" { $key = "HKU\$($UserSid)_Classes_admu" } "root" { $key = "HKU\$($UserSid)_admu" } } If ($counter -ge 0) { $counter += 1 } # Allow additional retries so GC / PSDrive teardown can release self-held handles if ($counter -gt 5) { throw "Registry $op $key failed" } } process { $username = Convert-SecurityIdentifier $UserSid switch ($op) { "Load" { Clear-RegistryProviderHandle $results = Set-RegistryExe -op Load -hive $hive -UserSid $UserSid -ProfilePath $ProfilePath if ($results) { Write-ToLog "Load Successful: $results" -Level Verbose -Step "Set-UserRegistryLoadState" } else { $processList = Get-ProcessByOwner -username $username if ($processList) { Show-ProcessListResult -ProcessList $processList -domainUsername $username } else { Write-ToLog "No processes found for $username; retrying load after releasing registry provider handles (attempt $counter)" -Level Verbose -Step "Set-UserRegistryLoadState" } Start-Sleep -Seconds 2 Set-UserRegistryLoadState -op Load -ProfilePath $ProfilePath -UserSid $UserSid -counter $counter -hive $hive } } "Unload" { # Release PSDrive / provider handles held by this process before REG UNLOAD. # User-owned processes are rarely the locker at this stage; ADMU itself is. Clear-RegistryProviderHandle $results = Set-RegistryExe -op Unload -hive $hive -UserSid $UserSid -ProfilePath $ProfilePath if ($results) { Write-ToLog "Unload Successful: $results" -Level Verbose -Step "Set-UserRegistryLoadState" } else { $processList = Get-ProcessByOwner -username $username if ($processList) { Show-ProcessListResult -ProcessList $processList -domainUsername $username } else { Write-ToLog "No processes found for $username. REG UNLOAD is likely blocked by open handles in the ADMU process (PID $PID). Retrying after GC/PSDrive release (attempt $counter)." -Level Verbose -Step "Set-UserRegistryLoadState" } Start-Sleep -Seconds 2 Set-UserRegistryLoadState -op "Unload" -ProfilePath $ProfilePath -UserSid $UserSid -counter $counter -hive $hive } } } } end { } } |