#
.SYNOPSIS
Applies registry settings to the Default User profile and the current logged-in user.
.DESCRIPTION
Loads C:\Users\Default\NTUSER.DAT as a temporary hive (HKU\DefaultProfile), applies
all settings, then unloads it. Every new user account created on this machine inherits
these settings on first logon. The same settings are applied directly to the current
user's HKCU. Does NOT block OneDrive re-launch - the Explorer namespace CLSID and RunOnce entries have been removed.
.ITEMS
taskbar-zarovnat-vlevo-taskbaral-0: TaskbarAl = 0 in Explorer\Advanced. Windows 11 default is center-aligned (TaskbarAl = 1). Left alignment matches Windows 10 muscle memory and is strongly preferred by business users transitioning from Win10.
taskbar-skryt-search-copilot-task-view-w: Hides Search box (SearchboxTaskbarMode=0), Copilot button (ShowCopilotButton=0), Task View (ShowTaskViewButton=0), Widgets (TaskbarDa=0), Chat/Teams (TaskbarMn=0). Reduces taskbar clutter to just pinned apps and running processes.
taskbar-zobrazit-vsechny-ikonky-v-tray-s: Registers scheduled task that sets EnableAutoTray=0 on logon (repeat every 1 min). Windows 11 periodically re-hides tray icons - this task forces all icons visible so users can see VPN status, antivirus, backup, etc.
taskbar-vyprazdnit-pinlist-taskbarlayout: Deploys TaskbarLayoutModification.xml. ProfileType=default: empty pins (clean slate). ProfileType=admin: Explorer+PowerShell+Edge. ProfileType=user: Explorer+Edge. Lock is removed by UnlockStartLayout task 5 min after first boot so users can customize.
explorer-zobrazovat-pripony-souboru-hide: HideFileExt = 0 in Explorer\Advanced. Shows file extensions (.docx, .exe, .pdf, .ps1) in File Explorer. Essential for recognizing file types, avoiding phishing (fake .pdf.exe), and general IT work.
explorer-otevrit-na-this-pc-launchto-1: LaunchTo = 1. File Explorer opens to "This PC" (drives view) instead of Quick Access. More useful on fresh machines where Quick Access history is empty and irrelevant.
start-menu-vyprazdnit-piny-win11: ConfigureStartPins = {"pinnedList":[]} applied via registry. Removes all default Start menu tiles (Edge, Teams, Store, Office, Solitaire, etc.) from the Windows 11 Start grid. User starts with an empty, clean Start menu.
start-menu-zakaz-bing-vyhledavani: DisableSearchBoxSuggestions = 1 in Software\Policies\Microsoft\Windows. Disables web search, Bing suggestions, and online results in Start menu search. Search returns only local apps, files, and settings.
copilot-zakaz-turnoffwindowscopilot-1: TurnOffWindowsCopilot = 1 in SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot. Disables the Windows Copilot sidebar entirely. Not suitable for most client environments (data privacy, AI usage policies).
numlock-zapnout-pri-startu-initialkeyboa: InitialKeyboardIndicators = 2 in Default profile. Ensures NumLock is enabled when Windows starts. Standard expectation for users working with numeric data - prevents confusion on data entry.
accent-barva-na-titulnich-listech-colorp: ColorPrevalence = 1 in Personalize key. Shows the X9.cz accent color (#223B47) on window title bars and borders. Gives all windows a consistent branded appearance.
onedrive-runonce-klic-je-tady-smazat: REMOVED. The RunOnce key deletion and Explorer namespace CLSID removal were deleted - those registry tweaks prevented a freshly installed OneDrive (e.g. for M365) from launching. OneDrive AppX uninstall in step 01 is intentional; blocking re-launch is not.
explorer-showrecent-0-showfrequent-0: ShowRecent=0 and ShowFrequent=0 in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer. Hides Recent files and Frequent folders from Quick Access. Privacy improvement and cleaner File Explorer on fresh deployments.
explorer-fullpath-1-cabinetstate: FullPath=1 in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState. Displays the full directory path (e.g. C:\Users\jan\Documents\Projekty) in the File Explorer title bar instead of just the folder name.
#>
param(
[object]$Config,
[string]$LogFile,
[ValidateSet("default","admin","user")]
[string]$ProfileType = "default"
)
$ErrorActionPreference = "Continue"
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
$null = New-Item -ItemType Directory -Force -Path (Split-Path $LogFile -Parent) -ErrorAction SilentlyContinue
Add-Content -Path $LogFile -Value $line -Encoding UTF8
}
function Get-Feature {
param([object]$Cfg, [string]$StepID, [string]$FeatureID, [bool]$Default = $true)
try {
if ($null -eq $Cfg) { return $Default }
$stepFeatures = $Cfg.features.$StepID
if ($null -eq $stepFeatures) { return $Default }
$val = $stepFeatures.$FeatureID
if ($null -eq $val) { return $Default }
return [bool]$val
} catch { return $Default }
}
# -----------------------------------------------------------------------
# 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 tweaks (alignment, buttons, tray, layout XML)
# -----------------------------------------------------------------------
if (Get-Feature $Config "defaultProfile" "taskbarTweaks") {
Write-Log "Applying taskbar tweaks" -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 all tray 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
$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
}
$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
# Taskbar pinned apps layout (Win10/11)
# ProfileType: default = empty, admin = Explorer+PS+Edge, user = Explorer+Edge
# Note: TaskbarLayoutModification.xml locks the taskbar temporarily.
# UnlockStartLayout scheduled task removes the lock 5 min after first boot
# so users can then customize pins freely.
# Win11 24H2+ may require ProvisionedLayoutModification.xml format instead.
Write-Log " Writing taskbar layout (ProfileType=$ProfileType)" -Level INFO
# Ensure File Explorer shortcut exists in Default profile's Start Menu.
# On a clean Windows 11 install the System Tools folder may be missing
# from C:\Users\Default\AppData\Roaming - without it the XML pin is silently skipped.
$wsh = New-Object -ComObject WScript.Shell
$defRoaming = "C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs"
$explorerLnkDir = "$defRoaming\System Tools"
$explorerLnk = "$explorerLnkDir\File Explorer.lnk"
if (-not (Test-Path $explorerLnk)) {
if (-not (Test-Path $explorerLnkDir)) { New-Item -ItemType Directory -Path $explorerLnkDir -Force | Out-Null }
$sc = $wsh.CreateShortcut($explorerLnk)
$sc.TargetPath = "$env:WINDIR\explorer.exe"
$sc.Save()
Write-Log " Created File Explorer.lnk in Default profile Start Menu" -Level OK
}
# Same for PowerShell (admin profile)
if ($ProfileType -eq "admin") {
$psLnkDir = "$defRoaming\Windows PowerShell"
$psLnk = "$psLnkDir\Windows PowerShell.lnk"
if (-not (Test-Path $psLnk)) {
if (-not (Test-Path $psLnkDir)) { New-Item -ItemType Directory -Path $psLnkDir -Force | Out-Null }
$sc = $wsh.CreateShortcut($psLnk)
$sc.TargetPath = "$env:WINDIR\System32\WindowsPowerShell\v1.0\powershell.exe"
$sc.Save()
Write-Log " Created Windows PowerShell.lnk in Default profile Start Menu" -Level OK
}
}
$taskbarLayoutDir = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell"
if (-not (Test-Path $taskbarLayoutDir)) {
New-Item -ItemType Directory -Path $taskbarLayoutDir -Force | Out-Null
}
$pinList = switch ($ProfileType) {
"admin" {
@'
'@
}
"user" {
@'
'@
}
default {
@'
'@
} # explicit pins with Replace = no Store, no other defaults
}
$taskbarLayoutXml = @"
$pinList
"@
$taskbarLayoutXml | Set-Content -Path "$taskbarLayoutDir\LayoutModification.xml" -Encoding UTF8 -Force
Write-Log " Taskbar LayoutModification.xml written (profile: $ProfileType)" -Level OK
# NumLock 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
} else {
Write-Log "taskbarTweaks feature disabled - skipping" -Level INFO
}
# -----------------------------------------------------------------------
# Start menu tweaks (pins, Bing, Copilot, GameDVR)
# -----------------------------------------------------------------------
if (Get-Feature $Config "defaultProfile" "startMenuTweaks") {
Write-Log "Applying Start menu tweaks" -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
# Disable Copilot
Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\WindowsCopilot" `
-Name "TurnOffWindowsCopilot" -Value 1
# Disable GameDVR
Set-ProfileReg -SubKey "System\GameConfigStore" `
-Name "GameDVR_Enabled" -Value 0
Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\GameDVR" `
-Name "AppCaptureEnabled" -Value 0
} else {
Write-Log "startMenuTweaks feature disabled - skipping" -Level INFO
}
# -----------------------------------------------------------------------
# Explorer tweaks (file extensions, LaunchTo, ShowRecent, FullPath)
# -----------------------------------------------------------------------
if (Get-Feature $Config "defaultProfile" "explorerTweaks") {
Write-Log "Applying Explorer tweaks" -Level STEP
$advPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
# Show file extensions in Explorer
Set-ProfileReg -SubKey $advPath -Name "HideFileExt" -Value 0
# Open Explorer to This PC instead of Quick Access
Set-ProfileReg -SubKey $advPath -Name "LaunchTo" -Value 1
# Hide Recent files from Quick Access
Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" `
-Name "ShowRecent" -Value 0
# Hide Frequent folders from Quick Access
Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" `
-Name "ShowFrequent" -Value 0
# Show full path in Explorer title bar
Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState" `
-Name "FullPath" -Value 1
} else {
Write-Log "explorerTweaks feature disabled - skipping" -Level INFO
}
}
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