diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b9377d3 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/scripts/00-admin-account.ps1 b/scripts/00-admin-account.ps1 index bbd3390..98acf07 100644 --- a/scripts/00-admin-account.ps1 +++ b/scripts/00-admin-account.ps1 @@ -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 diff --git a/scripts/01-bloatware.ps1 b/scripts/01-bloatware.ps1 index 30fbbe4..482c5bb 100644 --- a/scripts/01-bloatware.ps1 +++ b/scripts/01-bloatware.ps1 @@ -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 diff --git a/scripts/02-software.ps1 b/scripts/02-software.ps1 index f6d7cf1..7536cae 100644 --- a/scripts/02-software.ps1 +++ b/scripts/02-software.ps1 @@ -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 diff --git a/scripts/03-system-registry.ps1 b/scripts/03-system-registry.ps1 index ac68be4..d27bbba 100644 --- a/scripts/03-system-registry.ps1 +++ b/scripts/03-system-registry.ps1 @@ -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 diff --git a/scripts/04-default-profile.ps1 b/scripts/04-default-profile.ps1 index 03b0b1e..b08fec6 100644 --- a/scripts/04-default-profile.ps1 +++ b/scripts/04-default-profile.ps1 @@ -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) diff --git a/scripts/05-personalization.ps1 b/scripts/05-personalization.ps1 index 957806e..9d69fd3 100644 --- a/scripts/05-personalization.ps1 +++ b/scripts/05-personalization.ps1 @@ -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 diff --git a/scripts/06-scheduled-tasks.ps1 b/scripts/06-scheduled-tasks.ps1 index fbdfec8..ca8c879 100644 --- a/scripts/06-scheduled-tasks.ps1 +++ b/scripts/06-scheduled-tasks.ps1 @@ -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 diff --git a/scripts/07-desktop-info.ps1 b/scripts/07-desktop-info.ps1 index 84f2e7f..e188773 100644 --- a/scripts/07-desktop-info.ps1 +++ b/scripts/07-desktop-info.ps1 @@ -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 diff --git a/scripts/08-activation.ps1 b/scripts/08-activation.ps1 index c3cbef3..8a87281 100644 --- a/scripts/08-activation.ps1 +++ b/scripts/08-activation.ps1 @@ -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 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 : 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 diff --git a/tools/extract-docs.py b/tools/extract-docs.py new file mode 100644 index 0000000..7d61cac --- /dev/null +++ b/tools/extract-docs.py @@ -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() diff --git a/web/data/descriptions.json b/web/data/descriptions.json new file mode 100644 index 0000000..f7aef92 --- /dev/null +++ b/web/data/descriptions.json @@ -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 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 : 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." + } + } +} \ No newline at end of file diff --git a/web/favicon.ico b/web/favicon.ico new file mode 100644 index 0000000..3f9c992 Binary files /dev/null and b/web/favicon.ico differ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..3607d64 --- /dev/null +++ b/web/index.html @@ -0,0 +1,237 @@ + + + + + +Xetup - Windows deployment pro X9.cz + + + + + +
+
+ X9.cz + xetupby X9.cz +
+ +
+ +
+
MSP deployment tool — X9.cz
+ +

Automaticky nastavene Windows za 20 minut

+ +

+ Nahrazuje 3 hodiny rucniho nastavovani jednim skriptem. + Win10 + Win11, OEM i cisty install, funguje offline. +

+ + + +
+
+ +

~20 stroju / mesic

+

Ruzni klienti, Win10 i Win11, vcetne nepodporovaneho HW.

+
+
+ 🔒 +

Offline provoz

+

Scripty + assets jsou soucasti balicku. Site jen pro winget a Atera.

+
+
+ 📄 +

Per-client config

+

config.json vedle .exe pro opakovatelne nasazeni u stejneho klienta.

+
+
+ 🚀 +

Go TUI launcher

+

xetup.exe — jednotny binarni spoustec. Zatim ve vyvoji.

+
+
+
+ + + + + diff --git a/web/nginx.conf b/web/nginx.conf new file mode 100644 index 0000000..f497827 --- /dev/null +++ b/web/nginx.conf @@ -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; +} diff --git a/web/spec/index.html b/web/spec/index.html new file mode 100644 index 0000000..ea8216e --- /dev/null +++ b/web/spec/index.html @@ -0,0 +1,1213 @@ + + + + + +Specifikace & anotace – xetup + + + + + +
+ + +
+ +
+ + + + + +
+ +

Specifikace & anotace

