61 lines
3.7 KiB
PowerShell
61 lines
3.7 KiB
PowerShell
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
|