param( [object]$Config, [string]$LogFile ) $ErrorActionPreference = "Continue" function Write-Log { param([string]$Message, [string]$Level = "INFO") $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message" Add-Content -Path $LogFile -Value $line -Encoding UTF8 } # ----------------------------------------------------------------------- # Helper - apply a registry setting to both Default hive and current HKCU # ----------------------------------------------------------------------- function Grant-HiveWriteAccess { param([string]$HivePath) # full path e.g. "Registry::HKU\DefaultProfile\Software\..." # Grants Administrators FullControl on a loaded hive key with restricted ACL. try { $acl = Get-Acl -Path $HivePath -ErrorAction Stop $rule = New-Object System.Security.AccessControl.RegistryAccessRule( "BUILTIN\Administrators", [System.Security.AccessControl.RegistryRights]::FullControl, [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit", [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow ) $acl.SetAccessRule($rule) Set-Acl -Path $HivePath -AclObject $acl -ErrorAction Stop } catch { Write-Log " Grant-HiveWriteAccess failed for $HivePath - $_" -Level WARN } } function Set-ProfileReg { param( [string]$SubKey, # relative to HKCU (e.g. "Software\Microsoft\...") [string]$Name, $Value, [string]$Type = "DWord" ) # Apply to loaded Default hive $defPath = "Registry::HKU\DefaultProfile\$SubKey" try { if (-not (Test-Path $defPath)) { New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null } Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop } catch { # Retry after granting write access to parent key try { $parentPath = $defPath -replace '\\[^\\]+$', '' if (Test-Path $parentPath) { Grant-HiveWriteAccess -HivePath $parentPath } if (-not (Test-Path $defPath)) { New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null } Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop } catch { Write-Log " DEFAULT HIVE failed $SubKey\$Name - $_" -Level ERROR } } # Apply to current user as well $hkcuPath = "HKCU:\$SubKey" try { if (-not (Test-Path $hkcuPath)) { New-Item -Path $hkcuPath -Force -ErrorAction Stop | Out-Null } Set-ItemProperty -Path $hkcuPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop Write-Log " SET $SubKey\$Name = $Value" -Level OK } catch { Write-Log " HKCU failed $SubKey\$Name - $_" -Level ERROR } } function Remove-ProfileReg { param([string]$SubKey, [string]$Name) $defPath = "Registry::HKU\DefaultProfile\$SubKey" try { if (Test-Path $defPath) { Remove-ItemProperty -Path $defPath -Name $Name -Force -ErrorAction SilentlyContinue } } catch { } $hkcuPath = "HKCU:\$SubKey" try { if (Test-Path $hkcuPath) { Remove-ItemProperty -Path $hkcuPath -Name $Name -Force -ErrorAction SilentlyContinue Write-Log " REMOVED $SubKey\$Name" -Level OK } } catch { Write-Log " FAILED removing $SubKey\$Name - $_" -Level ERROR } } # ----------------------------------------------------------------------- # Load Default profile hive # ----------------------------------------------------------------------- $hivePath = "C:\Users\Default\NTUSER.DAT" $hiveKey = "DefaultProfile" Write-Log "Loading Default hive: $hivePath" -Level INFO # Unload first in case previous run left it mounted & reg unload "HKU\$hiveKey" 2>&1 | Out-Null $loadResult = & reg load "HKU\$hiveKey" $hivePath 2>&1 if ($LASTEXITCODE -ne 0) { Write-Log "Failed to load Default hive: $loadResult" -Level ERROR exit 1 } Write-Log "Default hive loaded" -Level OK try { # ----------------------------------------------------------------------- # Taskbar settings (Win10 + Win11) # ----------------------------------------------------------------------- Write-Log "Applying taskbar settings" -Level STEP $tbPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" # Win11: align taskbar to left (0 = left, 1 = center) Set-ProfileReg -SubKey $tbPath -Name "TaskbarAl" -Value 0 # Hide Search box / button - Win10/11 (0 = hidden, 1 = icon, 2 = full box) # Note: Win11 uses Search subkey, Win10 uses Explorer\Advanced - set both Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Search" ` -Name "SearchboxTaskbarMode" -Value 0 Set-ProfileReg -SubKey $tbPath -Name "SearchboxTaskbarMode" -Value 0 # Hide Task View button Set-ProfileReg -SubKey $tbPath -Name "ShowTaskViewButton" -Value 0 # Hide Widgets button Set-ProfileReg -SubKey $tbPath -Name "TaskbarDa" -Value 0 # Hide Chat / Teams button Set-ProfileReg -SubKey $tbPath -Name "TaskbarMn" -Value 0 # Hide Copilot button Set-ProfileReg -SubKey $tbPath -Name "ShowCopilotButton" -Value 0 # Show file extensions in Explorer Set-ProfileReg -SubKey $tbPath -Name "HideFileExt" -Value 0 # Open Explorer to This PC instead of Quick Access Set-ProfileReg -SubKey $tbPath -Name "LaunchTo" -Value 1 # ----------------------------------------------------------------------- # System tray - show all icons # ----------------------------------------------------------------------- # EnableAutoTray = 0 works on Win10; Win11 ignores it but set anyway Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" ` -Name "EnableAutoTray" -Value 0 # Win11 workaround: clear cached tray icon streams so all icons appear on next login # Windows rebuilds the streams with all icons visible when no cache exists $trayNotifyKey = "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" if (Test-Path $trayNotifyKey) { Remove-ItemProperty -Path $trayNotifyKey -Name "IconStreams" -Force -ErrorAction SilentlyContinue Remove-ItemProperty -Path $trayNotifyKey -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue Write-Log " Cleared TrayNotify icon streams (Win11 systray workaround)" -Level OK } # Also clear in Default hive so new users start with clean state $defTrayKey = "Registry::HKU\DefaultProfile\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" if (Test-Path $defTrayKey) { Remove-ItemProperty -Path $defTrayKey -Name "IconStreams" -Force -ErrorAction SilentlyContinue Remove-ItemProperty -Path $defTrayKey -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue Write-Log " Cleared TrayNotify icon streams in Default hive" -Level OK } # ----------------------------------------------------------------------- # Desktop icons - show This PC # ----------------------------------------------------------------------- # CLSID {20D04FE0-3AEA-1069-A2D8-08002B30309D} = This PC / Computer Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel" ` -Name "{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -Value 0 # ----------------------------------------------------------------------- # Start menu settings # ----------------------------------------------------------------------- Write-Log "Applying Start menu settings" -Level STEP # Disable Bing search suggestions in Start menu Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\Explorer" ` -Name "DisableSearchBoxSuggestions" -Value 1 # Win11: empty Start menu pins Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Start" ` -Name "ConfigureStartPins" ` -Value '{"pinnedList":[]}' ` -Type "String" # Hide "Recently added" apps in Start menu Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "Start_TrackProgs" -Value 0 # Hide recently opened files/docs from Start menu Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "Start_TrackDocs" -Value 0 # ----------------------------------------------------------------------- # Copilot - disable # ----------------------------------------------------------------------- Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\WindowsCopilot" ` -Name "TurnOffWindowsCopilot" -Value 1 # ----------------------------------------------------------------------- # GameDVR - disable # ----------------------------------------------------------------------- Set-ProfileReg -SubKey "System\GameConfigStore" ` -Name "GameDVR_Enabled" -Value 0 Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\GameDVR" ` -Name "AppCaptureEnabled" -Value 0 # ----------------------------------------------------------------------- # Num Lock on startup # ----------------------------------------------------------------------- Set-ProfileReg -SubKey "Control Panel\Keyboard" ` -Name "InitialKeyboardIndicators" -Value 2 -Type "String" # ----------------------------------------------------------------------- # Accent color on title bars # ----------------------------------------------------------------------- Set-ProfileReg -SubKey "Software\Microsoft\Windows\DWM" ` -Name "ColorPrevalence" -Value 1 # ----------------------------------------------------------------------- # OneDrive - remove RunOnce key from Default profile # ----------------------------------------------------------------------- Write-Log "Removing OneDrive from Default profile RunOnce" -Level INFO Remove-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Run" ` -Name "OneDriveSetup" Remove-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\RunOnce" ` -Name "Delete Cached Standalone Update Binary" # Remove OneDrive from Explorer namespace (left panel) $oneDriveClsid = "{018D5C66-4533-4307-9B53-224DE2ED1FE6}" $nsPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\$oneDriveClsid" $defNsPath = "Registry::HKU\DefaultProfile\$nsPath" if (Test-Path $defNsPath) { Remove-Item -Path $defNsPath -Recurse -Force -ErrorAction SilentlyContinue Write-Log " Removed OneDrive from Explorer namespace (Default)" -Level OK } $hkcuNsPath = "HKCU:\$nsPath" if (Test-Path $hkcuNsPath) { Remove-Item -Path $hkcuNsPath -Recurse -Force -ErrorAction SilentlyContinue Write-Log " Removed OneDrive from Explorer namespace (HKCU)" -Level OK } # ----------------------------------------------------------------------- # Empty taskbar pinned apps (Win10/11) # ----------------------------------------------------------------------- Write-Log "Clearing taskbar pinned apps layout" -Level INFO $taskbarLayoutDir = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell" if (-not (Test-Path $taskbarLayoutDir)) { New-Item -ItemType Directory -Path $taskbarLayoutDir -Force | Out-Null } $taskbarLayoutXml = @" "@ $taskbarLayoutXml | Set-Content -Path "$taskbarLayoutDir\LayoutModification.xml" -Encoding UTF8 -Force Write-Log " Taskbar LayoutModification.xml written" -Level OK } finally { # ----------------------------------------------------------------------- # Unload Default hive - always, even on error # ----------------------------------------------------------------------- Write-Log "Unloading Default hive" -Level INFO [GC]::Collect() [GC]::WaitForPendingFinalizers() Start-Sleep -Milliseconds 500 $unloadResult = & reg unload "HKU\$hiveKey" 2>&1 if ($LASTEXITCODE -eq 0) { Write-Log "Default hive unloaded" -Level OK } else { Write-Log "Failed to unload Default hive: $unloadResult" -Level ERROR } } # ----------------------------------------------------------------------- # Restart Explorer to apply taskbar/tray changes to current session # ----------------------------------------------------------------------- Write-Log "Restarting Explorer to apply taskbar changes" -Level INFO try { Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 Start-Process explorer Write-Log "Explorer restarted" -Level OK } catch { Write-Log "Explorer restart failed (non-fatal): $_" -Level WARN } Write-Log "Step 4 complete" -Level OK