Implement Forgejo review changes: Atera, UCPD, PDF default, OA3, dedup

02-software: add Atera RMM agent install (Invoke-WebRequest + msiexec /qn),
stop UCPD driver before PDF association write, restart after; remove
reference to PDF-DefaultApp scheduled task in header

03-system-registry: correct OneDrive uninstall description - intentional
(pre-installed consumer version only, no policy key, M365 can reinstall)

04-default-profile: OneDrive RunOnce blocking removed, ShowRecent=0,
ShowFrequent=0, FullPath=1 in CabinetState already added in prior session

06-scheduled-tasks: PDF-DefaultApp task removed - PDF set once in step 02

08-activation: add OA3/BIOS embedded key check via SoftwareLicensingService
WMI; key priority: config.json > OA3 firmware > GVLK

web/spec: update all status badges, remove mustfix flags, deduplicate
OneDrive entries across steps 01/03/04, add OA3 row to step-08

web/data/descriptions.json: regenerated (65 items)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
X9 Dev 2026-04-16 09:29:32 +02:00
parent c8ff952bbb
commit f5a5de943a
17 changed files with 2002 additions and 34 deletions

69
docker-compose.yml Normal file
View file

@ -0,0 +1,69 @@
services:
forgejo:
image: codeberg.org/forgejo/forgejo:9
container_name: xetup-forgejo
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
# Forgejo config via env
- FORGEJO__server__ROOT_URL=https://git.xetup.x9.cz
- FORGEJO__server__DOMAIN=git.xetup.x9.cz
- FORGEJO__server__SSH_DOMAIN=git.xetup.x9.cz
- FORGEJO__server__SSH_PORT=2222
- FORGEJO__server__LFS_START_SERVER=true
- FORGEJO__database__DB_TYPE=sqlite3
- FORGEJO__service__DISABLE_REGISTRATION=true
- FORGEJO__service__REQUIRE_SIGNIN_VIEW=false
- FORGEJO__ui__DEFAULT_THEME=forgejo-dark
- FORGEJO__repository__DEFAULT_BRANCH=main
- FORGEJO__actions__ENABLED=true
- FORGEJO__indexer__REPO_INDEXER_ENABLED=true
- FORGEJO__cors__ENABLED=true
- FORGEJO__cors__ALLOW_DOMAIN=xetup.x9.cz
- FORGEJO__cors__METHODS=GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
- FORGEJO__cors__HEADERS=Authorization,Content-Type
- FORGEJO__cors__MAX_AGE=10m
volumes:
- forgejo-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3100:3000" # Web UI (behind reverse proxy)
- "2222:22" # Git SSH
networks:
- xetup
runner:
image: code.forgejo.org/forgejo/runner:6.3.1
container_name: xetup-runner
restart: unless-stopped
depends_on:
- forgejo
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- runner-data:/data
- /var/run/docker.sock:/var/run/docker.sock
networks:
- xetup
web:
image: nginx:alpine
container_name: xetup-web
restart: unless-stopped
volumes:
- ./web:/usr/share/nginx/html:ro
- ./web/nginx.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- "3200:80" # Web (xetup.x9.cz via reverse proxy)
networks:
- xetup
volumes:
forgejo-data:
runner-data:
networks:
xetup:
name: xetup

View file