+
+ Verze: 0.3-draft + Datum: 2026-04-16 + x9/xetup + Status: aktivni vyvoj +
+ +
+ OK hotovo, v provozu + Must fix zname chyby, nutno opravit + TODO naplanovano, nerealizovano + Open otevrena otazka + Warn potencialni problem + New nova feature + Future dlouhodoby plan +
+ + + + + +
+
+ 00 + Admin ucet (adminx9) + Must fix +
+
+ + + + + + + +
Vytvorit lokalni ucet adminx9Hotovo
Pridat do skupiny AdministratorsHotovo
Skryt z login obrazovky (SpecialAccounts\UserList = 0)Hotovo
Heslo nevypirsi, uzivatel nesmeni hesloHotovo
Zadne heslo (aktualne nastavovano z config.json)Zmenit: ucet BEZ hesla (rozhodnuti)
FullName = "X9.cz s.r.o." (via ADSI)Chybi, doplnit
+
+ Proc bez hesla: Ucet je skryty pred uzivateli, slouzi pouze MSP adminstraci. + Heslo v config.json by bylo ulozene citelne. +
+
+ +
+ + +
+
+ 01 + Bloatware removal + OK +
+
+ + + + + + + +
AppX balicky – odstraneni pro vsechny uzivatele a provisionedRemove-AppxPackage -AllUsers + Remove-AppxProvisionedPackage
Zachovano: Microsoft.WindowsCalculatorZamerny vyjimek
Windows Capabilities (Fax, IE, OpenSSH, WMP, WordPad, …)Remove-WindowsCapability
Windows Optional Features (PS 2.0, MediaPlayback, Recall, …)Disable-WindowsOptionalFeature
Microsoft-RemoteDesktopConnection NESMI byt odstranenRDP klient musi zustat funkci. Overit ze neni v seznamu.
OneDrive nesmi byt odstranovano tadyOneDrive musi zustat instalovatelny pro M365.
+
+ +
+ + +
+
+ 02 + Software (winget) + TODO +
+
+ + + + + + + + +
7-Zip (7zip.7zip)OK
Adobe Acrobat Reader 64-bit (Adobe.Acrobat.Reader.64-bit)OK
OpenVPN Connect (OpenVPNTechnologies.OpenVPNConnect)OK
Seznam SW je neuplny – co dalsiho patri dovnitr?TODO: doplnit uplny seznam
Atera Agent installInvoke-WebRequest + msiexec /i /qn
Adobe PDF default: .pdf -> AcroRd32 po instalaciOK – UCPD stop/start kolem zápisu asociace
UCPD.sys (kernel driver, od Feb 2024) blokuje UserChoiceReseno: Stop-Service ucpd → HKCR zapis → Start-Service ucpd
+
+ Atera Agent URL:
+ https://x9.servicedesk.atera.com/api/utils/agent-install/windows/?cid=31&aeid=50b72e7113e54a63ac76b96c54c7e337 +
+
+ +
+ + +
+
+ 03 + System Registry (HKLM) + TODO +
+
+ + + + + + + + + + + + + +
Bypass NRO (OOBE\BypassNRO = 1)OK
Zakaz auto-instalace TeamsConfigureChatAutoInstall = 0
Zakaz Cloud Optimized ContentOK
Zakaz Widgets / News and InterestsOK
Hesla bez expirace (net accounts /maxpwage:UNLIMITED)OK
Casova zona: Central Europe Standard TimeOK
Zakaz GameDVROK
Edge – skryt First Run ExperienceHKLM\Policies\Edge\HideFirstRunExperience = 1
OneDrive uninstall (intentional)OneDriveSetup.exe /uninstall – odstrani pre-installed verzi. M365 si nainstaluje vlastni.
Edge policies – doplnit ~15 dalsich klicuViz seznam nize
Powercfg nastaveni (spotreba energie)Pridat: standby-ac 0, monitor-ac 60, standby-dc 30, monitor-dc 15
Proxy auto-detect zakaz (AutoDetect = 0)HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings
+
+ Edge policies k doplneni: + DefaultBrowserSettingEnabled = 0, NewTabPageContentEnabled = 0, + ImportOnEachLaunch = 0, ShowRecommendationsEnabled = 0, + PersonalizationReportingEnabled = 0, SpotlightExperiencesAndRecommendationsEnabled = 0, + DiagnosticData = 0, EdgeShoppingAssistantEnabled = 0, EdgeCollectionsEnabled = 0, + HubsSidebarEnabled = 0, ShowMicrosoftRewards = 0, SearchSuggestEnabled = 0 a dalsi. +
+
+ Powercfg prikazy:
+ powercfg /change standby-timeout-ac 0 (neusne na nabijeni)
+ powercfg /change monitor-timeout-ac 60 (monitor zhasne po 60 min)
+ powercfg /change standby-timeout-dc 30
+ powercfg /change monitor-timeout-dc 15 +
+
+ +
+ + +
+
+ 04 + Default Profile (NTUSER.DAT) + OK +
+
+ + + + + + + + + + + + + + + +
Taskbar: zarovnat vlevo (TaskbarAl = 0)Win11 default je center
Taskbar: skryt Search, Copilot, Task View, Widgets, ChatOK
Taskbar: zobrazit vsechny ikonky v tray (Scheduled task)ShowAllTrayIcons
Taskbar: vyprazdnit pinlist (TaskbarLayoutModification.xml)OK
Explorer: zobrazovat pripony souboru (HideFileExt = 0)OK
Explorer: otevrit na This PC (LaunchTo = 1)OK
Start menu: vyprazdnit piny (Win11)ConfigureStartPins = {"pinnedList":[]}
Start menu: zakaz Bing vyhledavaniDisableSearchBoxSuggestions = 1
Copilot: zakaz (TurnOffWindowsCopilot = 1)OK
NumLock zapnout pri startu (InitialKeyboardIndicators = 2)OK
Accent barva na titulnich listech (ColorPrevalence = 1)OK
OneDrive RunOnce klic je tady – smazatOpraveno – blok odstranen ze scriptu (brani reinstalaci pres M365)
Explorer: ShowRecent = 0, ShowFrequent = 0Skryt nedavne a caste soubory v Quick Access
Explorer: FullPath = 1 (CabinetState)Zobrazovat plnou cestu v titulku okna Explorera
+
+ Metoda: reg load HKU\DefaultProfile C:\Users\Default\NTUSER.DAT + → zapsat zmeny → reg unload HKU\DefaultProfile.
+ Tato operace musi probihat PRED prvnim prihlasenim uzivatele. + Aktualne prihlaseny uzivatel dostava zmeny pres primy zapis do HKCU. +
+
+ +
+ + +
+
+ 05 + Personalizace (barvy, tapeta) + OK +
+
+ + + + + + + +
System tema (taskbar, Start): DarkOK
Aplikacni tema: LightOK
Accent barva: #223B47 (tmave modroseda)OK
Accent barva na Start a taskbaru: anoOK
Pruhlednost: vypnutaOK
Tapeta: jednobarevna #223B47 (bez obrazku)BackInfo prepise tapetu svym BMP
+
+ BackInfo.exe (STEP 07) prepise tapetu BMP se systemovymi informacemi. + Jednobarevna tapeta je fallback pro pripad, ze BackInfo nedobehne nebo se nespusti. +
+
+ +
+ + +
+
+ 06 + Scheduled Tasks + OK +
+
+ + + + +
ShowAllTrayIcons – pri logonu + kazdou 1 minWin11 automaticky skryva tray ikony
UnlockStartLayout – jednou po aplikaci layoutuOdemkne Start menu pro uzivatelske zmeny
PDF-DefaultApp pri kazdem logonu – odstranenPDF asociace nastavena jednou v kroku 02 (UCPD stop/start). Task nebyl nutny.
+
+ +
+ + +
+
+ 07 + BackInfo (systemovy info na tapete) + Must fix +
+
+ + + + + + +
07-desktop-info.ps1 SMAZAT – stary pristupNahradit deploym. krokem pro BackInfo.exe
Zkopirovat assets/Backinfo/ do C:\Program Files\Backinfo\Pridat do master scriptu
Spustit backinfo_W11.ps1 (detekce OS, registry, Startup)Pridat do master scriptu
BackInfo.exe v assets/Backinfo/ k dispoziciHotovo – jen deploy krok chybi
BackInfo auto-start pri kazdem logonu via Startup shortcutZaridi backinfo_W11.ps1
+
+ BackInfo.ini konfiguruje: hostname (velky, centrovan), uzivatelske jmeno, + OS verze, HW info (CPU, RAM, disk), sitove informace (IP, hostname).

