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 } $ScriptDir = "C:\Windows\Setup\Scripts" if (-not (Test-Path $ScriptDir)) { New-Item -ItemType Directory -Path $ScriptDir -Force | Out-Null } function Register-Task { param( [string]$TaskName, [string]$Description, [object]$Action, [object[]]$Triggers, [string]$RunLevel = "Highest" ) try { # Remove existing task with same name Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 5) ` -MultipleInstances IgnoreNew ` -StartWhenAvailable $principal = New-ScheduledTaskPrincipal -GroupId "Users" ` -RunLevel $RunLevel $task = New-ScheduledTask -Action $Action ` -Trigger $Triggers ` -Settings $settings ` -Principal $principal ` -Description $Description Register-ScheduledTask -TaskName $TaskName -InputObject $task -Force | Out-Null Write-Log " Registered task: $TaskName" -Level OK } catch { Write-Log " Failed to register task $TaskName - $_" -Level ERROR } } # ----------------------------------------------------------------------- # Task: ShowAllTrayIcons # Runs on logon: clears TrayNotify icon cache and restarts Explorer so all # tray icons are visible on first login (Win10: EnableAutoTray=0, Win11: cache clear) # ----------------------------------------------------------------------- Write-Log "Registering task: ShowAllTrayIcons" -Level STEP $showTrayScript = "$ScriptDir\ShowAllTrayIcons.ps1" @' # Win10: disable auto-hiding of tray icons $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer" Set-ItemProperty -Path $regPath -Name "EnableAutoTray" -Value 0 -Force -ErrorAction SilentlyContinue # Win11: clear icon stream cache so all icons become visible after Explorer restart $trayPath = "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" if (Test-Path $trayPath) { Remove-ItemProperty -Path $trayPath -Name "IconStreams" -Force -ErrorAction SilentlyContinue Remove-ItemProperty -Path $trayPath -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue } # Restart Explorer to apply changes Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 1500 if (-not (Get-Process explorer -ErrorAction SilentlyContinue)) { Start-Process explorer } '@ | Set-Content -Path $showTrayScript -Encoding UTF8 -Force $showTrayAction = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$showTrayScript`"" $showTrayTrigger = New-ScheduledTaskTrigger -AtLogOn Register-Task -TaskName "ShowAllTrayIcons" ` -Description "Show all system tray icons for current user" ` -Action $showTrayAction ` -Triggers $showTrayTrigger # ----------------------------------------------------------------------- # Task: PDF-DefaultApp # Runs on every logon, restores .pdf -> Adobe Reader association # Guards against Edge overwriting it # ----------------------------------------------------------------------- Write-Log "Registering task: PDF-DefaultApp" -Level STEP $pdfScript = "$ScriptDir\PDF-DefaultApp.ps1" @' # Restore .pdf -> Adobe Reader HKCR association (system-wide). # Runs as SYSTEM so it can write to HKCR regardless of Edge updates. # Note: HKCU UserChoice requires Windows Hash validation and cannot be # set reliably via registry; HKCR provides the system-wide fallback. $acroPaths = @( "$env:ProgramFiles\Adobe\Acrobat DC\Acrobat\Acrobat.exe" "${env:ProgramFiles(x86)}\Adobe\Acrobat DC\Acrobat\Acrobat.exe" "${env:ProgramFiles(x86)}\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" "$env:ProgramFiles\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" "${env:ProgramFiles(x86)}\Adobe\Reader\Reader\AcroRd32.exe" ) $acroExe = $acroPaths | Where-Object { Test-Path $_ } | Select-Object -First 1 if (-not $acroExe) { exit 0 } $progId = "AcroExch.Document.DC" $openCmd = "`"$acroExe`" `"%1`"" # HKCR\.pdf if (-not (Test-Path "HKCR:\.pdf")) { New-Item -Path "HKCR:\.pdf" -Force | Out-Null } $current = (Get-ItemProperty -Path "HKCR:\.pdf" -Name "(Default)" -ErrorAction SilentlyContinue)."(Default)" if ($current -ne $progId) { Set-ItemProperty -Path "HKCR:\.pdf" -Name "(Default)" -Value $progId -Force } # HKCR\AcroExch.Document.DC\shell\open\command $cmdPath = "HKCR:\$progId\shell\open\command" if (-not (Test-Path $cmdPath)) { New-Item -Path $cmdPath -Force | Out-Null } Set-ItemProperty -Path $cmdPath -Name "(Default)" -Value $openCmd -Force '@ | Set-Content -Path $pdfScript -Encoding UTF8 -Force $pdfAction = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$pdfScript`"" $pdfTrigger = New-ScheduledTaskTrigger -AtLogOn # Runs as SYSTEM to allow HKCR writes (system-wide file association) $pdfPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest $pdfSettings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 2) ` -MultipleInstances IgnoreNew ` -StartWhenAvailable $pdfTask = New-ScheduledTask -Action $pdfAction ` -Trigger $pdfTrigger ` -Settings $pdfSettings ` -Principal $pdfPrincipal ` -Description "Restore Adobe Reader as default PDF app on logon" try { Unregister-ScheduledTask -TaskName "PDF-DefaultApp" -Confirm:$false -ErrorAction SilentlyContinue Register-ScheduledTask -TaskName "PDF-DefaultApp" -InputObject $pdfTask -Force | Out-Null Write-Log " Registered task: PDF-DefaultApp" -Level OK } catch { Write-Log " Failed to register task PDF-DefaultApp - $_" -Level ERROR } # ----------------------------------------------------------------------- # Task: UnlockStartLayout # Runs once after deployment to unlock the Start menu layout # so users can still customize it later # ----------------------------------------------------------------------- Write-Log "Registering task: UnlockStartLayout" -Level STEP $unlockScript = "$ScriptDir\UnlockStartLayout.ps1" @' # Remove Start layout lock so users can modify it $layoutXml = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml" if (Test-Path $layoutXml) { Remove-Item $layoutXml -Force -ErrorAction SilentlyContinue } # Unregister self after running once Unregister-ScheduledTask -TaskName "UnlockStartLayout" -Confirm:$false -ErrorAction SilentlyContinue '@ | Set-Content -Path $unlockScript -Encoding UTF8 -Force $unlockAction = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$unlockScript`"" # Trigger: 5 minutes after system startup, once $unlockTrigger = New-ScheduledTaskTrigger -AtStartup $unlockTrigger.Delay = "PT5M" $unlockPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest $unlockSettings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 10) ` -StartWhenAvailable $unlockTask = New-ScheduledTask -Action $unlockAction ` -Trigger $unlockTrigger ` -Settings $unlockSettings ` -Principal $unlockPrincipal ` -Description "Unlock Start menu layout 5 min after first boot" try { Unregister-ScheduledTask -TaskName "UnlockStartLayout" -Confirm:$false -ErrorAction SilentlyContinue Register-ScheduledTask -TaskName "UnlockStartLayout" -InputObject $unlockTask -Force | Out-Null Write-Log " Registered task: UnlockStartLayout" -Level OK } catch { Write-Log " Failed to register task UnlockStartLayout - $_" -Level ERROR } Write-Log "Step 6 complete" -Level OK