param( [ValidateSet('Apply','Restore')][string]$Action = 'Apply', [string]$BackupDirectory = 'C:\ProgramData\VDI\usb-experience-20261104' ) $ErrorActionPreference = 'Stop' $user = (Get-CimInstance Win32_ComputerSystem).UserName if (-not $user) { throw 'No signed-in desktop user; refusing to change SYSTEM AutoPlay preferences' } $account = New-Object System.Security.Principal.NTAccount($user) $sid = $account.Translate([System.Security.Principal.SecurityIdentifier]).Value $base = "Registry::HKEY_USERS\$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers" if (-not (Test-Path "Registry::HKEY_USERS\$sid")) { throw 'Desktop user registry is not loaded' } $backup = Join-Path $BackupDirectory 'preferences.clixml' $paths = @( @{Path=$base; Name='DisableAutoplay'; Value=0; Kind='DWord'}, @{Path="$base\UserChosenExecuteHandlers\StorageOnArrival"; Name=''; Value='MSPromptEachTime'; Kind='String'}, @{Path="$base\EventHandlersDefaultSelection\StorageOnArrival"; Name=''; Value='MSPromptEachTime'; Kind='String'} ) if ($Action -eq 'Apply') { if (-not (Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers\Handlers\MSPromptEachTime')) { throw 'Windows Ask every time handler is unavailable' } New-Item -ItemType Directory -Force -Path $BackupDirectory | Out-Null if (-not (Test-Path -LiteralPath $backup)) { $before = foreach ($item in $paths) { $key = Get-Item -LiteralPath $item.Path -ErrorAction SilentlyContinue $exists = $key -and ($key.GetValueNames() -contains $item.Name) [pscustomobject]@{Path=$item.Path; Name=$item.Name; Exists=[bool]$exists; Value=$(if($exists){$key.GetValue($item.Name)}else{$null}); Kind=$(if($exists){$key.GetValueKind($item.Name).ToString()}else{$null})} } [pscustomobject]@{User=$user; Sid=$sid; Values=@($before)} | Export-Clixml -LiteralPath $backup } $saved = Import-Clixml -LiteralPath $backup if ($saved.Sid -ne $sid) { throw 'Backup belongs to a different desktop user' } foreach ($item in $paths) { if (-not (Test-Path -LiteralPath $item.Path)) { New-Item -Path $item.Path -Force | Out-Null } $key = [Microsoft.Win32.Registry]::Users.OpenSubKey($item.Path.Substring('Registry::HKEY_USERS\'.Length), $true) try { $key.SetValue($item.Name, $item.Value, [Microsoft.Win32.RegistryValueKind]$item.Kind) if ($key.GetValue($item.Name) -ne $item.Value) { throw "Readback failed: $($item.Path)" } } finally { $key.Close() } } } else { $saved = Import-Clixml -LiteralPath $backup if ($saved.Sid -ne $sid) { throw 'Backup belongs to a different desktop user' } foreach ($item in $saved.Values) { if ($item.Exists) { if (-not (Test-Path -LiteralPath $item.Path)) { New-Item -Path $item.Path -Force | Out-Null } $key = [Microsoft.Win32.Registry]::Users.OpenSubKey($item.Path.Substring('Registry::HKEY_USERS\'.Length), $true) try { $key.SetValue($item.Name, $item.Value, [Microsoft.Win32.RegistryValueKind]$item.Kind) } finally { $key.Close() } } elseif (Test-Path -LiteralPath $item.Path) { $key = [Microsoft.Win32.Registry]::Users.OpenSubKey($item.Path.Substring('Registry::HKEY_USERS\'.Length), $true) try { $key.DeleteValue($item.Name, $false) } finally { $key.Close() } } } } [pscustomobject]@{Action=$Action; User=$user; Sid=$sid; Backup=$backup; StorageOnArrival=(Get-Item -LiteralPath "$base\UserChosenExecuteHandlers\StorageOnArrival").GetValue(''); DisableAutoplay=(Get-Item -LiteralPath $base).GetValue('DisableAutoplay')} | ConvertTo-Json -Compress