+ Proc BackInfo misto vlastniho PS: + BackInfo.exe podporuje Win10 i Win11 bez specialnich hacku, je stabilni a uz je v assets. +
+
+ +
+ + +
+
+ 08 + Windows aktivace + OK + Open +
+
+ + + + + + + +
OA3 BIOS/UEFI klic – kontrola embedded keyWMI: SoftwareLicensingService.OA3xOriginalProductKey
Klic z config.json (activation.productKey)OK – priorita nad OA3 a GVLK
Fallback na GVLK (KMS client key) dle edice OSOK
Volitelny KMS server (activation.kmsServer)OK
Preskocit pokud jiz aktivovanoOK
Typ klice: MAK vs KMS vs retail?Zavisi na klientovi – otevrena otazka
+
+ +
+ + + + + +
+
+ 09 + PC identita – Rename + C:\X9 + New +
+
+ + + + + +
Rename-Computer dle parametru z TUI nebo config.jsonFinalni krok pred restartem – PC name + popis
Nastavit popis pocitace (Computer Description)Via WMI nebo registry HKLM\SYSTEM\...\ComputerName
Vytvorit C:\X9\ adresarovou strukturuPro logy, skripty, assets
Vlastni ikonka pro C:\X9\ slozkuDesktop.ini + X9-ikona.ico
+
+ Rename-Computer vyzaduje restart. Tento krok musi byt posledni pred finalnim shrnutim. + Technik vi, ze po deployi nasleduje restart. +
+
+ +
+ + +
+
+ 10 + Network discovery + firewall + New +
+
+ + + + +
Nastavit sitovy profil jako Private (ne Public)Set-NetConnectionProfile -NetworkCategory Private
Povolit ping (ICMP) pro diagnostikuFirewall rule: Enable ICMPv4/ICMPv6
Zapnout Network Discovery pro Private profilnetsh advfirewall nebo Set-NetFirewallRule
+
+ Pozor: Sitovy profil (Private/Public) se muze zmenit po kazdem prihlaseni k jine siti. + Zvazit scheduled task pri logonu pro opakovanou korekci profilu. +
+
+ +
+ + +
+
+ --- + Taskbar pinned apps (profily) + New + Future +
+
+ + + + +
-ProfileType parametr: admin vs user variantaRuzna sada pinnutych appek dle role uzivatele
XML layout pro "admin": Explorer, PS, Edge, Notepad++, …TaskbarLayoutModification.xml
XML layout pro "user": Edge, Outlook, Teams, Explorer, …Odlisna sada pro bezneho zamestnance
+
+ Win11 24H2 zmenil zpusob aplikace Taskbar layoutu (ProvisionedLayoutModification.xml vs. starsi TaskbarLayoutModification.xml). + Nutno overit kompatibilitu s ruznymy buildy pred implementaci. +
+
+ +
+ + + + + +
+
+ Arc + xetup.exe – Go TUI launcher + Future +
+
+ + + + + + + + + +
Single binary (go:embed scripty + assets)Offline provoz, jedna stazitelna .exe
TUI form (huh/bubbletea): PC name, popis, product keyInteraktivni zadani dat technikem
Checklist kroku (on/off per-script) + ulozit do config.jsonOpakovatelne nasazeni u stejneho klienta
Live log output behem spousteni PS scriptuStdout z powershell.exe v realnem case
Finalni summary OK/ERRORNa konci nasazeni
Self-update: stahnout novou verzi z xetup.x9.czOverit hash pred spustenim
config.json: per-klient preset (prefix jmena PC, SW, klic)Lezi vedle .exe na USB klienta
OpenVPN soubor + doménovy join + domén. uzivatel pro profilRozsireni TUI formulare v budoucnu
+
+ Struktura: cmd/xetup/, internal/config/, + internal/spec/, internal/tui/, internal/runner/

+ Go zavislosti: + bubbletea (TUI framework), huh (forms), lipgloss (styling) +
+
+ +
+ + +
+
+ Arc + spec.yaml – single source of truth + Future +
+
+ + + + + +
Popis vsech kroku: id, label, script, defaultxetup.exe cte spec.yaml pro TUI checklist
Pole "requires" (napr. activation vyzaduje productKey)TUI upozorni pokud chybi
Auto-generovana dokumentace z spec.yamlCI akce: spec.yaml → tato stranka
spec.yaml jako SSOT pro tuto stranku i deploy skriptyIdealni stav: stranka vzdy odpovida kodu
+
+ Navrh struktury spec.yaml:
+ steps: + - id: admin-account + label: "Admin account (adminx9)" + script: 00-admin-account.ps1 + default: true + - id: activation + label: "Windows activation" + script: 08-activation.ps1 + default: true + requires: [productKey] +
+
+ +
+ +
+
+ + + + + + diff --git a/web/x9-logo.jpeg b/web/x9-logo.jpeg new file mode 100644 index 0000000..80b35e9 Binary files /dev/null and b/web/x9-logo.jpeg differ