xetup/scripts/06-scheduled-tasks.ps1
Filip Zubik c42943cfa8 PS scripts, web platform, Forgejo CI, xetup.exe launcher
Initial deployment suite for X9.cz MSP Windows 10/11 deployment:
- PowerShell scripts 00-11: admin account, bloatware removal, software (winget+Atera),
  system registry tweaks, default profile, personalization, scheduled tasks,
  BackInfo desktop info, Windows activation, PC identity/rename, network, Dell Update
- Web platform: xetup.x9.cz (nginx), spec/annotation page, /dl shortlink, GitHub mirror
- Forgejo Actions CI: auto-build xetup.exe on push, publish to releases/latest
- Go xetup.exe: embeds all scripts/assets, per-feature checkboxes, load/save config
2026-04-16 14:49:41 +02:00

205 lines
9.5 KiB
PowerShell

<#
.SYNOPSIS
Registers logon scheduled tasks to maintain per-user settings that Windows resets.
.DESCRIPTION
Creates scheduled tasks under Task Scheduler that run at user logon (and optionally
on a timer) to enforce settings that Windows tends to revert. Tasks are registered
in the Default profile task store so new user accounts inherit them automatically.
Note: PDF-DefaultApp task has been removed - PDF default is set once during deployment.
.ITEMS
showalltrayicons-pri-logonu-kazdou-1-min: Task 'ShowAllTrayIcons': runs at logon, repeats every 1 minute. Sets HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\EnableAutoTray=0. Windows 11 re-enables auto-hiding of tray icons after updates and sometimes after logon - the 1-min repeat ensures permanent override.
unlockstartlayout-jednou-po-aplikaci-lay: Task 'UnlockStartLayout': runs once, 30 seconds after logon. Clears the Start menu layout lock bit that is set when ConfigureStartPins is applied. Without this, users cannot pin or unpin apps from Start after deployment.
pdf-defaultapp-pri-kazdem-logonu: REMOVED. PDF default is set once during deployment (step 02) with UCPD service stopped. The scheduled task is no longer needed.
#>
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
# -----------------------------------------------------------------------
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