Implement full deployment script suite (steps 1-7)
- Deploy-Windows.ps1: master script with Write-Log, Invoke-Step, summary report, DryRun support
- 01-bloatware.ps1: remove AppX packages, Windows Capabilities, Optional Features
- 02-software.ps1: winget installs from config.json, set Adobe Reader as default PDF app
- 03-system-registry.ps1: HKLM tweaks (NRO bypass, Teams, Widgets, Edge, OneDrive, GameDVR, Recall, timezone)
- 04-default-profile.ps1: NTUSER.DAT changes for taskbar, Explorer, Start menu, NumLock, Copilot
- 05-personalization.ps1: dark/light theme, accent color #223B47, transparency off, wallpaper
- 06-scheduled-tasks.ps1: ShowAllTrayIcons, PDF-DefaultApp, UnlockStartLayout tasks
- 07-desktop-info.ps1: DesktopInfo render script (System.Drawing BMP), scheduled task, deploy date registry
- tests/Test-Deployment.ps1: post-deployment verification, 30+ checks
- CLAUDE.md: add Czech communication preference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 09:44:38 +01:00
|
|
|
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]$Trigger,
|
|
|
|
|
[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 $Trigger `
|
|
|
|
|
-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 + every 1 minute, sets EnableAutoTray=0 so all tray icons
|
|
|
|
|
# are always visible (Win11 hides them by default)
|
|
|
|
|
# -----------------------------------------------------------------------
|
|
|
|
|
Write-Log "Registering task: ShowAllTrayIcons" -Level STEP
|
|
|
|
|
|
|
|
|
|
$showTrayScript = "$ScriptDir\ShowAllTrayIcons.ps1"
|
|
|
|
|
@'
|
|
|
|
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer"
|
|
|
|
|
Set-ItemProperty -Path $regPath -Name "EnableAutoTray" -Value 0 -Force
|
|
|
|
|
Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue
|
|
|
|
|
'@ | 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),
|
|
|
|
|
$(New-ScheduledTaskTrigger -RepetitionInterval (New-TimeSpan -Minutes 1) -Once -At (Get-Date))
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Register-Task -TaskName "ShowAllTrayIcons" `
|
|
|
|
|
-Description "Show all system tray icons for current user" `
|
|
|
|
|
-Action $showTrayAction `
|
|
|
|
|
-Trigger $showTrayTrigger[0]
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------------------------
|
|
|
|
|
# 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 association
|
|
|
|
|
$acroPaths = @(
|
2026-03-14 20:03:30 +01:00
|
|
|
"$env:ProgramFiles\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
|
|
|
|
|
"${env:ProgramFiles(x86)}\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
|
Implement full deployment script suite (steps 1-7)
- Deploy-Windows.ps1: master script with Write-Log, Invoke-Step, summary report, DryRun support
- 01-bloatware.ps1: remove AppX packages, Windows Capabilities, Optional Features
- 02-software.ps1: winget installs from config.json, set Adobe Reader as default PDF app
- 03-system-registry.ps1: HKLM tweaks (NRO bypass, Teams, Widgets, Edge, OneDrive, GameDVR, Recall, timezone)
- 04-default-profile.ps1: NTUSER.DAT changes for taskbar, Explorer, Start menu, NumLock, Copilot
- 05-personalization.ps1: dark/light theme, accent color #223B47, transparency off, wallpaper
- 06-scheduled-tasks.ps1: ShowAllTrayIcons, PDF-DefaultApp, UnlockStartLayout tasks
- 07-desktop-info.ps1: DesktopInfo render script (System.Drawing BMP), scheduled task, deploy date registry
- tests/Test-Deployment.ps1: post-deployment verification, 30+ checks
- CLAUDE.md: add Czech communication preference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 09:44:38 +01:00
|
|
|
"${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"
|
|
|
|
|
|
|
|
|
|
# Check current association
|
|
|
|
|
$current = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pdf\UserChoice" `
|
|
|
|
|
-Name "ProgId" -ErrorAction SilentlyContinue).ProgId
|
|
|
|
|
|
|
|
|
|
if ($current -ne $progId) {
|
|
|
|
|
$ucPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pdf\UserChoice"
|
|
|
|
|
if (-not (Test-Path $ucPath)) { New-Item -Path $ucPath -Force | Out-Null }
|
|
|
|
|
Set-ItemProperty -Path $ucPath -Name "ProgId" -Value $progId -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
|
|
|
|
|
|
|
|
|
|
Register-Task -TaskName "PDF-DefaultApp" `
|
|
|
|
|
-Description "Restore Adobe Reader as default PDF app on logon" `
|
|
|
|
|
-Action $pdfAction `
|
|
|
|
|
-Trigger $pdfTrigger
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------------------------
|
|
|
|
|
# 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
|