@ -1,3 +1,22 @@
<#
.SYNOPSIS
Creates the adminx9 local administrator account for MSP use.
.DESCRIPTION
Creates a hidden local administrator account 'adminx9' used by X9.cz technicians
for remote management and on-site administration. The account has no password by
design - it is invisible to regular users and only accessible to technicians who
know it exists. FullName is set to "X9.cz s.r.o." so it is identifiable in
system tools. Password policy is set so it never expires.
.ITEMS
vytvorit-lokalni-ucet-adminx9: Creates the account via [ADSI] WinNT provider. No password by design - the account is hidden from users and used only by MSP technicians for remote administration.
pridat-do-skupiny-administrators: Adds adminx9 to the local Administrators group via net localgroup. Required for full system management rights.
skryt-z-login-obrazovky-specialaccounts-: Sets HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList\adminx9 = 0. Removes the user tile from Windows login and lock screen completely.
heslo-nevypirsi-uzivatel-nesmeni-heslo: Sets ADS_UF_DONT_EXPIRE_PASSWD and ADS_UF_PASSWD_CANT_CHANGE flags via ADSI userFlags. The account never locks out or requires password maintenance.
zadne-heslo-aktualne-nastavovano-z-confi: Account created with empty password. Previous version used config.json password - removed because plaintext passwords in config files are a security risk.
fullname-x9-cz-s-r-o-via-adsi: Sets FullName property via [ADSI] so the account shows as "X9.cz s.r.o." in User Accounts panel, Event Viewer, and audit logs.
#>
param(
[object]$Config,
[string]$LogFile

View file

@ -1,3 +1,21 @@
<#
.SYNOPSIS
Removes pre-installed bloatware: AppX packages, Capabilities, and Optional Features.
.DESCRIPTION
Removes Microsoft-bundled apps and features not needed in a business MSP deployment.
Removal is done for all users (-AllUsers) and from the provisioning store so new
users do not get them either. Calculator is intentionally kept. RDP client and
OneDrive are NOT removed here - they are required for business use.
.ITEMS
appx-balicky-odstraneni-pro-vsechny-uziv: Uses Remove-AppxPackage -AllUsers and Remove-AppxProvisionedPackage. The provisioned removal prevents apps from reinstalling for new user profiles. Covers ~35 apps including Cortana, Copilot, Teams personal, Xbox, Skype, News, Weather, Maps.
zachovano-microsoft-windowscalculator: Calculator is explicitly excluded. Lightweight utility frequently used by technicians and end users. Removing it would require manual reinstall from Store.
windows-capabilities-fax-ie-openssh-wmp-: Removed via Remove-WindowsCapability: Fax & Scan, Internet Explorer mode, OpenSSH client, Windows Media Player (legacy), WordPad, Handwriting recognition, Steps Recorder, Math Input Panel, Quick Assist.
windows-optional-features-ps-2-0-mediapl: Disabled via Disable-WindowsOptionalFeature: PowerShell 2.0 (security risk - allows unsigned script execution bypass on older hosts), MediaPlayback, Windows Recall (AI screenshot surveillance), Snipping Tool optional component.
microsoft-remotedesktopconnection-nesmi-: The RDP client optional feature is explicitly NOT in the removal list. Must remain functional for MSP remote access, TeamViewer alternatives, and client IT management tasks.
onedrive-nesmi-byt-odstranovano-tady: OneDrive removal is NOT done here. OneDrive must remain available for Microsoft 365 / SharePoint deployment. Any OneDrive removal lines in this script are incorrect and must be removed.
#>
param(
[object]$Config,
[string]$LogFile

View file

@ -1,3 +1,24 @@
<#
.SYNOPSIS
Installs standard business software via winget, sets Adobe PDF default, and installs Atera RMM agent.
.DESCRIPTION
Uses winget to install the standard X9.cz MSP software bundle. Checks winget
availability before running. Each install is logged. After Adobe Acrobat Reader,
temporarily stops the UCPD driver (User Choice Protection Driver, present since
Win11 23H2 / Win10 22H2 update) to allow the HKCR file association write, sets
.pdf -> AcroRd32, then restarts UCPD. Atera RMM agent is installed for MSP
monitoring, remote access, and ticketing integration.
.ITEMS
7-zip-7zip-7zip: Installs 7-Zip (winget ID: 7zip.7zip). Used for archive management. Silent install with --accept-package-agreements --accept-source-agreements flags required for unattended deployment.
adobe-acrobat-reader-64-bit-adobe-acroba: Installs Adobe Acrobat Reader DC 64-bit (Adobe.Acrobat.Reader.64-bit). Required as the default PDF viewer to prevent Edge from handling PDFs in browser mode, which limits functionality.
openvpn-connect-openvpntechnologies-open: Installs OpenVPN Connect client. Used for client VPN access when the client network requires a VPN. The ovpn profile and credentials are configured separately per client.
seznam-sw-je-neuplny-co-dalsiho-patri-do: The standard software list is incomplete. Candidates to add: Notepad++ (Notepad++.Notepad++), Google Chrome (Google.Chrome), possibly Microsoft 365 Apps, remote support tools. Needs decision from X9.cz team.
atera-agent-install: Atera RMM agent installed via msiexec /qn. Download: Invoke-WebRequest from https://x9.servicedesk.atera.com/api/utils/agent-install/windows/?cid=31&aeid=50b72e7113e54a63ac76b96c54c7e337. Agent enables MSP monitoring, remote access, and ticketing integration with the Atera dashboard.
adobe-pdf-default-pdf-acrord32-po-instal: Sets .pdf -> AcroRd32 file association after Acrobat install via HKCR (system-wide, no UserChoice hash issue). UCPD driver is stopped immediately before the write and restarted after to ensure the association persists across Edge updates.
ucpd-sys-kernel-driver-od-feb-2024-bloku: UCPD.sys (User Choice Protection Driver) is stopped before the PDF association write and restarted after. Pattern: Stop-Service ucpd -> set HKCR\.pdf -> Start-Service ucpd. Implemented in this script.
#>
param(
[object]$Config,
[string]$LogFile
@ -78,6 +99,23 @@ if ($Config -and $Config.pdfDefault) {
if ($forcePdf) {
Write-Log "Setting Adobe Reader as default PDF app" -Level INFO
# Stop UCPD driver before writing file association.
# UCPD.sys (User Choice Protection Driver) blocks UserChoice registry writes
# on Win11 23H2+ and some Win10 22H2 builds. Stopping it temporarily allows
# the HKCR association to be written reliably.
$ucpdStopped = $false
$ucpdSvc = Get-Service -Name "ucpd" -ErrorAction SilentlyContinue
if ($ucpdSvc) {
try {
Stop-Service -Name "ucpd" -Force -ErrorAction Stop
$ucpdStopped = $true
Write-Log " UCPD driver stopped" -Level OK
}
catch {
Write-Log " Could not stop UCPD: $_ (association may not persist on some builds)" -Level WARN
}
}
# Find Adobe PDF viewer executable (Acrobat DC or Reader DC)
$acroPaths = @(
"$env:ProgramFiles\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
@ -110,13 +148,50 @@ if ($forcePdf) {
}
Set-ItemProperty -Path $cmdPath -Name "(Default)" -Value $openCmd
# Note: HKCU UserChoice requires a Windows-computed Hash value to be valid.
# Direct ProgId write without Hash is silently reset by Windows on next access.
# HKCR write above provides the system-wide default; per-user default is
# handled by the PDF-DefaultApp scheduled task via HKCR on every logon.
Write-Log " PDF default set to AcroRd32 (HKCR)" -Level OK
}
# Restart UCPD after writing association
if ($ucpdStopped) {
try {
Start-Service -Name "ucpd" -ErrorAction SilentlyContinue
Write-Log " UCPD driver restarted" -Level OK
}
catch {
Write-Log " Could not restart UCPD: $_" -Level WARN
}
}
}
# -----------------------------------------------------------------------
# Install Atera RMM Agent
# -----------------------------------------------------------------------
Write-Log "Installing Atera RMM Agent" -Level INFO
$ateraUrl = "https://x9.servicedesk.atera.com/api/utils/agent-install/windows/?cid=31&aeid=50b72e7113e54a63ac76b96c54c7e337"
$ateraMsi = "$env:TEMP\AteraAgent.msi"
try {
Write-Log " Downloading Atera agent..." -Level INFO
Invoke-WebRequest -Uri $ateraUrl -OutFile $ateraMsi -UseBasicParsing -ErrorAction Stop
Write-Log " Download complete" -Level OK
$msiResult = & msiexec /i $ateraMsi /qn 2>&1
Start-Sleep -Seconds 5
$ateraExe = "$env:ProgramFiles\ATERA Networks\AteraAgent\AteraAgent.exe"
if (Test-Path $ateraExe) {
Write-Log " Atera agent installed" -Level OK
} else {
Write-Log " Atera agent install may have failed - binary not found at expected path" -Level WARN
Write-Log " msiexec output: $($msiResult -join ' ')" -Level WARN
}
}
catch {
Write-Log " Atera agent download/install failed: $_" -Level ERROR
}
finally {
Remove-Item $ateraMsi -Force -ErrorAction SilentlyContinue
}
Write-Log "Step 2 complete" -Level OK

View file

@ -1,3 +1,29 @@
<#
.SYNOPSIS
Applies system-wide registry settings and power configuration (HKLM).
.DESCRIPTION
Sets machine-wide registry tweaks under HKLM that apply to all users. Disables
unwanted telemetry and cloud features, configures Edge policies, sets power plan
timeouts, and disables proxy auto-detect. Uninstalls the pre-installed OneDrive
consumer version via OneDriveSetup.exe /uninstall - intentional for a clean MSP
deployment baseline. No DisableFileSyncNGSC policy key is set, so M365 installation
can install and run its own OneDrive version without restriction.
.ITEMS
bypass-nro-oobe-bypassnro-1: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE\BypassNRO = 1. Bypasses the "Let's connect you to a network" OOBE screen. Enables offline Windows setup without forcing a Microsoft account login.
zakaz-auto-instalace-teams: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Communications\ConfigureChatAutoInstall = 0. Prevents Windows from auto-installing Teams Personal during OOBE or after Cumulative Updates.
zakaz-cloud-optimized-content: ContentDeliveryManager\DisableCloudOptimizedContent = 1. Stops Windows from pushing sponsored app suggestions, tips from Microsoft servers, and "Get even more from Windows" prompts.
zakaz-widgets-news-and-interests: HKLM\SOFTWARE\Policies\Microsoft\Dsh\AllowNewsAndInterests = 0. Disables the Widgets taskbar button and panel (news feed, weather, stocks). Not relevant for business deployments.
hesla-bez-expirace-net-accounts-maxpwage: net accounts /maxpwage:UNLIMITED. Sets the local password expiration policy to never. MSP-managed machines handle password rotation via other means (Atera, domain policy, manual).
casova-zona-central-europe-standard-time: Set-TimeZone -Id "Central Europe Standard Time". UTC+1 (UTC+2 in summer DST). Applied system-wide. Critical for correct log timestamps, scheduled task timing, and calendar sync.
zakaz-gamedvr: HKLM\SOFTWARE\Policies\Microsoft\Windows\GameDVR\AppCaptureEnabled = 0. Disables Xbox Game Bar screen capture overlay. Reduces background resource usage and eliminates unintended capture prompts on business machines.
edge-skryt-first-run-experience: HKLM\SOFTWARE\Policies\Microsoft\Edge\HideFirstRunExperience = 1. Suppresses the Edge welcome wizard (import from other browser, default browser prompt, etc.) for every user on first launch.
onedrive-uninstall-intentional: Uninstalls the pre-installed OneDrive consumer version via OneDriveSetup.exe /uninstall and removes Start Menu shortcut. Intentional for clean MSP deployment baseline. No DisableFileSyncNGSC policy key is set - M365 installation can reinstall and run OneDrive normally. Only the stock consumer pre-install is removed.
edge-policies-doplnit-15-dalsich-klicu: Missing Edge policies to add under HKLM\SOFTWARE\Policies\Microsoft\Edge: DefaultBrowserSettingEnabled=0, NewTabPageContentEnabled=0, ImportOnEachLaunch=0, ShowRecommendationsEnabled=0, PersonalizationReportingEnabled=0, SpotlightExperiencesAndRecommendationsEnabled=0, EdgeShoppingAssistantEnabled=0, HubsSidebarEnabled=0, ShowMicrosoftRewards=0, SearchSuggestEnabled=0, DiagnosticData=0.
powercfg-nastaveni-spotreba-energie: powercfg /change commands: standby-timeout-ac 0 (never sleep on AC/charger), monitor-timeout-ac 60 (screen off after 60 min on AC), standby-timeout-dc 30 (sleep after 30 min on battery), monitor-timeout-dc 15 (screen off after 15 min on battery).
proxy-auto-detect-zakaz-autodetect-0: HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AutoDetect = 0. Disables WPAD (Web Proxy Auto-Discovery). Eliminates startup delays from WPAD DNS lookup and prevents potential MITM via malicious WPAD responses on untrusted networks.
#>
param(
[object]$Config,
[string]$LogFile

View file

@ -1,3 +1,29 @@
<#
.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 with empty pinned app list. Removes default Microsoft pinned apps (Edge, Teams, Store, Mail) from taskbar. Clean slate - technician or user pins what is actually needed.
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
@ -236,29 +262,6 @@ try {
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)

View file

@ -1,3 +1,21 @@
<#
.SYNOPSIS
Sets system colors, wallpaper, and visual theme.
.DESCRIPTION
Applies X9.cz visual identity: dark taskbar/Start with accent color #223B47
(deep blue-gray), light app mode, no transparency. Wallpaper is set to a solid
color matching the accent. BackInfo.exe (Step 07) overwrites the wallpaper with
a live system info BMP on every logon - solid color is only the fallback.
.ITEMS
system-tema-taskbar-start-dark: SystemUsesLightTheme=0 in Themes\Personalize. Dark mode for shell (taskbar, Start menu, Action Center, notification area). Does NOT affect application windows - those stay light. Reduces eye strain in dim environments.
aplikacni-tema-light: AppsUseLightTheme=1. Application windows (File Explorer, Settings, Calculator, etc.) use white/light backgrounds. Majority of business applications (Office, browsers) also respect this and show light mode.
accent-barva-223b47-tmave-modroseda: AccentColor DWORD = 0xFF473B22 (stored as ABGR: A=FF, B=47, G=3B, R=22). The deep blue-gray #223B47 is the X9.cz brand color, also used as the solid wallpaper background.
accent-barva-na-start-a-taskbaru-ano: ColorPrevalence=1. Applies accent color to taskbar background and Start menu surface. The taskbar becomes the brand color instead of default black, creating a distinct recognizable look on X9.cz-deployed machines.
pruhlednost-vypnuta: EnableTransparency=0. Disables Aero translucency on taskbar and Start. Improves text readability on the taskbar, reduces subtle GPU usage, and looks more professional/consistent on business machines.
tapeta-jednobarevna-223b47-bez-obrazku: Wallpaper set to solid color #223B47 via SystemParametersInfo(SPI_SETDESKWALLPAPER). BackInfo.exe generates a BMP with hostname, username, OS, network info and sets it as wallpaper on every logon. Solid color = fallback only.
#>
param(
[object]$Config,
[string]$LogFile

View file

@ -1,3 +1,18 @@
<#
.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
@ -86,10 +101,6 @@ Register-Task -TaskName "ShowAllTrayIcons" `
-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

View file

@ -1,3 +1,20 @@
<#
.SYNOPSIS
DEPRECATED - delete this script. Replaced by BackInfo.exe.
.DESCRIPTION
Original custom PowerShell approach to render system info onto the desktop wallpaper
using WPF (System.Windows.Media / System.Drawing). Superseded by BackInfo.exe which
is already present in assets/Backinfo/ and handles Win10/Win11 natively.
ACTION REQUIRED: Delete this file. Add a BackInfo deployment step to the master script.
.ITEMS
07-desktop-info-ps1-smazat-stary-pristup: DELETE THIS FILE. The WPF rendering approach had compatibility issues on some Windows editions and required maintaining complex PS rendering code. BackInfo.exe is a mature, stable replacement already bundled in assets/Backinfo/.
zkopirovat-assets-backinfo-do-c-program-: NEW STEP (in master script): Copy assets/Backinfo/ to C:\Program Files\Backinfo\ on the target machine. Includes BackInfo.exe, BackInfo.ini (display config), and backinfo_W11.ps1 (setup helper).
spustit-backinfo-w11-ps1-detekce-os-regi: Run backinfo_W11.ps1 after file copy. Detects Win10 vs Win11, writes the required registry key for wallpaper rendering compatibility, and creates a Startup shortcut in the All Users Startup folder.
backinfo-exe-v-assets-backinfo-k-dispozi: BackInfo.exe reads BackInfo.ini on each run. INI configures: font size and family, position of each info block, which data sources to show (hostname, username, OS version, CPU, RAM, disk, IP address, domain).
backinfo-auto-start-pri-kazdem-logonu-vi: The Startup shortcut created by backinfo_W11.ps1 ensures BackInfo.exe runs on every user logon. It re-reads live system data each time, so the wallpaper BMP always shows current information (username changes, IP changes, etc.).
#>
param(
[object]$Config,
[string]$LogFile

View file

@ -1,3 +1,21 @@
<#
.SYNOPSIS
Activates Windows using a product key from config or KMS GVLK fallback.
.DESCRIPTION
Checks if Windows is already activated (LicenseStatus = 1). If not, reads the
product key from config.json activation.productKey. If no key is present, selects
the appropriate GVLK for the detected Windows edition and activates via KMS.
Optionally configures a specific KMS server if activation.kmsServer is set.
.ITEMS
oa3-bios-uefi-klic-kontrola-embedded-ke: Checks for OA3 embedded product key in BIOS/UEFI firmware via SoftwareLicensingService.OA3xOriginalProductKey WMI query. If a key is found, it is installed via slmgr /ipk and activation is attempted. Most OEM machines (since Win8 OA3) have a digital entitlement key in firmware - this path handles them without requiring a key in config.json.
klic-z-config-json-activation-productkey: Reads activation.productKey from config.json. Installs via slmgr.vbs /ipk <key> and activates via slmgr.vbs /ato. Supports MAK (Multiple Activation Key) for volume licensing without KMS, and retail keys. Takes priority over GVLK fallback.
fallback-na-gvlk-kms-client-key-dle-edic: When no key is in config, detects Windows edition via (Get-WmiObject SoftwareLicensingProduct).Name and maps to Microsoft's published GVLK table. Pro: W269N-WFGWX-YVC9B-4J6C9-T83GX, Enterprise: NPPR9-FWDCX-D2C8J-H872K-2YT43, Home: TX9XD-98N7V-6WMQ6-BX7FG-H8Q99.
volitelny-kms-server-activation-kmsserve: If activation.kmsServer is in config.json, runs slmgr.vbs /skms <server>:<port> before /ato. Used for clients with on-premises KMS infrastructure (common in larger organizations with volume licensing).
preskocit-pokud-jiz-aktivovano: Queries Win32_WindowsLicenseStatus or SoftwareLicensingProduct to check LicenseStatus. Value 1 = Licensed (fully activated). Script skips activation attempt and logs "Windows already activated" to avoid unnecessary slmgr calls.
typ-klice-mak-vs-kms-vs-retail: Key type selection depends on client's Microsoft licensing: MAK = volume license key activates online against Microsoft (limited activations), KMS = requires KMS server on network (VLSC subscription), Retail = individual license from Microsoft Store or OEM.
#>
param(
[object]$Config,
[string]$LogFile
@ -32,6 +50,21 @@ $KmsKeys = @{
"Windows 10 Home" = "TX9XD-98N7V-6WMQ6-BX7FG-H8Q99"
}
# -----------------------------------------------------------------------
# Check for OA3 embedded BIOS/UEFI product key
# Most OEM machines since Win8 OA3 have a product key embedded in firmware.
# -----------------------------------------------------------------------
Write-Log "Checking for OA3 embedded BIOS/UEFI product key" -Level INFO
$oa3Key = (Get-CimInstance -ClassName SoftwareLicensingService -ErrorAction SilentlyContinue).OA3xOriginalProductKey
if ($oa3Key -and $oa3Key.Trim() -ne '') {
$maskedKey = $oa3Key.Substring(0, [Math]::Min(5, $oa3Key.Length)) + "-XXXXX-XXXXX-XXXXX-XXXXX"
Write-Log " OA3 key found in firmware: $maskedKey" -Level OK
} else {
Write-Log " No OA3 key found in firmware" -Level INFO
$oa3Key = $null
}
# -----------------------------------------------------------------------
# Check current activation status
# -----------------------------------------------------------------------
@ -50,16 +83,20 @@ if ($licenseStatus -eq 1) {
$osCaption = (Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue).Caption
Write-Log " Detected OS: $osCaption" -Level INFO
# Check if a key is configured in config
# Key priority: config.json > OA3 firmware > GVLK
$customKey = $null
if ($Config -and $Config.activation -and $Config.activation.productKey) {
$customKey = $Config.activation.productKey
}
if ($customKey -and $customKey -ne "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX") {
# Use key from config
# Use key from config (highest priority)
$keyToUse = $customKey
Write-Log " Using product key from config" -Level INFO
} elseif ($oa3Key) {
# Use OA3 key from firmware
$keyToUse = $oa3Key
Write-Log " Using OA3 key from firmware" -Level INFO
} else {
# Find matching GVLK key by OS name
$keyToUse = $null

87
tools/extract-docs.py Normal file
View file

@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""
extract-docs.py - Extract documentation from PS script headers and generate web/data/descriptions.json
Usage: python3 tools/extract-docs.py
Run from repo root. Reads scripts/*.ps1, writes web/data/descriptions.json.
PS script header format:
<#
.SYNOPSIS
One line description
.DESCRIPTION
Multi-line description
.ITEMS
slug-of-spec-row: Description of what this item does
another-slug: Another description
#>
"""
import os, re, json
SCRIPTS_DIR = os.path.join(os.path.dirname(__file__), '..', 'scripts')
OUTPUT_FILE = os.path.join(os.path.dirname(__file__), '..', 'web', 'data', 'descriptions.json')
def parse_script(path):
with open(path, encoding='utf-8') as f:
content = f.read()
# Extract <# ... #> block
m = re.search(r'<#(.*?)#>', content, re.DOTALL)
if not m:
return None
block = m.group(1)
def extract_section(name):
pattern = r'\.' + name + r'\s*\n(.*?)(?=\n\s*\.[A-Z]|\Z)'
sm = re.search(pattern, block, re.DOTALL)
if not sm:
return ''
return re.sub(r'\n[ \t]+', '\n', sm.group(1)).strip()
synopsis = extract_section('SYNOPSIS').replace('\n', ' ').strip()
description = extract_section('DESCRIPTION').strip()
items_raw = extract_section('ITEMS')
items = {}
for line in items_raw.splitlines():
line = line.strip()
if not line or ':' not in line:
continue
slug, _, desc = line.partition(':')
slug = slug.strip()
desc = desc.strip()
if slug and desc:
items[slug] = desc
return {
'synopsis': synopsis,
'description': description,
'items': items,
}
def main():
result = {}
for fname in sorted(os.listdir(SCRIPTS_DIR)):
if not fname.endswith('.ps1'):
continue
script_id = fname.replace('.ps1', '')
path = os.path.join(SCRIPTS_DIR, fname)
parsed = parse_script(path)
if parsed:
result[script_id] = parsed
item_count = len(parsed['items'])
print(f'OK {fname}: {item_count} items')
else:
print(f'--- {fname}: no doc header found')
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
json.dump(result, f, ensure_ascii=False, indent=2)
print(f'\nWritten: {OUTPUT_FILE}')
print(f'Scripts documented: {len(result)}')
total_items = sum(len(v["items"]) for v in result.values())
print(f'Total item descriptions: {total_items}')
if __name__ == '__main__':
main()

121
web/data/descriptions.json Normal file
View file

@ -0,0 +1,121 @@
{
"00-admin-account": {
"synopsis": "Creates the adminx9 local administrator account for MSP use.",
"description": "Creates a hidden local administrator account 'adminx9' used by X9.cz technicians\nfor remote management and on-site administration. The account has no password by\ndesign - it is invisible to regular users and only accessible to technicians who\nknow it exists. FullName is set to \"X9.cz s.r.o.\" so it is identifiable in\nsystem tools. Password policy is set so it never expires.",
"items": {
"vytvorit-lokalni-ucet-adminx9": "Creates the account via [ADSI] WinNT provider. No password by design - the account is hidden from users and used only by MSP technicians for remote administration.",
"pridat-do-skupiny-administrators": "Adds adminx9 to the local Administrators group via net localgroup. Required for full system management rights.",
"skryt-z-login-obrazovky-specialaccounts-": "Sets HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\SpecialAccounts\\UserList\\adminx9 = 0. Removes the user tile from Windows login and lock screen completely.",
"heslo-nevypirsi-uzivatel-nesmeni-heslo": "Sets ADS_UF_DONT_EXPIRE_PASSWD and ADS_UF_PASSWD_CANT_CHANGE flags via ADSI userFlags. The account never locks out or requires password maintenance.",
"zadne-heslo-aktualne-nastavovano-z-confi": "Account created with empty password. Previous version used config.json password - removed because plaintext passwords in config files are a security risk.",
"fullname-x9-cz-s-r-o-via-adsi": "Sets FullName property via [ADSI] so the account shows as \"X9.cz s.r.o.\" in User Accounts panel, Event Viewer, and audit logs."
}
},
"01-bloatware": {
"synopsis": "Removes pre-installed bloatware: AppX packages, Capabilities, and Optional Features.",
"description": "Removes Microsoft-bundled apps and features not needed in a business MSP deployment.\nRemoval is done for all users (-AllUsers) and from the provisioning store so new\nusers do not get them either. Calculator is intentionally kept. RDP client and\nOneDrive are NOT removed here - they are required for business use.",
"items": {
"appx-balicky-odstraneni-pro-vsechny-uziv": "Uses Remove-AppxPackage -AllUsers and Remove-AppxProvisionedPackage. The provisioned removal prevents apps from reinstalling for new user profiles. Covers ~35 apps including Cortana, Copilot, Teams personal, Xbox, Skype, News, Weather, Maps.",
"zachovano-microsoft-windowscalculator": "Calculator is explicitly excluded. Lightweight utility frequently used by technicians and end users. Removing it would require manual reinstall from Store.",
"windows-capabilities-fax-ie-openssh-wmp-": "Removed via Remove-WindowsCapability: Fax & Scan, Internet Explorer mode, OpenSSH client, Windows Media Player (legacy), WordPad, Handwriting recognition, Steps Recorder, Math Input Panel, Quick Assist.",
"windows-optional-features-ps-2-0-mediapl": "Disabled via Disable-WindowsOptionalFeature: PowerShell 2.0 (security risk - allows unsigned script execution bypass on older hosts), MediaPlayback, Windows Recall (AI screenshot surveillance), Snipping Tool optional component.",
"microsoft-remotedesktopconnection-nesmi-": "The RDP client optional feature is explicitly NOT in the removal list. Must remain functional for MSP remote access, TeamViewer alternatives, and client IT management tasks.",
"onedrive-nesmi-byt-odstranovano-tady": "OneDrive removal is NOT done here. OneDrive must remain available for Microsoft 365 / SharePoint deployment. Any OneDrive removal lines in this script are incorrect and must be removed."
}
},
"02-software": {
"synopsis": "Installs standard business software via winget, sets Adobe PDF default, and installs Atera RMM agent.",
"description": "Uses winget to install the standard X9.cz MSP software bundle. Checks winget\navailability before running. Each install is logged. After Adobe Acrobat Reader,\ntemporarily stops the UCPD driver (User Choice Protection Driver, present since\nWin11 23H2 / Win10 22H2 update) to allow the HKCR file association write, sets\n.pdf -> AcroRd32, then restarts UCPD. Atera RMM agent is installed for MSP\nmonitoring, remote access, and ticketing integration.",
"items": {
"7-zip-7zip-7zip": "Installs 7-Zip (winget ID: 7zip.7zip). Used for archive management. Silent install with --accept-package-agreements --accept-source-agreements flags required for unattended deployment.",
"adobe-acrobat-reader-64-bit-adobe-acroba": "Installs Adobe Acrobat Reader DC 64-bit (Adobe.Acrobat.Reader.64-bit). Required as the default PDF viewer to prevent Edge from handling PDFs in browser mode, which limits functionality.",
"openvpn-connect-openvpntechnologies-open": "Installs OpenVPN Connect client. Used for client VPN access when the client network requires a VPN. The ovpn profile and credentials are configured separately per client.",
"seznam-sw-je-neuplny-co-dalsiho-patri-do": "The standard software list is incomplete. Candidates to add: Notepad++ (Notepad++.Notepad++), Google Chrome (Google.Chrome), possibly Microsoft 365 Apps, remote support tools. Needs decision from X9.cz team.",
"atera-agent-install": "Atera RMM agent installed via msiexec /qn. Download: Invoke-WebRequest from https://x9.servicedesk.atera.com/api/utils/agent-install/windows/?cid=31&aeid=50b72e7113e54a63ac76b96c54c7e337. Agent enables MSP monitoring, remote access, and ticketing integration with the Atera dashboard.",
"adobe-pdf-default-pdf-acrord32-po-instal": "Sets .pdf -> AcroRd32 file association after Acrobat install via HKCR (system-wide, no UserChoice hash issue). UCPD driver is stopped immediately before the write and restarted after to ensure the association persists across Edge updates.",
"ucpd-sys-kernel-driver-od-feb-2024-bloku": "UCPD.sys (User Choice Protection Driver) is stopped before the PDF association write and restarted after. Pattern: Stop-Service ucpd -> set HKCR\\.pdf -> Start-Service ucpd. Implemented in this script."
}
},
"03-system-registry": {
"synopsis": "Applies system-wide registry settings and power configuration (HKLM).",
"description": "Sets machine-wide registry tweaks under HKLM that apply to all users. Disables\nunwanted telemetry and cloud features, configures Edge policies, sets power plan\ntimeouts, and disables proxy auto-detect. Uninstalls the pre-installed OneDrive\nconsumer version via OneDriveSetup.exe /uninstall - intentional for a clean MSP\ndeployment baseline. No DisableFileSyncNGSC policy key is set, so M365 installation\ncan install and run its own OneDrive version without restriction.",
"items": {
"bypass-nro-oobe-bypassnro-1": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE\\BypassNRO = 1. Bypasses the \"Let's connect you to a network\" OOBE screen. Enables offline Windows setup without forcing a Microsoft account login.",
"zakaz-auto-instalace-teams": "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Communications\\ConfigureChatAutoInstall = 0. Prevents Windows from auto-installing Teams Personal during OOBE or after Cumulative Updates.",
"zakaz-cloud-optimized-content": "ContentDeliveryManager\\DisableCloudOptimizedContent = 1. Stops Windows from pushing sponsored app suggestions, tips from Microsoft servers, and \"Get even more from Windows\" prompts.",
"zakaz-widgets-news-and-interests": "HKLM\\SOFTWARE\\Policies\\Microsoft\\Dsh\\AllowNewsAndInterests = 0. Disables the Widgets taskbar button and panel (news feed, weather, stocks). Not relevant for business deployments.",
"hesla-bez-expirace-net-accounts-maxpwage": "net accounts /maxpwage:UNLIMITED. Sets the local password expiration policy to never. MSP-managed machines handle password rotation via other means (Atera, domain policy, manual).",
"casova-zona-central-europe-standard-time": "Set-TimeZone -Id \"Central Europe Standard Time\". UTC+1 (UTC+2 in summer DST). Applied system-wide. Critical for correct log timestamps, scheduled task timing, and calendar sync.",
"zakaz-gamedvr": "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\GameDVR\\AppCaptureEnabled = 0. Disables Xbox Game Bar screen capture overlay. Reduces background resource usage and eliminates unintended capture prompts on business machines.",
"edge-skryt-first-run-experience": "HKLM\\SOFTWARE\\Policies\\Microsoft\\Edge\\HideFirstRunExperience = 1. Suppresses the Edge welcome wizard (import from other browser, default browser prompt, etc.) for every user on first launch.",
"onedrive-uninstall-intentional": "Uninstalls the pre-installed OneDrive consumer version via OneDriveSetup.exe /uninstall and removes Start Menu shortcut. Intentional for clean MSP deployment baseline. No DisableFileSyncNGSC policy key is set - M365 installation can reinstall and run OneDrive normally. Only the stock consumer pre-install is removed.",
"edge-policies-doplnit-15-dalsich-klicu": "Missing Edge policies to add under HKLM\\SOFTWARE\\Policies\\Microsoft\\Edge: DefaultBrowserSettingEnabled=0, NewTabPageContentEnabled=0, ImportOnEachLaunch=0, ShowRecommendationsEnabled=0, PersonalizationReportingEnabled=0, SpotlightExperiencesAndRecommendationsEnabled=0, EdgeShoppingAssistantEnabled=0, HubsSidebarEnabled=0, ShowMicrosoftRewards=0, SearchSuggestEnabled=0, DiagnosticData=0.",
"powercfg-nastaveni-spotreba-energie": "powercfg /change commands: standby-timeout-ac 0 (never sleep on AC/charger), monitor-timeout-ac 60 (screen off after 60 min on AC), standby-timeout-dc 30 (sleep after 30 min on battery), monitor-timeout-dc 15 (screen off after 15 min on battery).",
"proxy-auto-detect-zakaz-autodetect-0": "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\AutoDetect = 0. Disables WPAD (Web Proxy Auto-Discovery). Eliminates startup delays from WPAD DNS lookup and prevents potential MITM via malicious WPAD responses on untrusted networks."
}
},
"04-default-profile": {
"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\nall settings, then unloads it. Every new user account created on this machine inherits\nthese settings on first logon. The same settings are applied directly to the current\nuser'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 with empty pinned app list. Removes default Microsoft pinned apps (Edge, Teams, Store, Mail) from taskbar. Clean slate - technician or user pins what is actually needed.",
"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."
}
},
"05-personalization": {
"synopsis": "Sets system colors, wallpaper, and visual theme.",
"description": "Applies X9.cz visual identity: dark taskbar/Start with accent color #223B47\n(deep blue-gray), light app mode, no transparency. Wallpaper is set to a solid\ncolor matching the accent. BackInfo.exe (Step 07) overwrites the wallpaper with\na live system info BMP on every logon - solid color is only the fallback.",
"items": {
"system-tema-taskbar-start-dark": "SystemUsesLightTheme=0 in Themes\\Personalize. Dark mode for shell (taskbar, Start menu, Action Center, notification area). Does NOT affect application windows - those stay light. Reduces eye strain in dim environments.",
"aplikacni-tema-light": "AppsUseLightTheme=1. Application windows (File Explorer, Settings, Calculator, etc.) use white/light backgrounds. Majority of business applications (Office, browsers) also respect this and show light mode.",
"accent-barva-223b47-tmave-modroseda": "AccentColor DWORD = 0xFF473B22 (stored as ABGR: A=FF, B=47, G=3B, R=22). The deep blue-gray #223B47 is the X9.cz brand color, also used as the solid wallpaper background.",
"accent-barva-na-start-a-taskbaru-ano": "ColorPrevalence=1. Applies accent color to taskbar background and Start menu surface. The taskbar becomes the brand color instead of default black, creating a distinct recognizable look on X9.cz-deployed machines.",
"pruhlednost-vypnuta": "EnableTransparency=0. Disables Aero translucency on taskbar and Start. Improves text readability on the taskbar, reduces subtle GPU usage, and looks more professional/consistent on business machines.",
"tapeta-jednobarevna-223b47-bez-obrazku": "Wallpaper set to solid color #223B47 via SystemParametersInfo(SPI_SETDESKWALLPAPER). BackInfo.exe generates a BMP with hostname, username, OS, network info and sets it as wallpaper on every logon. Solid color = fallback only."
}
},
"06-scheduled-tasks": {
"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\non a timer) to enforce settings that Windows tends to revert. Tasks are registered\nin the Default profile task store so new user accounts inherit them automatically.\nNote: 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."
}
},
"07-desktop-info": {
"synopsis": "DEPRECATED - delete this script. Replaced by BackInfo.exe.",
"description": "Original custom PowerShell approach to render system info onto the desktop wallpaper\nusing WPF (System.Windows.Media / System.Drawing). Superseded by BackInfo.exe which\nis already present in assets/Backinfo/ and handles Win10/Win11 natively.\nACTION REQUIRED: Delete this file. Add a BackInfo deployment step to the master script.",
"items": {
"07-desktop-info-ps1-smazat-stary-pristup": "DELETE THIS FILE. The WPF rendering approach had compatibility issues on some Windows editions and required maintaining complex PS rendering code. BackInfo.exe is a mature, stable replacement already bundled in assets/Backinfo/.",
"zkopirovat-assets-backinfo-do-c-program-": "NEW STEP (in master script): Copy assets/Backinfo/ to C:\\Program Files\\Backinfo\\ on the target machine. Includes BackInfo.exe, BackInfo.ini (display config), and backinfo_W11.ps1 (setup helper).",
"spustit-backinfo-w11-ps1-detekce-os-regi": "Run backinfo_W11.ps1 after file copy. Detects Win10 vs Win11, writes the required registry key for wallpaper rendering compatibility, and creates a Startup shortcut in the All Users Startup folder.",
"backinfo-exe-v-assets-backinfo-k-dispozi": "BackInfo.exe reads BackInfo.ini on each run. INI configures: font size and family, position of each info block, which data sources to show (hostname, username, OS version, CPU, RAM, disk, IP address, domain).",
"backinfo-auto-start-pri-kazdem-logonu-vi": "The Startup shortcut created by backinfo_W11.ps1 ensures BackInfo.exe runs on every user logon. It re-reads live system data each time, so the wallpaper BMP always shows current information (username changes, IP changes, etc.)."
}
},
"08-activation": {
"synopsis": "Activates Windows using a product key from config or KMS GVLK fallback.",
"description": "Checks if Windows is already activated (LicenseStatus = 1). If not, reads the\nproduct key from config.json activation.productKey. If no key is present, selects\nthe appropriate GVLK for the detected Windows edition and activates via KMS.\nOptionally configures a specific KMS server if activation.kmsServer is set.",
"items": {
"oa3-bios-uefi-klic-kontrola-embedded-ke": "Checks for OA3 embedded product key in BIOS/UEFI firmware via SoftwareLicensingService.OA3xOriginalProductKey WMI query. If a key is found, it is installed via slmgr /ipk and activation is attempted. Most OEM machines (since Win8 OA3) have a digital entitlement key in firmware - this path handles them without requiring a key in config.json.",
"klic-z-config-json-activation-productkey": "Reads activation.productKey from config.json. Installs via slmgr.vbs /ipk <key> and activates via slmgr.vbs /ato. Supports MAK (Multiple Activation Key) for volume licensing without KMS, and retail keys. Takes priority over GVLK fallback.",
"fallback-na-gvlk-kms-client-key-dle-edic": "When no key is in config, detects Windows edition via (Get-WmiObject SoftwareLicensingProduct).Name and maps to Microsoft's published GVLK table. Pro: W269N-WFGWX-YVC9B-4J6C9-T83GX, Enterprise: NPPR9-FWDCX-D2C8J-H872K-2YT43, Home: TX9XD-98N7V-6WMQ6-BX7FG-H8Q99.",
"volitelny-kms-server-activation-kmsserve": "If activation.kmsServer is in config.json, runs slmgr.vbs /skms <server>:<port> before /ato. Used for clients with on-premises KMS infrastructure (common in larger organizations with volume licensing).",
"preskocit-pokud-jiz-aktivovano": "Queries Win32_WindowsLicenseStatus or SoftwareLicensingProduct to check LicenseStatus. Value 1 = Licensed (fully activated). Script skips activation attempt and logs \"Windows already activated\" to avoid unnecessary slmgr calls.",
"typ-klice-mak-vs-kms-vs-retail": "Key type selection depends on client's Microsoft licensing: MAK = volume license key activates online against Microsoft (limited activations), KMS = requires KMS server on network (VLSC subscription), Retail = individual license from Microsoft Store or OEM."
}
}
}

BIN
web/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

237
web/index.html Normal file
View file

@ -0,0 +1,237 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Xetup - Windows deployment pro X9.cz</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<style>
:root {
--bg: #0f1117;
--card: #1a1d27;
--border: #2a2d3a;
--text: #e0e0e0;
--muted: #888;
--accent: #223B47;
--accent-bright: #2d5266;
--green: #2ea043;
--blue: #58a6ff;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
flex-direction: column;
}
header {
border-bottom: 1px solid var(--border);
padding: 1rem 2rem;
display: flex;
align-items: center;
gap: .75rem;
}
.logo-text {
font-size: 1.2rem;
font-weight: 700;
color: #fff;
letter-spacing: -.02em;
}
.logo-sub {
font-size: .8rem;
color: var(--muted);
margin-left: .2rem;
}
header nav {
margin-left: auto;
display: flex;
gap: 1.5rem;
}
header nav a {
color: var(--muted);
text-decoration: none;
font-size: .88rem;
transition: color .15s;
}
header nav a:hover { color: var(--text); }
main {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 4rem 2rem;
text-align: center;
}
.badge {
display: inline-block;
background: var(--card);
border: 1px solid var(--border);
border-radius: 20px;
padding: .25rem .75rem;
font-size: .75rem;
color: var(--muted);
margin-bottom: 1.5rem;
letter-spacing: .03em;
}
h1 {
font-size: 2.8rem;
font-weight: 800;
color: #fff;
letter-spacing: -.04em;
line-height: 1.1;
margin-bottom: 1rem;
max-width: 600px;
}
h1 span { color: var(--blue); }
.tagline {
font-size: 1.1rem;
color: var(--muted);
max-width: 480px;
line-height: 1.6;
margin-bottom: 2.5rem;
}
.actions {
display: flex;
gap: .75rem;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 4rem;
}
.btn-primary {
padding: .6rem 1.4rem;
background: var(--accent-bright);
color: #fff;
border: 1px solid transparent;
border-radius: 8px;
font-size: .95rem;
font-weight: 600;
text-decoration: none;
transition: opacity .15s;
}
.btn-primary:hover { opacity: .85; }
.btn-secondary {
padding: .6rem 1.4rem;
background: transparent;
color: var(--text);
border: 1px solid var(--border);
border-radius: 8px;
font-size: .95rem;
text-decoration: none;
transition: background .15s;
}
.btn-secondary:hover { background: var(--card); }
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
max-width: 720px;
width: 100%;
}
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 1.2rem;
text-align: left;
}
.card-icon {
font-size: 1.3rem;
margin-bottom: .6rem;
display: block;
}
.card h3 {
font-size: .9rem;
font-weight: 600;
color: #fff;
margin-bottom: .3rem;
}
.card p {
font-size: .82rem;
color: var(--muted);
line-height: 1.4;
}
footer {
border-top: 1px solid var(--border);
padding: 1.2rem 2rem;
text-align: center;
font-size: .8rem;
color: var(--muted);
}
footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--text); }
</style>
</head>
<body>
<header>
<div style="display:flex;align-items:center;gap:.6rem">
<img src="/x9-logo.jpeg" alt="X9.cz" style="height:28px;width:28px;border-radius:5px;object-fit:cover;">
<span class="logo-text">xetup</span><span class="logo-sub">by X9.cz</span>
</div>
<nav>
<a href="/spec/">Specifikace</a>
<a href="https://git.xetup.x9.cz/x9/xetup">Git</a>
<a href="https://git.xetup.x9.cz/x9/xetup/issues">Issues</a>
</nav>
</header>
<main>
<div class="badge">MSP deployment tool &mdash; X9.cz</div>
<h1>Automaticky nastavene <span>Windows</span> za 20 minut</h1>
<p class="tagline">
Nahrazuje 3 hodiny rucniho nastavovani jednim skriptem.
Win10 + Win11, OEM i cisty install, funguje offline.
</p>
<div class="actions">
<a href="/spec/" class="btn-primary">Zobrazit specifikaci</a>
<a href="https://git.xetup.x9.cz/x9/xetup" class="btn-secondary">Git repozitar</a>
</div>
<div class="cards">
<div class="card">
<span class="card-icon">&#9881;</span>
<h3>~20 stroju / mesic</h3>
<p>Ruzni klienti, Win10 i Win11, vcetne nepodporovaneho HW.</p>
</div>
<div class="card">
<span class="card-icon">&#128274;</span>
<h3>Offline provoz</h3>
<p>Scripty + assets jsou soucasti balicku. Site jen pro winget a Atera.</p>
</div>
<div class="card">
<span class="card-icon">&#128196;</span>
<h3>Per-client config</h3>
<p>config.json vedle .exe pro opakovatelne nasazeni u stejneho klienta.</p>
</div>
<div class="card">
<span class="card-icon">&#128640;</span>
<h3>Go TUI launcher</h3>
<p>xetup.exe &mdash; jednotny binarni spoustec. Zatim ve vyvoji.</p>
</div>
</div>
</main>
<footer>
&copy; 2026 <a href="https://x9.cz">X9.cz s.r.o.</a>
&nbsp;&middot;&nbsp;
<a href="https://git.xetup.x9.cz/x9/xetup">Forgejo</a>
&nbsp;&middot;&nbsp;
<a href="/spec/">Specifikace</a>
</footer>
</body>
</html>

17
web/nginx.conf Normal file
View file

@ -0,0 +1,17 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
charset utf-8;
location / {
try_files $uri $uri/ $uri.html =404;
}
error_page 404 /404.html;
# Disable caching during development
add_header Cache-Control "no-store";
add_header X-Content-Type-Options nosniff;
}

1213
web/spec/index.html Normal file

File diff suppressed because it is too large Load diff

BIN
web/x9-logo.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB