1	<#
2	.SYNOPSIS
3	    Creates the adminx9 local administrator account for MSP use.
4
5	.DESCRIPTION
6	    Creates a hidden local administrator account 'adminx9' used by X9.cz technicians
7	    for remote management and on-site administration. The account has no password by
8	    design - it is invisible to regular users and only accessible to technicians who
9	    know it exists. FullName is set to "X9.cz s.r.o." so it is identifiable in
10	    system tools. Password policy is set so it never expires.
11
12	.ITEMS
13	    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.
14	    pridat-do-skupiny-administrators: Adds adminx9 to the local Administrators group via net localgroup. Required for full system management rights.
15	    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.
16	    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.
17	    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.
18	    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.
19	#>
20	param(
21	    [object]$Config,
22	    [string]$LogFile
23	)
24
25	$ErrorActionPreference = "Continue"
26
27	function Write-Log {
28	    param([string]$Message, [string]$Level = "INFO")
29	    $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
30	    Add-Content -Path $LogFile -Value $line -Encoding UTF8
31	}
32
33	# -----------------------------------------------------------------------
34	# Read account config
35	# -----------------------------------------------------------------------
36	$accountName = "adminx9"
37	$accountPass = "AdminX9.AdminX9"
38	$accountDesc = "X9 MSP admin account"
39
40	if ($Config -and $Config.adminAccount) {
41	    if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
42	    if ($Config.adminAccount.password) { $accountPass = $Config.adminAccount.password }
43	    if ($Config.adminAccount.description) { $accountDesc = $Config.adminAccount.description }
44	}
45
46	Write-Log "Creating admin account: $accountName" -Level INFO
47
48	$securePass = ConvertTo-SecureString $accountPass -AsPlainText -Force
49
50	# -----------------------------------------------------------------------
51	# Create or update account
52	# -----------------------------------------------------------------------
53	$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue
54
55	if ($existing) {
56	    Write-Log "  Account already exists - updating password" -Level INFO
57	    try {
58	        Set-LocalUser -Name $accountName -Password $securePass -PasswordNeverExpires $true
59	        Enable-LocalUser -Name $accountName
60	        Write-Log "  Account updated: $accountName" -Level OK

<#
.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
)

$ErrorActionPreference = "Continue"

function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
    Add-Content -Path $LogFile -Value $line -Encoding UTF8
}

# -----------------------------------------------------------------------
# Read account config
# -----------------------------------------------------------------------
$accountName = "adminx9"
$accountPass = "AdminX9.AdminX9"
$accountDesc = "X9 MSP admin account"

if ($Config -and $Config.adminAccount) {
    if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
    if ($Config.adminAccount.password) { $accountPass = $Config.adminAccount.password }
    if ($Config.adminAccount.description) { $accountDesc = $Config.adminAccount.description }
}

Write-Log "Creating admin account: $accountName" -Level INFO

$securePass = ConvertTo-SecureString $accountPass -AsPlainText -Force

# -----------------------------------------------------------------------
# Create or update account
# -----------------------------------------------------------------------
$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue

if ($existing) {
    Write-Log "  Account already exists - updating password" -Level INFO
    try {
        Set-LocalUser -Name $accountName -Password $securePass -PasswordNeverExpires $true
        Enable-LocalUser -Name $accountName
        Write-Log "  Account updated: $accountName" -Level OK


60	        Write-Log "  Account updated: $accountName" -Level OK
61	    }
62	    catch {
63	        Write-Log "  Failed to update account: $_" -Level ERROR
64	    }
65	} else {
66	    try {
67	        New-LocalUser -Name $accountName `
68	                      -Password $securePass `
69	                      -Description $accountDesc `
70	                      -PasswordNeverExpires `
71	                      -UserMayNotChangePassword `
72	                      -ErrorAction Stop | Out-Null
73	        Write-Log "  Account created: $accountName" -Level OK
74	    }
75	    catch {
76	        Write-Log "  Failed to create account: $_" -Level ERROR
77	    }
78	}
79
80	# -----------------------------------------------------------------------
81	# Add to Administrators group
82	# -----------------------------------------------------------------------
83	try {
84	    $adminsGroup = (Get-LocalGroup | Where-Object { $_.SID -eq "S-1-5-32-544" }).Name
85	    $members = Get-LocalGroupMember -Group $adminsGroup -ErrorAction SilentlyContinue |
86	               Where-Object { $_.Name -like "*$accountName" }
87	    if (-not $members) {
88	        Add-LocalGroupMember -Group $adminsGroup -Member $accountName -ErrorAction Stop
89	        Write-Log "  Added to $adminsGroup" -Level OK
90	    } else {
91	        Write-Log "  Already in $adminsGroup" -Level INFO
92	    }
93	}
94	catch {
95	    Write-Log "  Failed to add to Administrators: $_" -Level ERROR
96	}
97
98	# -----------------------------------------------------------------------
99	# Hide account from login screen
100	# -----------------------------------------------------------------------
101	try {
102	    $specialPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList"
103	    if (-not (Test-Path $specialPath)) {
104	        New-Item -Path $specialPath -Force | Out-Null
105	    }
106	    Set-ItemProperty -Path $specialPath -Name $accountName -Value 0 -Type DWord -Force
107	    Write-Log "  Account hidden from login screen" -Level OK
108	}
109	catch {
110	    Write-Log "  Failed to hide account from login screen: $_" -Level ERROR
111	}
112
113	Write-Log "Step 0a - Admin account complete" -Level OK
114

        Write-Log "  Account updated: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to update account: $_" -Level ERROR
    }
} else {
    try {
        New-LocalUser -Name $accountName `
                      -Password $securePass `
                      -Description $accountDesc `
                      -PasswordNeverExpires `
                      -UserMayNotChangePassword `
                      -ErrorAction Stop | Out-Null
        Write-Log "  Account created: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to create account: $_" -Level ERROR
    }
}

# -----------------------------------------------------------------------
# Add to Administrators group
# -----------------------------------------------------------------------
try {
    $adminsGroup = (Get-LocalGroup | Where-Object { $_.SID -eq "S-1-5-32-544" }).Name
    $members = Get-LocalGroupMember -Group $adminsGroup -ErrorAction SilentlyContinue |
               Where-Object { $_.Name -like "*$accountName" }
    if (-not $members) {
        Add-LocalGroupMember -Group $adminsGroup -Member $accountName -ErrorAction Stop
        Write-Log "  Added to $adminsGroup" -Level OK
    } else {
        Write-Log "  Already in $adminsGroup" -Level INFO
    }
}
catch {
    Write-Log "  Failed to add to Administrators: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# Hide account from login screen
# -----------------------------------------------------------------------
try {
    $specialPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList"
    if (-not (Test-Path $specialPath)) {
        New-Item -Path $specialPath -Force | Out-Null
    }
    Set-ItemProperty -Path $specialPath -Name $accountName -Value 0 -Type DWord -Force
    Write-Log "  Account hidden from login screen" -Level OK
}
catch {
    Write-Log "  Failed to hide account from login screen: $_" -Level ERROR
}

Write-Log "Step 0a - Admin account complete" -Level OK


Zapiš si, že zpracování připomínek musí být per řádek ... a doplnil jsem edge: EDGE:
Panel oblíbených položek: Vždy zobrazit
Zapnout tlačítka: Historie, Aplikace, Stažené soubory, Výkon
Vypnout tlačítka: Domovská stránka, Kolekce, Rozdělená obrazovka, VPN, Drop, Snímek obrazovky, Sdílet, Zpětná vazba
Výchozí vyhledávač: Google, Ostatní vyhledávače odstranit


Mám jasný obrázek. Teď implementuji vše najednou:

**Zbývající mustfix:**
1. `00-admin-account.ps1` — stále má hardcoded heslo + chybí FullName přes ADSI
2. `07-desktop-info.ps1` — nahradit BackInfo deploymentem

Začínám:


Edit

# -----------------------------------------------------------------------
# Read account config
# -----------------------------------------------------------------------
$accountName = "adminx9"
$accountPass = "AdminX9.AdminX9"
$accountDesc = "X9 MSP admin account"

if ($Config -and $Config.adminAccount) {
    if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
    if ($Config.adminAccount.password) { $accountPass = $Config.adminAccount.password }
    if ($Config.adminAccount.description) { $accountDesc = $Config.adminAccount.description }
}

Write-Log "Creating admin account: $accountName" -Level INFO

$securePass = ConvertTo-SecureString $accountPass -AsPlainText -Force

# -----------------------------------------------------------------------
# Create or update account
# -----------------------------------------------------------------------
$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue

if ($existing) {
    Write-Log "  Account already exists - updating password" -Level INFO
    try {
        Set-LocalUser -Name $accountName -Password $securePass -PasswordNeverExpires $true
        Enable-LocalUser -Name $accountName
        Write-Log "  Account updated: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to update account: $_" -Level ERROR
    }
} else {
    try {
        New-LocalUser -Name $accountName `
                      -Password $securePass `
                      -Description $accountDesc `
                      -PasswordNeverExpires `
                      -UserMayNotChangePassword `
                      -ErrorAction Stop | Out-Null
        Write-Log "  Account created: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to create account: $_" -Level ERROR
    }
}

# -----------------------------------------------------------------------
# Account config - no password by design
# -----------------------------------------------------------------------
$accountName = "adminx9"
$accountDesc = "X9 MSP admin account"
$accountFullName = "X9.cz s.r.o."

if ($Config -and $Config.adminAccount) {
    if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
}

Write-Log "Creating admin account: $accountName" -Level INFO

# Empty password - account is hidden from login screen, no password needed
$emptyPass = [System.Security.SecureString]::new()

# -----------------------------------------------------------------------
# Create or update account
# -----------------------------------------------------------------------
$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue

if ($existing) {
    Write-Log "  Account already exists - clearing password" -Level INFO
    try {
        Set-LocalUser -Name $accountName -Password $emptyPass -PasswordNeverExpires $true
        Enable-LocalUser -Name $accountName
        Write-Log "  Account updated: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to update account: $_" -Level ERROR
    }
} else {
    try {
        New-LocalUser -Name $accountName `
                      -Password $emptyPass `
                      -Description $accountDesc `
                      -PasswordNeverExpires `
                      -UserMayNotChangePassword `
                      -ErrorAction Stop | Out-Null
        Write-Log "  Account created: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to create account: $_" -Level ERROR
    }
}

# -----------------------------------------------------------------------
# Set FullName via ADSI
# -----------------------------------------------------------------------
try {
    $adsiUser = [ADSI]"WinNT://./$accountName,user"
    $adsiUser.FullName = $accountFullName
    $adsiUser.SetInfo()
    Write-Log "  FullName set to: $accountFullName" -Level OK
}
catch {
    Write-Log "  Failed to set FullName: $_" -Level ERROR
}


The file /opt/xetup/scripts/00-admin-account.ps1 has been updated successfully.

# -----------------------------------------------------------------------
# Account config - no password by design
# -----------------------------------------------------------------------
$accountName = "adminx9"
$accountDesc = "X9 MSP admin account"
$accountFullName = "X9.cz s.r.o."

if ($Config -and $Config.adminAccount) {
    if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
}

Write-Log "Creating admin account: $accountName" -Level INFO

# Empty password - account is hidden from login screen, no password needed
$emptyPass = [System.Security.SecureString]::new()

# -----------------------------------------------------------------------
# Create or update account
# -----------------------------------------------------------------------
$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue

if ($existing) {
    Write-Log "  Account already exists - clearing password" -Level INFO
    try {
        Set-LocalUser -Name $accountName -Password $emptyPass -PasswordNeverExpires $true
        Enable-LocalUser -Name $accountName
        Write-Log "  Account updated: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to update account: $_" -Level ERROR
    }
} else {
    try {
        New-LocalUser -Name $accountName `
                      -Password $emptyPass `
                      -Description $accountDesc `
                      -PasswordNeverExpires `
                      -UserMayNotChangePassword `
                      -ErrorAction Stop | Out-Null
        Write-Log "  Account created: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to create account: $_" -Level ERROR
    }
}

# -----------------------------------------------------------------------
# Set FullName via ADSI
# -----------------------------------------------------------------------
try {
    $adsiUser = [ADSI]"WinNT://./$accountName,user"
    $adsiUser.FullName = $accountFullName
    $adsiUser.SetInfo()
    Write-Log "  FullName set to: $accountFullName" -Level OK
}
catch {
    Write-Log "  Failed to set FullName: $_" -Level ERROR
}

<#
.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
)

$ErrorActionPreference = "Continue"

function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
    Add-Content -Path $LogFile -Value $line -Encoding UTF8
}

# -----------------------------------------------------------------------
# Read account config
# -----------------------------------------------------------------------
$accountName = "adminx9"
$accountPass = "AdminX9.AdminX9"
$accountDesc = "X9 MSP admin account"

if ($Config -and $Config.adminAccount) {
    if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
    if ($Config.adminAccount.password) { $accountPass = $Config.adminAccount.password }
    if ($Config.adminAccount.description) { $accountDesc = $Config.adminAccount.description }
}

Write-Log "Creating admin account: $accountName" -Level INFO

$securePass = ConvertTo-SecureString $accountPass -AsPlainText -Force

# -----------------------------------------------------------------------
# Create or update account
# -----------------------------------------------------------------------
$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue

if ($existing) {
    Write-Log "  Account already exists - updating password" -Level INFO
    try {
        Set-LocalUser -Name $accountName -Password $securePass -PasswordNeverExpires $true
        Enable-LocalUser -Name $accountName
        Write-Log "  Account updated: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to update account: $_" -Level ERROR
    }
} else {
    try {
        New-LocalUser -Name $accountName `
                      -Password $securePass `
                      -Description $accountDesc `
                      -PasswordNeverExpires `
                      -UserMayNotChangePassword `
                      -ErrorAction Stop | Out-Null
        Write-Log "  Account created: $accountName" -Level OK
    }
    catch {
        Write-Log "  Failed to create account: $_" -Level ERROR
    }
}

# -----------------------------------------------------------------------
# Add to Administrators group
# -----------------------------------------------------------------------
try {
    $adminsGroup = (Get-LocalGroup | Where-Object { $_.SID -eq "S-1-5-32-544" }).Name
    $members = Get-LocalGroupMember -Group $adminsGroup -ErrorAction SilentlyContinue |
               Where-Object { $_.Name -like "*$accountName" }
    if (-not $members) {
        Add-LocalGroupMember -Group $adminsGroup -Member $accountName -ErrorAction Stop
        Write-Log "  Added to $adminsGroup" -Level OK
    } else {
        Write-Log "  Already in $adminsGroup" -Level INFO
    }
}
catch {
    Write-Log "  Failed to add to Administrators: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# Hide account from login screen
# -----------------------------------------------------------------------
try {
    $specialPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList"
    if (-not (Test-Path $specialPath)) {
        New-Item -Path $specialPath -Force | Out-Null
    }
    Set-ItemProperty -Path $specialPath -Name $accountName -Value 0 -Type DWord -Force
    Write-Log "  Account hidden from login screen" -Level OK
}
catch {
    Write-Log "  Failed to hide account from login screen: $_" -Level ERROR
}

Write-Log "Step 0a - Admin account complete" -Level OK

+# Account config - no password by design

-    if ($Config.adminAccount.password) { $accountPass = $Config.adminAccount.password }

-    if ($Config.adminAccount.description) { $accountDesc = $Config.adminAccount.description }

-$securePass = ConvertTo-SecureString $accountPass -AsPlainText -Force

+# Empty password - account is hidden from login screen, no password needed

-    Write-Log "  Account already exists - updating password" -Level INFO

+    Write-Log "  Account already exists - clearing password" -Level INFO

-        Set-LocalUser -Name $accountName -Password $securePass -PasswordNeverExpires $true

+        Set-LocalUser -Name $accountName -Password $emptyPass -PasswordNeverExpires $true

-                      -Password $securePass `

+                      -Password $emptyPass `

+    $adsiUser = [ADSI]"WinNT://./$accountName,user"

+    $adsiUser.FullName = $accountFullName

+    Write-Log "  FullName set to: $accountFullName" -Level OK

+    Write-Log "  Failed to set FullName: $_" -Level ERROR


Prompt:
Zapiš si, že zpracování připomínek musí být per řádek ... a doplnil jsem edge: EDGE:
Panel oblíbených položek: Vždy zobrazit
Zapnout tlačítka: Historie, Aplikace, Stažené soubory, Výkon
Vypnout tlačítka: Domovská stránka, Kolekce, Rozdělená obrazovka, VPN, Drop, Snímek obrazovky, Sdílet, Zpětná vazba
Výchozí vyhledávač: Google, Ostatní vyhledávače odstranit


Teď vytvořím nový `07-backinfo.ps1` (nahradí starý desktop-info):


Bash

cat /opt/xetup/Deploy-Windows.ps1 | grep -n "07\|desktop\|backinfo\|BackInfo" -i | head -20

Check how Deploy-Windows.ps1 references step 07


110:    desktopInfo     = $true
203:# Step 7 - DesktopInfo
205:if ($stepsEnabled['desktopInfo']) {
206:    Invoke-Step -Name "Step 7 - DesktopInfo" -Action {
207:        & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile
209:} else { Skip-Step "Step 7 - DesktopInfo" }


Write

<#
.SYNOPSIS
    Deploys BackInfo.exe to C:\Program Files\Backinfo\ and configures auto-start.

.DESCRIPTION
    Copies the BackInfo folder from assets to Program Files, writes the OS name
    to the registry (HKLM\SOFTWARE\BackInfo\OSName) so BackInfo can display it,
    and creates a Startup shortcut so BackInfo launches on every user logon.
    BackInfo renders a BMP wallpaper overlay with hostname, username, OS, HW info,
    and network info - configured via BackInfo.ini.

.ITEMS
    kopirovat-assets-backinfo-do-program-fil: Copies all files from assets\Backinfo\ to C:\Program Files\Backinfo\. Includes BackInfo.exe, BackInfo.ini, and backinfo_W11.ps1. Creates the target directory if it does not exist.
    registry-osname-hklm-software-backinfo: Detects Windows build number and edition, writes OSName string to HKLM\SOFTWARE\BackInfo\OSName (and WOW6432Node). BackInfo.ini references %OSName% to display the correct OS on the wallpaper.
    startup-shortcut-backinfo-exe: Creates a shortcut at C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\BackInfo.lnk pointing to C:\Program Files\Backinfo\BackInfo.exe. Ensures BackInfo starts for every user on logon.
    07-desktop-info-ps1-smazat-nahrazeno: 07-desktop-info.ps1 is superseded by this script. BackInfo.exe is the preferred approach - stable on Win10 and Win11, configurable via INI, already present in assets.
#>
param(
    [object]$Config,
    [string]$LogFile
)

$ErrorActionPreference = "Continue"

function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
    Add-Content -Path $LogFile -Value $line -Encoding UTF8
}

# -----------------------------------------------------------------------
# Copy BackInfo assets to Program Files
# -----------------------------------------------------------------------
$assetsBackinfo = Join-Path $PSScriptRoot "..\assets\Backinfo"
$destBackinfo   = "C:\Program Files\Backinfo"

Write-Log "Deploying BackInfo to $destBackinfo" -Level INFO

if (-not (Test-Path $assetsBackinfo)) {
    Write-Log "  Assets not found: $assetsBackinfo" -Level ERROR
    exit 1
}

try {
    if (-not (Test-Path $destBackinfo)) {
        New-Item -ItemType Directory -Path $destBackinfo -Force | Out-Null
    }
    Copy-Item -Path "$assetsBackinfo\*" -Destination $destBackinfo -Recurse -Force
    Write-Log "  Copied BackInfo assets to $destBackinfo" -Level OK
}
catch {
    Write-Log "  Failed to copy BackInfo assets: $_" -Level ERROR
    exit 1
}

# -----------------------------------------------------------------------
# Detect OS name and write to registry (BackInfo reads this via %OSName%)
# -----------------------------------------------------------------------
Write-Log "Detecting OS for BackInfo registry" -Level INFO

try {
    $cvPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
    $cv     = Get-ItemProperty -Path $cvPath
    $build  = [int]$cv.CurrentBuild

    $osBase = if ($build -ge 22000) { "Windows 11" } else { "Windows 10" }

    $edition = switch ($cv.EditionID) {
        "Professional"  { "Pro" }
        "ProfessionalN" { "Pro N" }
        "Core"          { "Home" }
        "CoreN"         { "Home N" }
        "Enterprise"    { "Enterprise" }
        "Education"     { "Education" }
        default         { $cv.EditionID }
    }

    $osName = "$osBase $edition"

    foreach ($regPath in @("HKLM:\SOFTWARE\BackInfo", "HKLM:\SOFTWARE\WOW6432Node\BackInfo")) {
        if (-not (Test-Path $regPath)) {
            New-Item -Path $regPath -Force | Out-Null
        }
        Set-ItemProperty -Path $regPath -Name "OSName" -Value $osName -Type String -Force
    }
    Write-Log "  OSName set to: $osName" -Level OK
}
catch {
    Write-Log "  Failed to set BackInfo registry: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# Create Startup shortcut for all users
# -----------------------------------------------------------------------
Write-Log "Creating BackInfo startup shortcut" -Level INFO

try {
    $backInfoExe  = "$destBackinfo\BackInfo.exe"
    $shortcutPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\BackInfo.lnk"

    $wsh      = New-Object -ComObject WScript.Shell
    $shortcut = $wsh.CreateShortcut($shortcutPath)
    $shortcut.TargetPath  = $backInfoExe
    $shortcut.WorkingDirectory = $destBackinfo
    $shortcut.Description = "BackInfo system info wallpaper"
    $shortcut.Save()

    Write-Log "  Startup shortcut created: $shortcutPath" -Level OK
}
catch {
    Write-Log "  Failed to create startup shortcut: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# Launch BackInfo now to render initial wallpaper
# -----------------------------------------------------------------------
Write-Log "Launching BackInfo for initial render" -Level INFO
try {
    Start-Process -FilePath "$destBackinfo\BackInfo.exe" -ErrorAction Stop
    Write-Log "  BackInfo launched" -Level OK
}
catch {
    Write-Log "  BackInfo launch failed (non-fatal): $_" -Level WARN
}

Write-Log "Step 7 complete" -Level OK


File created successfully at: /opt/xetup/scripts/07-backinfo.ps1

<#
.SYNOPSIS
    Deploys BackInfo.exe to C:\Program Files\Backinfo\ and configures auto-start.

.DESCRIPTION
    Copies the BackInfo folder from assets to Program Files, writes the OS name
    to the registry (HKLM\SOFTWARE\BackInfo\OSName) so BackInfo can display it,
    and creates a Startup shortcut so BackInfo launches on every user logon.
    BackInfo renders a BMP wallpaper overlay with hostname, username, OS, HW info,
    and network info - configured via BackInfo.ini.

.ITEMS
    kopirovat-assets-backinfo-do-program-fil: Copies all files from assets\Backinfo\ to C:\Program Files\Backinfo\. Includes BackInfo.exe, BackInfo.ini, and backinfo_W11.ps1. Creates the target directory if it does not exist.
    registry-osname-hklm-software-backinfo: Detects Windows build number and edition, writes OSName string to HKLM\SOFTWARE\BackInfo\OSName (and WOW6432Node). BackInfo.ini references %OSName% to display the correct OS on the wallpaper.
    startup-shortcut-backinfo-exe: Creates a shortcut at C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\BackInfo.lnk pointing to C:\Program Files\Backinfo\BackInfo.exe. Ensures BackInfo starts for every user on logon.
    07-desktop-info-ps1-smazat-nahrazeno: 07-desktop-info.ps1 is superseded by this script. BackInfo.exe is the preferred approach - stable on Win10 and Win11, configurable via INI, already present in assets.
#>
param(
    [object]$Config,
    [string]$LogFile
)

$ErrorActionPreference = "Continue"

function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
    Add-Content -Path $LogFile -Value $line -Encoding UTF8
}

# -----------------------------------------------------------------------
# Copy BackInfo assets to Program Files
# -----------------------------------------------------------------------
$assetsBackinfo = Join-Path $PSScriptRoot "..\assets\Backinfo"
$destBackinfo   = "C:\Program Files\Backinfo"

Write-Log "Deploying BackInfo to $destBackinfo" -Level INFO

if (-not (Test-Path $assetsBackinfo)) {
    Write-Log "  Assets not found: $assetsBackinfo" -Level ERROR
    exit 1
}

try {
    if (-not (Test-Path $destBackinfo)) {
        New-Item -ItemType Directory -Path $destBackinfo -Force | Out-Null
    }
    Copy-Item -Path "$assetsBackinfo\*" -Destination $destBackinfo -Recurse -Force
    Write-Log "  Copied BackInfo assets to $destBackinfo" -Level OK
}
catch {
    Write-Log "  Failed to copy BackInfo assets: $_" -Level ERROR
    exit 1
}

# -----------------------------------------------------------------------
# Detect OS name and write to registry (BackInfo reads this via %OSName%)
# -----------------------------------------------------------------------
Write-Log "Detecting OS for BackInfo registry" -Level INFO

try {
    $cvPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
    $cv     = Get-ItemProperty -Path $cvPath
    $build  = [int]$cv.CurrentBuild

    $osBase = if ($build -ge 22000) { "Windows 11" } else { "Windows 10" }

    $edition = switch ($cv.EditionID) {
        "Professional"  { "Pro" }
        "ProfessionalN" { "Pro N" }
        "Core"          { "Home" }
        "CoreN"         { "Home N" }
        "Enterprise"    { "Enterprise" }
        "Education"     { "Education" }
        default         { $cv.EditionID }
    }

    $osName = "$osBase $edition"

    foreach ($regPath in @("HKLM:\SOFTWARE\BackInfo", "HKLM:\SOFTWARE\WOW6432Node\BackInfo")) {
        if (-not (Test-Path $regPath)) {
            New-Item -Path $regPath -Force | Out-Null
        }
        Set-ItemProperty -Path $regPath -Name "OSName" -Value $osName -Type String -Force
    }
    Write-Log "  OSName set to: $osName" -Level OK
}
catch {
    Write-Log "  Failed to set BackInfo registry: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# Create Startup shortcut for all users
# -----------------------------------------------------------------------
Write-Log "Creating BackInfo startup shortcut" -Level INFO

try {
    $backInfoExe  = "$destBackinfo\BackInfo.exe"
    $shortcutPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\BackInfo.lnk"

    $wsh      = New-Object -ComObject WScript.Shell
    $shortcut = $wsh.CreateShortcut($shortcutPath)
    $shortcut.TargetPath  = $backInfoExe
    $shortcut.WorkingDirectory = $destBackinfo
    $shortcut.Description = "BackInfo system info wallpaper"
    $shortcut.Save()

    Write-Log "  Startup shortcut created: $shortcutPath" -Level OK
}
catch {
    Write-Log "  Failed to create startup shortcut: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# Launch BackInfo now to render initial wallpaper
# -----------------------------------------------------------------------
Write-Log "Launching BackInfo for initial render" -Level INFO
try {
    Start-Process -FilePath "$destBackinfo\BackInfo.exe" -ErrorAction Stop
    Write-Log "  BackInfo launched" -Level OK
}
catch {
    Write-Log "  BackInfo launch failed (non-fatal): $_" -Level WARN
}

Write-Log "Step 7 complete" -Level OK


Teď aktualizuji Deploy-Windows.ps1 aby volal nový skript:


100	# Build step enable/disable map from config + CLI overrides
101	# -----------------------------------------------------------------------
102	$stepsEnabled = @{
103	    adminAccount    = $true
104	    bloatware       = $true
105	    software        = $true
106	    systemRegistry  = $true
107	    defaultProfile  = $true
108	    personalization = $true
109	    scheduledTasks  = $true
110	    desktopInfo     = $true
111	    activation      = $true
112	}
113	if ($Config -and $Config.steps) {
114	    foreach ($key in @($stepsEnabled.Keys)) {
115	        $val = $Config.steps.$key
116	        if ($null -ne $val) { $stepsEnabled[$key] = [bool]$val }
117	    }
118	}
119	# CLI switches override config.steps
120	if ($SkipBloatware)      { $stepsEnabled['bloatware']      = $false }
121	if ($SkipSoftware)       { $stepsEnabled['software']       = $false }
122	if ($SkipDefaultProfile) { $stepsEnabled['defaultProfile'] = $false }
123
124	function Skip-Step {
125	    param([string]$Name)
126	    Write-Log "$Name - SKIPPED (disabled in config)" -Level WARN
127	    $StepResults.Add(@{ Name = $Name; Status = "SKIPPED" })
128	}
129
130	# -----------------------------------------------------------------------
131	# Step 0a - Admin account
132	# -----------------------------------------------------------------------
133	if ($stepsEnabled['adminAccount']) {
134	    Invoke-Step -Name "Step 0a - Admin account" -Action {
135	        & "$ScriptRoot\scripts\00-admin-account.ps1" -Config $Config -LogFile $LogFile
136	    }
137	} else { Skip-Step "Step 0a - Admin account" }
138
139	# -----------------------------------------------------------------------
140	# Step 0b - Windows activation
141	# -----------------------------------------------------------------------
142	if ($stepsEnabled['activation']) {
143	    Invoke-Step -Name "Step 0b - Windows activation" -Action {
144	        & "$ScriptRoot\scripts\08-activation.ps1" -Config $Config -LogFile $LogFile
145	    }
146	} else { Skip-Step "Step 0b - Windows activation" }
147
148	# -----------------------------------------------------------------------
149	# Step 1 - Bloatware removal
150	# -----------------------------------------------------------------------
151	if ($stepsEnabled['bloatware']) {
152	    Invoke-Step -Name "Step 1 - Bloatware removal" -Action {
153	        & "$ScriptRoot\scripts\01-bloatware.ps1" -Config $Config -LogFile $LogFile
154	    }
155	} else { Skip-Step "Step 1 - Bloatware removal" }
156
157	# -----------------------------------------------------------------------
158	# Step 2 - Software installation
159	# -----------------------------------------------------------------------
160	if ($stepsEnabled['software']) {
161	    Invoke-Step -Name "Step 2 - Software installation" -Action {
162	        & "$ScriptRoot\scripts\02-software.ps1" -Config $Config -LogFile $LogFile
163	    }
164	} else { Skip-Step "Step 2 - Software installation" }
165
166	# -----------------------------------------------------------------------
167	# Step 3 - System registry (HKLM)
168	# -----------------------------------------------------------------------
169	if ($stepsEnabled['systemRegistry']) {
170	    Invoke-Step -Name "Step 3 - System registry" -Action {
171	        & "$ScriptRoot\scripts\03-system-registry.ps1" -Config $Config -LogFile $LogFile
172	    }
173	} else { Skip-Step "Step 3 - System registry" }
174
175	# -----------------------------------------------------------------------
176	# Step 4 - Default profile (NTUSER.DAT)
177	# -----------------------------------------------------------------------
178	if ($stepsEnabled['defaultProfile']) {
179	    Invoke-Step -Name "Step 4 - Default profile" -Action {
180	        & "$ScriptRoot\scripts\04-default-profile.ps1" -Config $Config -LogFile $LogFile
181	    }
182	} else { Skip-Step "Step 4 - Default profile" }
183
184	# -----------------------------------------------------------------------
185	# Step 5 - Personalization
186	# -----------------------------------------------------------------------
187	if ($stepsEnabled['personalization']) {
188	    Invoke-Step -Name "Step 5 - Personalization" -Action {
189	        & "$ScriptRoot\scripts\05-personalization.ps1" -Config $Config -LogFile $LogFile
190	    }
191	} else { Skip-Step "Step 5 - Personalization" }
192
193	# -----------------------------------------------------------------------
194	# Step 6 - Scheduled tasks
195	# -----------------------------------------------------------------------
196	if ($stepsEnabled['scheduledTasks']) {
197	    Invoke-Step -Name "Step 6 - Scheduled tasks" -Action {
198	        & "$ScriptRoot\scripts\06-scheduled-tasks.ps1" -Config $Config -LogFile $LogFile
199	    }
200	} else { Skip-Step "Step 6 - Scheduled tasks" }
201
202	# -----------------------------------------------------------------------
203	# Step 7 - DesktopInfo
204	# -----------------------------------------------------------------------
205	if ($stepsEnabled['desktopInfo']) {
206	    Invoke-Step -Name "Step 7 - DesktopInfo" -Action {
207	        & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile
208	    }
209	} else { Skip-Step "Step 7 - DesktopInfo" }
210
211	# -----------------------------------------------------------------------
212	# Summary
213	# -----------------------------------------------------------------------
214	Write-Log "========================================" -Level INFO
215	Write-Log "SUMMARY" -Level INFO
216	Write-Log "========================================" -Level INFO
217
218	$countOK      = ($StepResults | Where-Object { $_.Status -eq "OK"      }).Count
219	$countError   = ($StepResults | Where-Object { $_.Status -eq "ERROR"   }).Count

# Build step enable/disable map from config + CLI overrides
# -----------------------------------------------------------------------
$stepsEnabled = @{
    adminAccount    = $true
    bloatware       = $true
    software        = $true
    systemRegistry  = $true
    defaultProfile  = $true
    personalization = $true
    scheduledTasks  = $true
    desktopInfo     = $true
    activation      = $true
}
if ($Config -and $Config.steps) {
    foreach ($key in @($stepsEnabled.Keys)) {
        $val = $Config.steps.$key
        if ($null -ne $val) { $stepsEnabled[$key] = [bool]$val }
    }
}
# CLI switches override config.steps
if ($SkipBloatware)      { $stepsEnabled['bloatware']      = $false }
if ($SkipSoftware)       { $stepsEnabled['software']       = $false }
if ($SkipDefaultProfile) { $stepsEnabled['defaultProfile'] = $false }

function Skip-Step {
    param([string]$Name)
    Write-Log "$Name - SKIPPED (disabled in config)" -Level WARN
    $StepResults.Add(@{ Name = $Name; Status = "SKIPPED" })
}

# -----------------------------------------------------------------------
# Step 0a - Admin account
# -----------------------------------------------------------------------
if ($stepsEnabled['adminAccount']) {
    Invoke-Step -Name "Step 0a - Admin account" -Action {
        & "$ScriptRoot\scripts\00-admin-account.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 0a - Admin account" }

# -----------------------------------------------------------------------
# Step 0b - Windows activation
# -----------------------------------------------------------------------
if ($stepsEnabled['activation']) {
    Invoke-Step -Name "Step 0b - Windows activation" -Action {
        & "$ScriptRoot\scripts\08-activation.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 0b - Windows activation" }

# -----------------------------------------------------------------------
# Step 1 - Bloatware removal
# -----------------------------------------------------------------------
if ($stepsEnabled['bloatware']) {
    Invoke-Step -Name "Step 1 - Bloatware removal" -Action {
        & "$ScriptRoot\scripts\01-bloatware.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 1 - Bloatware removal" }

# -----------------------------------------------------------------------
# Step 2 - Software installation
# -----------------------------------------------------------------------
if ($stepsEnabled['software']) {
    Invoke-Step -Name "Step 2 - Software installation" -Action {
        & "$ScriptRoot\scripts\02-software.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 2 - Software installation" }

# -----------------------------------------------------------------------
# Step 3 - System registry (HKLM)
# -----------------------------------------------------------------------
if ($stepsEnabled['systemRegistry']) {
    Invoke-Step -Name "Step 3 - System registry" -Action {
        & "$ScriptRoot\scripts\03-system-registry.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 3 - System registry" }

# -----------------------------------------------------------------------
# Step 4 - Default profile (NTUSER.DAT)
# -----------------------------------------------------------------------
if ($stepsEnabled['defaultProfile']) {
    Invoke-Step -Name "Step 4 - Default profile" -Action {
        & "$ScriptRoot\scripts\04-default-profile.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 4 - Default profile" }

# -----------------------------------------------------------------------
# Step 5 - Personalization
# -----------------------------------------------------------------------
if ($stepsEnabled['personalization']) {
    Invoke-Step -Name "Step 5 - Personalization" -Action {
        & "$ScriptRoot\scripts\05-personalization.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 5 - Personalization" }

# -----------------------------------------------------------------------
# Step 6 - Scheduled tasks
# -----------------------------------------------------------------------
if ($stepsEnabled['scheduledTasks']) {
    Invoke-Step -Name "Step 6 - Scheduled tasks" -Action {
        & "$ScriptRoot\scripts\06-scheduled-tasks.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 6 - Scheduled tasks" }

# -----------------------------------------------------------------------
# Step 7 - DesktopInfo
# -----------------------------------------------------------------------
if ($stepsEnabled['desktopInfo']) {
    Invoke-Step -Name "Step 7 - DesktopInfo" -Action {
        & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 7 - DesktopInfo" }

# -----------------------------------------------------------------------
# Summary
# -----------------------------------------------------------------------
Write-Log "========================================" -Level INFO
Write-Log "SUMMARY" -Level INFO
Write-Log "========================================" -Level INFO

$countOK      = ($StepResults | Where-Object { $_.Status -eq "OK"      }).Count
$countError   = ($StepResults | Where-Object { $_.Status -eq "ERROR"   }).Count


Error: EACCES: permission denied, open '/opt/xetup/Deploy-Windows.ps1'


Bash

sudo chown dev:dev /opt/xetup/Deploy-Windows.ps1

Fix Deploy-Windows.ps1 ownership


(Bash completed with no output)


The file /opt/xetup/Deploy-Windows.ps1 has been updated successfully.

#Requires -RunAsAdministrator

[CmdletBinding()]
param(
    [switch]$SkipBloatware,
    [switch]$SkipSoftware,
    [switch]$SkipDefaultProfile,
    [switch]$DryRun
)

$ErrorActionPreference = "Continue"

# -----------------------------------------------------------------------
# Paths
# -----------------------------------------------------------------------
$ScriptRoot  = $PSScriptRoot
$LogDir      = "C:\Windows\Setup\Scripts"
$LogFile     = "$LogDir\Deploy.log"
$ConfigFile  = "$ScriptRoot\config\config.json"

# -----------------------------------------------------------------------
# Logging
# -----------------------------------------------------------------------
function Write-Log {
    param(
        [string]$Message,
        [ValidateSet("INFO","OK","ERROR","WARN","STEP")]
        [string]$Level = "INFO"
    )
    $timestamp = Get-Date -Format "HH:mm:ss"
    $line = "[$timestamp] [$Level] $Message"
    Add-Content -Path $LogFile -Value $line -Encoding UTF8
    switch ($Level) {
        "OK"    { Write-Host $line -ForegroundColor Green }
        "ERROR" { Write-Host $line -ForegroundColor Red }
        "WARN"  { Write-Host $line -ForegroundColor Yellow }
        "STEP"  { Write-Host $line -ForegroundColor Cyan }
        default { Write-Host $line }
    }
}

# -----------------------------------------------------------------------
# Step runner - catches errors, logs, always continues
# -----------------------------------------------------------------------
$StepResults = [System.Collections.Generic.List[hashtable]]::new()

function Invoke-Step {
    param(
        [string]$Name,
        [scriptblock]$Action
    )

    Write-Log "---- $Name ----" -Level STEP

    if ($DryRun) {
        Write-Log "DryRun - skipping execution" -Level WARN
        $StepResults.Add(@{ Name = $Name; Status = "DRYRUN" })
        return
    }

    try {
        & $Action
        Write-Log "$Name - OK" -Level OK
        $StepResults.Add(@{ Name = $Name; Status = "OK" })
    }
    catch {
        Write-Log "$Name - ERROR: $_" -Level ERROR
        $StepResults.Add(@{ Name = $Name; Status = "ERROR" })
    }
}

# -----------------------------------------------------------------------
# Init
# -----------------------------------------------------------------------
if (-not (Test-Path $LogDir)) {
    New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
}

Write-Log "========================================" -Level INFO
Write-Log "Deploy-Windows.ps1 started" -Level INFO
Write-Log "Computer: $env:COMPUTERNAME" -Level INFO
Write-Log "User: $env:USERNAME" -Level INFO
Write-Log "Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -Level INFO
if ($DryRun) { Write-Log "Mode: DRY RUN" -Level WARN }
Write-Log "========================================" -Level INFO

# -----------------------------------------------------------------------
# Load config
# -----------------------------------------------------------------------
$Config = $null
Invoke-Step -Name "Load config.json" -Action {
    if (-not (Test-Path $ConfigFile)) {
        throw "config.json not found: $ConfigFile"
    }
    $script:Config = Get-Content $ConfigFile -Raw -Encoding UTF8 | ConvertFrom-Json
    Write-Log "Config loaded from $ConfigFile" -Level INFO
}

# -----------------------------------------------------------------------
# Build step enable/disable map from config + CLI overrides
# -----------------------------------------------------------------------
$stepsEnabled = @{
    adminAccount    = $true
    bloatware       = $true
    software        = $true
    systemRegistry  = $true
    defaultProfile  = $true
    personalization = $true
    scheduledTasks  = $true
    desktopInfo     = $true
    activation      = $true
}
if ($Config -and $Config.steps) {
    foreach ($key in @($stepsEnabled.Keys)) {
        $val = $Config.steps.$key
        if ($null -ne $val) { $stepsEnabled[$key] = [bool]$val }
    }
}
# CLI switches override config.steps
if ($SkipBloatware)      { $stepsEnabled['bloatware']      = $false }
if ($SkipSoftware)       { $stepsEnabled['software']       = $false }
if ($SkipDefaultProfile) { $stepsEnabled['defaultProfile'] = $false }

function Skip-Step {
    param([string]$Name)
    Write-Log "$Name - SKIPPED (disabled in config)" -Level WARN
    $StepResults.Add(@{ Name = $Name; Status = "SKIPPED" })
}

# -----------------------------------------------------------------------
# Step 0a - Admin account
# -----------------------------------------------------------------------
if ($stepsEnabled['adminAccount']) {
    Invoke-Step -Name "Step 0a - Admin account" -Action {
        & "$ScriptRoot\scripts\00-admin-account.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 0a - Admin account" }

# -----------------------------------------------------------------------
# Step 0b - Windows activation
# -----------------------------------------------------------------------
if ($stepsEnabled['activation']) {
    Invoke-Step -Name "Step 0b - Windows activation" -Action {
        & "$ScriptRoot\scripts\08-activation.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 0b - Windows activation" }

# -----------------------------------------------------------------------
# Step 1 - Bloatware removal
# -----------------------------------------------------------------------
if ($stepsEnabled['bloatware']) {
    Invoke-Step -Name "Step 1 - Bloatware removal" -Action {
        & "$ScriptRoot\scripts\01-bloatware.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 1 - Bloatware removal" }

# -----------------------------------------------------------------------
# Step 2 - Software installation
# -----------------------------------------------------------------------
if ($stepsEnabled['software']) {
    Invoke-Step -Name "Step 2 - Software installation" -Action {
        & "$ScriptRoot\scripts\02-software.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 2 - Software installation" }

# -----------------------------------------------------------------------
# Step 3 - System registry (HKLM)
# -----------------------------------------------------------------------
if ($stepsEnabled['systemRegistry']) {
    Invoke-Step -Name "Step 3 - System registry" -Action {
        & "$ScriptRoot\scripts\03-system-registry.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 3 - System registry" }

# -----------------------------------------------------------------------
# Step 4 - Default profile (NTUSER.DAT)
# -----------------------------------------------------------------------
if ($stepsEnabled['defaultProfile']) {
    Invoke-Step -Name "Step 4 - Default profile" -Action {
        & "$ScriptRoot\scripts\04-default-profile.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 4 - Default profile" }

# -----------------------------------------------------------------------
# Step 5 - Personalization
# -----------------------------------------------------------------------
if ($stepsEnabled['personalization']) {
    Invoke-Step -Name "Step 5 - Personalization" -Action {
        & "$ScriptRoot\scripts\05-personalization.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 5 - Personalization" }

# -----------------------------------------------------------------------
# Step 6 - Scheduled tasks
# -----------------------------------------------------------------------
if ($stepsEnabled['scheduledTasks']) {
    Invoke-Step -Name "Step 6 - Scheduled tasks" -Action {
        & "$ScriptRoot\scripts\06-scheduled-tasks.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 6 - Scheduled tasks" }

# -----------------------------------------------------------------------
# Step 7 - DesktopInfo
# -----------------------------------------------------------------------
if ($stepsEnabled['desktopInfo']) {
    Invoke-Step -Name "Step 7 - DesktopInfo" -Action {
        & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 7 - DesktopInfo" }

# -----------------------------------------------------------------------
# Summary
# -----------------------------------------------------------------------
Write-Log "========================================" -Level INFO
Write-Log "SUMMARY" -Level INFO
Write-Log "========================================" -Level INFO

$countOK      = ($StepResults | Where-Object { $_.Status -eq "OK"      }).Count
$countError   = ($StepResults | Where-Object { $_.Status -eq "ERROR"   }).Count
$countSkipped = ($StepResults | Where-Object { $_.Status -eq "SKIPPED" }).Count
$countDryRun  = ($StepResults | Where-Object { $_.Status -eq "DRYRUN"  }).Count

foreach ($r in $StepResults) {
    $lvl = switch ($r.Status) {
        "OK"      { "OK" }
        "ERROR"   { "ERROR" }
        "SKIPPED" { "WARN" }
        "DRYRUN"  { "WARN" }
    }
    Write-Log "$($r.Status.PadRight(8)) $($r.Name)" -Level $lvl
}

Write-Log "----------------------------------------" -Level INFO
Write-Log "OK: $countOK  ERROR: $countError  SKIPPED: $countSkipped  DRYRUN: $countDryRun" -Level INFO
Write-Log "Log saved to: $LogFile" -Level INFO
Write-Log "========================================" -Level INFO

if ($countError -gt 0) {
    Write-Log "Deployment finished with errors. Review log: $LogFile" -Level ERROR
    exit 1
} else {
    Write-Log "Deployment finished successfully." -Level OK
    exit 0
}

defaultProfile  = $true
personalization = $true
scheduledTasks  = $true
-    desktopInfo     = $true
+    backinfo        = $true
activation      = $true
}
if ($Config -and $Config.steps) {


#Requires -RunAsAdministrator

[CmdletBinding()]
param(
    [switch]$SkipBloatware,
    [switch]$SkipSoftware,
    [switch]$SkipDefaultProfile,
    [switch]$DryRun
)

$ErrorActionPreference = "Continue"

# -----------------------------------------------------------------------
# Paths
# -----------------------------------------------------------------------
$ScriptRoot  = $PSScriptRoot
$LogDir      = "C:\Windows\Setup\Scripts"
$LogFile     = "$LogDir\Deploy.log"
$ConfigFile  = "$ScriptRoot\config\config.json"

# -----------------------------------------------------------------------
# Logging
# -----------------------------------------------------------------------
function Write-Log {
    param(
        [string]$Message,
        [ValidateSet("INFO","OK","ERROR","WARN","STEP")]
        [string]$Level = "INFO"
    )
    $timestamp = Get-Date -Format "HH:mm:ss"
    $line = "[$timestamp] [$Level] $Message"
    Add-Content -Path $LogFile -Value $line -Encoding UTF8
    switch ($Level) {
        "OK"    { Write-Host $line -ForegroundColor Green }
        "ERROR" { Write-Host $line -ForegroundColor Red }
        "WARN"  { Write-Host $line -ForegroundColor Yellow }
        "STEP"  { Write-Host $line -ForegroundColor Cyan }
        default { Write-Host $line }
    }
}

# -----------------------------------------------------------------------
# Step runner - catches errors, logs, always continues
# -----------------------------------------------------------------------
$StepResults = [System.Collections.Generic.List[hashtable]]::new()

function Invoke-Step {
    param(
        [string]$Name,
        [scriptblock]$Action
    )

    Write-Log "---- $Name ----" -Level STEP

    if ($DryRun) {
        Write-Log "DryRun - skipping execution" -Level WARN
        $StepResults.Add(@{ Name = $Name; Status = "DRYRUN" })
        return
    }

    try {
        & $Action
        Write-Log "$Name - OK" -Level OK
        $StepResults.Add(@{ Name = $Name; Status = "OK" })
    }
    catch {
        Write-Log "$Name - ERROR: $_" -Level ERROR
        $StepResults.Add(@{ Name = $Name; Status = "ERROR" })
    }
}

# -----------------------------------------------------------------------
# Init
# -----------------------------------------------------------------------
if (-not (Test-Path $LogDir)) {
    New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
}

Write-Log "========================================" -Level INFO
Write-Log "Deploy-Windows.ps1 started" -Level INFO
Write-Log "Computer: $env:COMPUTERNAME" -Level INFO
Write-Log "User: $env:USERNAME" -Level INFO
Write-Log "Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -Level INFO
if ($DryRun) { Write-Log "Mode: DRY RUN" -Level WARN }
Write-Log "========================================" -Level INFO

# -----------------------------------------------------------------------
# Load config
# -----------------------------------------------------------------------
$Config = $null
Invoke-Step -Name "Load config.json" -Action {
    if (-not (Test-Path $ConfigFile)) {
        throw "config.json not found: $ConfigFile"
    }
    $script:Config = Get-Content $ConfigFile -Raw -Encoding UTF8 | ConvertFrom-Json
    Write-Log "Config loaded from $ConfigFile" -Level INFO
}

# -----------------------------------------------------------------------
# Build step enable/disable map from config + CLI overrides
# -----------------------------------------------------------------------
$stepsEnabled = @{
    adminAccount    = $true
    bloatware       = $true
    software        = $true
    systemRegistry  = $true
    defaultProfile  = $true
    personalization = $true
    scheduledTasks  = $true
    backinfo        = $true
    activation      = $true
}
if ($Config -and $Config.steps) {
    foreach ($key in @($stepsEnabled.Keys)) {
        $val = $Config.steps.$key
        if ($null -ne $val) { $stepsEnabled[$key] = [bool]$val }
    }
}
# CLI switches override config.steps
if ($SkipBloatware)      { $stepsEnabled['bloatware']      = $false }
if ($SkipSoftware)       { $stepsEnabled['software']       = $false }
if ($SkipDefaultProfile) { $stepsEnabled['defaultProfile'] = $false }

function Skip-Step {
    param([string]$Name)
    Write-Log "$Name - SKIPPED (disabled in config)" -Level WARN
    $StepResults.Add(@{ Name = $Name; Status = "SKIPPED" })
}

# -----------------------------------------------------------------------
# Step 0a - Admin account
# -----------------------------------------------------------------------
if ($stepsEnabled['adminAccount']) {
    Invoke-Step -Name "Step 0a - Admin account" -Action {
        & "$ScriptRoot\scripts\00-admin-account.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 0a - Admin account" }

# -----------------------------------------------------------------------
# Step 0b - Windows activation
# -----------------------------------------------------------------------
if ($stepsEnabled['activation']) {
    Invoke-Step -Name "Step 0b - Windows activation" -Action {
        & "$ScriptRoot\scripts\08-activation.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 0b - Windows activation" }

# -----------------------------------------------------------------------
# Step 1 - Bloatware removal
# -----------------------------------------------------------------------
if ($stepsEnabled['bloatware']) {
    Invoke-Step -Name "Step 1 - Bloatware removal" -Action {
        & "$ScriptRoot\scripts\01-bloatware.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 1 - Bloatware removal" }

# -----------------------------------------------------------------------
# Step 2 - Software installation
# -----------------------------------------------------------------------
if ($stepsEnabled['software']) {
    Invoke-Step -Name "Step 2 - Software installation" -Action {
        & "$ScriptRoot\scripts\02-software.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 2 - Software installation" }

# -----------------------------------------------------------------------
# Step 3 - System registry (HKLM)
# -----------------------------------------------------------------------
if ($stepsEnabled['systemRegistry']) {
    Invoke-Step -Name "Step 3 - System registry" -Action {
        & "$ScriptRoot\scripts\03-system-registry.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 3 - System registry" }

# -----------------------------------------------------------------------
# Step 4 - Default profile (NTUSER.DAT)
# -----------------------------------------------------------------------
if ($stepsEnabled['defaultProfile']) {
    Invoke-Step -Name "Step 4 - Default profile" -Action {
        & "$ScriptRoot\scripts\04-default-profile.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 4 - Default profile" }

# -----------------------------------------------------------------------
# Step 5 - Personalization
# -----------------------------------------------------------------------
if ($stepsEnabled['personalization']) {
    Invoke-Step -Name "Step 5 - Personalization" -Action {
        & "$ScriptRoot\scripts\05-personalization.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 5 - Personalization" }

# -----------------------------------------------------------------------
# Step 6 - Scheduled tasks
# -----------------------------------------------------------------------
if ($stepsEnabled['scheduledTasks']) {
    Invoke-Step -Name "Step 6 - Scheduled tasks" -Action {
        & "$ScriptRoot\scripts\06-scheduled-tasks.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 6 - Scheduled tasks" }

# -----------------------------------------------------------------------
# Step 7 - DesktopInfo
# -----------------------------------------------------------------------
if ($stepsEnabled['desktopInfo']) {
    Invoke-Step -Name "Step 7 - DesktopInfo" -Action {
        & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile
    }
} else { Skip-Step "Step 7 - DesktopInfo" }

# -----------------------------------------------------------------------
# Summary
# -----------------------------------------------------------------------
Write-Log "========================================" -Level INFO
Write-Log "SUMMARY" -Level INFO
Write-Log "========================================" -Level INFO

$countOK      = ($StepResults | Where-Object { $_.Status -eq "OK"      }).Count
$countError   = ($StepResults | Where-Object { $_.Status -eq "ERROR"   }).Count
$countSkipped = ($StepResults | Where-Object { $_.Status -eq "SKIPPED" }).Count
$countDryRun  = ($StepResults | Where-Object { $_.Status -eq "DRYRUN"  }).Count

foreach ($r in $StepResults) {
    $lvl = switch ($r.Status) {
        "OK"      { "OK" }
        "ERROR"   { "ERROR" }
        "SKIPPED" { "WARN" }
        "DRYRUN"  { "WARN" }
    }
    Write-Log "$($r.Status.PadRight(8)) $($r.Name)" -Level $lvl
}

Write-Log "----------------------------------------" -Level INFO
Write-Log "OK: $countOK  ERROR: $countError  SKIPPED: $countSkipped  DRYRUN: $countDryRun" -Level INFO
Write-Log "Log saved to: $LogFile" -Level INFO
Write-Log "========================================" -Level INFO

if ($countError -gt 0) {
    Write-Log "Deployment finished with errors. Review log: $LogFile" -Level ERROR
    exit 1
} else {
    Write-Log "Deployment finished successfully." -Level OK
    exit 0
}

-    Invoke-Step -Name "Step 7 - DesktopInfo" -Action {

-        & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile

+    Invoke-Step -Name "Step 7 - BackInfo" -Action {

+        & "$ScriptRoot\scripts\07-backinfo.ps1" -Config $Config -LogFile $LogFile

-} else { Skip-Step "Step 7 - DesktopInfo" }

+} else { Skip-Step "Step 7 - BackInfo" }


Teď aktualizuji spec stránku — step 00 a step 07, plus STEP_SCRIPT mapping:


504
505

506

507	        00
508	        Admin ucet (adminx9)
509	        Must fix
510

511

512

513
Vytvorit lokalni ucet adminx9	Hotovo

514
Pridat do skupiny Administrators	Hotovo

515
Skryt z login obrazovky (SpecialAccounts\UserList = 0)	Hotovo

516
Heslo nevypirsi, uzivatel nesmeni heslo	Hotovo

517
Zadne heslo (aktualne nastavovano z config.json)	Zmenit: ucet BEZ hesla (rozhodnuti)

518
FullName = "X9.cz s.r.o." (via ADSI)	Chybi, doplnit

519

520

521	          Proc bez hesla: Ucet je skryty pred uzivateli, slouzi pouze MSP adminstraci.
522	          Heslo v config.json by bylo ulozene citelne.
523

524

525

526	        Script: 00-admin-account.ps1
527

528

529

530
531
532

533

534	        01
535	        Bloatware removal
536	        OK
537

538

        00
        Admin ucet (adminx9)
        Must fix

Vytvorit lokalni ucet adminx9	Hotovo

Pridat do skupiny Administrators	Hotovo

Skryt z login obrazovky (SpecialAccounts\UserList = 0)	Hotovo

Heslo nevypirsi, uzivatel nesmeni heslo	Hotovo

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.

        Script: 00-admin-account.ps1

        01
        Bloatware removal
        OK


Edit

Admin ucet (adminx9)
        Must fix

Vytvorit lokalni ucet adminx9	Hotovo

Pridat do skupiny Administrators	Hotovo

Skryt z login obrazovky (SpecialAccounts\UserList = 0)	Hotovo

Heslo nevypirsi, uzivatel nesmeni heslo	Hotovo

Zadne heslo (aktualne nastavovano z config.json)	Zmenit: ucet BEZ hesla (rozhodnuti)

FullName = "X9.cz s.r.o." (via ADSI)	Chybi, doplnit

Admin ucet (adminx9)
        OK

Vytvorit lokalni ucet adminx9	Hotovo

Pridat do skupiny Administrators	Hotovo

Skryt z login obrazovky (SpecialAccounts\UserList = 0)	Hotovo

Heslo nevypirsi, uzivatel nesmeni heslo	Hotovo

Zadne heslo (aktualne nastavovano z config.json)	Opraveno – prazdny SecureString, config.json heslo odstranen

FullName = "X9.cz s.r.o." (via ADSI)	Opraveno – ADSI SetInfo() po vytvoreni uctu


The file /opt/xetup/web/spec/index.html has been updated successfully.

Admin ucet (adminx9)
        Must fix

Vytvorit lokalni ucet adminx9	Hotovo

Pridat do skupiny Administrators	Hotovo

Skryt z login obrazovky (SpecialAccounts\UserList = 0)	Hotovo

Heslo nevypirsi, uzivatel nesmeni heslo	Hotovo

Zadne heslo (aktualne nastavovano z config.json)	Zmenit: ucet BEZ hesla (rozhodnuti)

FullName = "X9.cz s.r.o." (via ADSI)	Chybi, doplnit

Admin ucet (adminx9)
        OK

Vytvorit lokalni ucet adminx9	Hotovo

Pridat do skupiny Administrators	Hotovo

Skryt z login obrazovky (SpecialAccounts\UserList = 0)	Hotovo

Heslo nevypirsi, uzivatel nesmeni heslo	Hotovo

Zadne heslo (aktualne nastavovano z config.json)	Opraveno – prazdny SecureString, config.json heslo odstranen

FullName = "X9.cz s.r.o." (via ADSI)	Opraveno – ADSI SetInfo() po vytvoreni uctu

-
Zadne heslo (aktualne nastavovano z config.json)	Zmenit: ucet BEZ hesla (rozhodnuti)

-
FullName = "X9.cz s.r.o." (via ADSI)	Chybi, doplnit

+
Zadne heslo (aktualne nastavovano z config.json)	Opraveno – prazdny SecureString, config.json heslo odstranen

+
FullName = "X9.cz s.r.o." (via ADSI)	Opraveno – ADSI SetInfo() po vytvoreni uctu

Proc bez hesla: Ucet je skryty pred uzivateli, slouzi pouze MSP adminstraci.


        07
        BackInfo (systemovy info na tapete)
        Must fix

07-desktop-info.ps1 SMAZAT – stary pristup	Nahradit 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 dispozici	Hotovo – jen deploy krok chybi

BackInfo auto-start pri kazdem logonu via Startup shortcut	Zaridi backinfo_W11.ps1

        07
        BackInfo (systemovy info na tapete)
        OK

07-desktop-info.ps1 SMAZAT – stary pristup	Nahrazeno novym 07-backinfo.ps1

Zkopirovat assets/Backinfo/ do C:\Program Files\Backinfo\	Implementovano v 07-backinfo.ps1

Spustit backinfo_W11.ps1 (detekce OS, registry, Startup)	Logika inlinovana v 07-backinfo.ps1

BackInfo.exe v assets/Backinfo/ k dispozici	Hotovo

BackInfo auto-start pri kazdem logonu via Startup shortcut	Shortcut do ProgramData\StartUp vytvori 07-backinfo.ps1


        07
        BackInfo (systemovy info na tapete)
        Must fix

07-desktop-info.ps1 SMAZAT – stary pristup	Nahradit 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 dispozici	Hotovo – jen deploy krok chybi

BackInfo auto-start pri kazdem logonu via Startup shortcut	Zaridi backinfo_W11.ps1

        07
        BackInfo (systemovy info na tapete)
        OK

07-desktop-info.ps1 SMAZAT – stary pristup	Nahrazeno novym 07-backinfo.ps1

Zkopirovat assets/Backinfo/ do C:\Program Files\Backinfo\	Implementovano v 07-backinfo.ps1

Spustit backinfo_W11.ps1 (detekce OS, registry, Startup)	Logika inlinovana v 07-backinfo.ps1

BackInfo.exe v assets/Backinfo/ k dispozici	Hotovo

BackInfo auto-start pri kazdem logonu via Startup shortcut	Shortcut do ProgramData\StartUp vytvori 07-backinfo.ps1

-
07-desktop-info.ps1 SMAZAT – stary pristup	Nahradit 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 dispozici	Hotovo – jen deploy krok chybi

-
BackInfo auto-start pri kazdem logonu via Startup shortcut	Zaridi backinfo_W11.ps1

+
07-desktop-info.ps1 SMAZAT – stary pristup	Nahrazeno novym 07-backinfo.ps1

+
Zkopirovat assets/Backinfo/ do C:\Program Files\Backinfo\	Implementovano v 07-backinfo.ps1

+
Spustit backinfo_W11.ps1 (detekce OS, registry, Startup)	Logika inlinovana v 07-backinfo.ps1

+
BackInfo.exe v assets/Backinfo/ k dispozici	Hotovo

+
BackInfo auto-start pri kazdem logonu via Startup shortcut	Shortcut do ProgramData\StartUp vytvori 07-backinfo.ps1

BackInfo.ini konfiguruje: hostname (velky, centrovan), uzivatelske jmeno,


Aktualizuji STEP_SCRIPT mapping v JS a opravím footer step 07:


'step-04': '04-default-profile',
'step-05': '05-personalization',
'step-06': '06-scheduled-tasks',
-    'step-07': '07-desktop-info',
+    'step-07': '07-backinfo',
'step-08': '08-activation',
};


719:
07-desktop-info.ps1 SMAZAT – stary pristup	Nahrazeno novym 07-backinfo.ps1

733:        Script: 07-desktop-info.ps1 (ke smazani) → novy inline krok v Deploy-Windows.ps1


Script: 07-desktop-info.ps1 (ke smazani) → novy inline krok v Deploy-Windows.ps1


-        Script: 07-desktop-info.ps1 (ke smazani) → novy inline krok v Deploy-Windows.ps1


Teď implementuji Edge politiky a uložím memory o per-řádkovém přístupu. Nejdřív zaznamenám paměť:


1	---
2	name: Communication and workflow preferences
3	description: How Filip wants to work - Czech communication, discussion before coding, interactive reviews
4	type: feedback
5	---
6
7	- Communicate in Czech (code/comments/logs stay English)
8	- When Filip says "nekodujme, udelame diskusi" - he wants discussion first, not jumping to code
9	- Prefers interactive HTML pages for reviews/decisions (not just markdown)
10	- Likes phased approaches - start simple, evolve
11	- Values colleague's field experience over theoretical best practices
12	- When specs conflict, ask rather than assume
13	- Filip appreciates out-of-the-box thinking (Go binaries, web platforms) but wants practical solutions
14	- Don't over-engineer for 20 machines/month scale
15	- Filip works on macOS, targets Windows - cross-compilation matters
16

---
name: Communication and workflow preferences
description: How Filip wants to work - Czech communication, discussion before coding, interactive reviews
type: feedback
---

- Communicate in Czech (code/comments/logs stay English)
- When Filip says "nekodujme, udelame diskusi" - he wants discussion first, not jumping to code
- Prefers interactive HTML pages for reviews/decisions (not just markdown)
- Likes phased approaches - start simple, evolve
- Values colleague's field experience over theoretical best practices
- When specs conflict, ask rather than assume
- Filip appreciates out-of-the-box thinking (Go binaries, web platforms) but wants practical solutions
- Don't over-engineer for 20 machines/month scale
- Filip works on macOS, targets Windows - cross-compilation matters


- Don't over-engineer for 20 machines/month scale
- Filip works on macOS, targets Windows - cross-compilation matters

- Don't over-engineer for 20 machines/month scale
- Filip works on macOS, targets Windows - cross-compilation matters
- Spec page changes must be processed **per row** — don't just skim the section, go through every single mustfix/todo item and implement or explain why not. Missing even one item is unacceptable.
- When applying Forgejo comments: actually read the current issues, don't just rely on session summaries which may be incomplete.

**Why:** Filip caught that step 00 (admin account) and step 07 (BackInfo) were both mustfix and I skipped them despite them being clearly visible in the spec page.


The file /home/dev/.claude/projects/-opt-xetup/memory/feedback_preferences.md has been updated successfully.

- Don't over-engineer for 20 machines/month scale
- Filip works on macOS, targets Windows - cross-compilation matters
- Spec page changes must be processed **per row** — don't just skim the section, go through every single mustfix/todo item and implement or explain why not. Missing even one item is unacceptable.
- When applying Forgejo comments: actually read the current issues, don't just rely on session summaries which may be incomplete.

**Why:** Filip caught that step 00 (admin account) and step 07 (BackInfo) were both mustfix and I skipped them despite them being clearly visible in the spec page.

---
name: Communication and workflow preferences
description: How Filip wants to work - Czech communication, discussion before coding, interactive reviews
type: feedback
---

- Communicate in Czech (code/comments/logs stay English)
- When Filip says "nekodujme, udelame diskusi" - he wants discussion first, not jumping to code
- Prefers interactive HTML pages for reviews/decisions (not just markdown)
- Likes phased approaches - start simple, evolve
- Values colleague's field experience over theoretical best practices
- When specs conflict, ask rather than assume
- Filip appreciates out-of-the-box thinking (Go binaries, web platforms) but wants practical solutions
- Don't over-engineer for 20 machines/month scale
- Filip works on macOS, targets Windows - cross-compilation matters

+- Spec page changes must be processed **per row** — don't just skim the section, go through every single mustfix/todo item and implement or explain why not. Missing even one item is unacceptable.

+- When applying Forgejo comments: actually read the current issues, don't just rely on session summaries which may be incomplete.

+**Why:** Filip caught that step 00 (admin account) and step 07 (BackInfo) were both mustfix and I skipped them despite them being clearly visible in the spec page.


Teď Edge politiky. Uživatel specifikoval konkrétní nastavení, implementuji je do `03-system-registry.ps1`:


233	# Microsoft Edge - hide First Run Experience
234	# -----------------------------------------------------------------------
235	Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" `
236	        -Name "HideFirstRunExperience" -Value 1
237
238	# Also disable Edge desktop shortcut creation after install
239	Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
240	        -Name "CreateDesktopShortcutDefault" -Value 0
241
242	# -----------------------------------------------------------------------
243	# Password - no expiration
244	# -----------------------------------------------------------------------
245	Write-Log "  Setting password max age to UNLIMITED" -Level INFO
246	$pwResult = & net accounts /maxpwage:UNLIMITED 2>&1
247	if ($LASTEXITCODE -eq 0) {
248	    Write-Log "  Password max age set to UNLIMITED" -Level OK
249	} else {
250	    Write-Log "  Failed to set password max age: $pwResult" -Level ERROR
251	}
252
253	# -----------------------------------------------------------------------
254	# Time zone
255	# -----------------------------------------------------------------------
256	$tz = "Central Europe Standard Time"
257	if ($Config -and $Config.deployment -and $Config.deployment.timezone) {
258	    $tz = $Config.deployment.timezone
259	}
260	Write-Log "  Setting time zone: $tz" -Level INFO
261	try {
262	    Set-TimeZone -Id $tz -ErrorAction Stop
263	    Write-Log "  Time zone set: $tz" -Level OK
264	}
265	catch {
266	    Write-Log "  Failed to set time zone: $_" -Level ERROR
267	}
268
269	# -----------------------------------------------------------------------
270	# OneDrive - uninstall from clean Windows (no policy block)
271	# NOTE: No policy key is set intentionally - M365 installation can reinstall
272	#       and run OneDrive normally. Policy DisableFileSyncNGSC would prevent that.
273	# -----------------------------------------------------------------------
274	Write-Log "  Uninstalling OneDrive" -Level INFO
275
276	# Remove OneDriveSetup.exe if present
277	$oneDrivePaths = @(
278	    "$env:SystemRoot\System32\OneDriveSetup.exe"
279	    "$env:SystemRoot\SysWOW64\OneDriveSetup.exe"
280	)
281	foreach ($odPath in $oneDrivePaths) {
282	    if (Test-Path $odPath) {
283	        try {
284	            # Uninstall first
285	            & $odPath /uninstall 2>&1 | Out-Null
286	            Write-Log "  OneDrive uninstalled via $odPath" -Level OK
287	        }
288	        catch {
289	            Write-Log "  OneDrive uninstall failed: $_" -Level WARN
290	        }
291	    }
292	}
293
294	# Remove OneDrive Start Menu shortcut
295	$odLnk = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk"
296	if (Test-Path $odLnk) {
297	    Remove-Item $odLnk -Force -ErrorAction SilentlyContinue
298	    Write-Log "  Removed OneDrive Start Menu shortcut" -Level OK
299	}
300
301	# -----------------------------------------------------------------------
302	# Outlook (new) - disable auto-install via UScheduler
303	# -----------------------------------------------------------------------
304	Write-Log "  Disabling Outlook (new) auto-install" -Level INFO
305
306	$uschedulerPaths = @(
307	    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate"
308	    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate"
309	)
310	foreach ($uPath in $uschedulerPaths) {
311	    if (Test-Path $uPath) {
312	        try {
313	            Remove-Item -Path $uPath -Recurse -Force
314	            Write-Log "  Removed UScheduler key: $uPath" -Level OK
315	        }
316	        catch {
317	            Write-Log "  Failed to remove UScheduler key: $_" -Level WARN
318	        }
319	    }
320	}
321
322	# -----------------------------------------------------------------------
323	# Disable GameDVR
324	# -----------------------------------------------------------------------
325	Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" `
326	        -Name "AllowGameDVR" -Value 0
327
328	# -----------------------------------------------------------------------
329	# Disable Recall (Windows AI feature)
330	# -----------------------------------------------------------------------
331	Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" `
332	        -Name "DisableAIDataAnalysis" -Value 1
333
334	# -----------------------------------------------------------------------
335	# Search on taskbar - hide via HKLM policy (Win11 22H2+ enforcement)
336	# User-level SearchboxTaskbarMode alone is insufficient on newer Win11 builds;
337	# this policy key ensures the setting survives Windows Updates.
338	# -----------------------------------------------------------------------
339	Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" `
340	        -Name "SearchOnTaskbarMode" -Value 0
341
342	# -----------------------------------------------------------------------
343	# Start menu - hide Recommended section (Win11)
344	# -----------------------------------------------------------------------
345	Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" `
346	        -Name "HideRecommendedSection" -Value 1
347
348	Write-Log "Step 3 complete" -Level OK
349

# Microsoft Edge - hide First Run Experience
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" `
        -Name "HideFirstRunExperience" -Value 1

# Also disable Edge desktop shortcut creation after install
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
        -Name "CreateDesktopShortcutDefault" -Value 0

# -----------------------------------------------------------------------
# Password - no expiration
# -----------------------------------------------------------------------
Write-Log "  Setting password max age to UNLIMITED" -Level INFO
$pwResult = & net accounts /maxpwage:UNLIMITED 2>&1
if ($LASTEXITCODE -eq 0) {
    Write-Log "  Password max age set to UNLIMITED" -Level OK
} else {
    Write-Log "  Failed to set password max age: $pwResult" -Level ERROR
}

# -----------------------------------------------------------------------
# Time zone
# -----------------------------------------------------------------------
$tz = "Central Europe Standard Time"
if ($Config -and $Config.deployment -and $Config.deployment.timezone) {
    $tz = $Config.deployment.timezone
}
Write-Log "  Setting time zone: $tz" -Level INFO
try {
    Set-TimeZone -Id $tz -ErrorAction Stop
    Write-Log "  Time zone set: $tz" -Level OK
}
catch {
    Write-Log "  Failed to set time zone: $_" -Level ERROR
}

# -----------------------------------------------------------------------
# OneDrive - uninstall from clean Windows (no policy block)
# NOTE: No policy key is set intentionally - M365 installation can reinstall
#       and run OneDrive normally. Policy DisableFileSyncNGSC would prevent that.
# -----------------------------------------------------------------------
Write-Log "  Uninstalling OneDrive" -Level INFO

# Remove OneDriveSetup.exe if present
$oneDrivePaths = @(
    "$env:SystemRoot\System32\OneDriveSetup.exe"
    "$env:SystemRoot\SysWOW64\OneDriveSetup.exe"
)
foreach ($odPath in $oneDrivePaths) {
    if (Test-Path $odPath) {
        try {
            # Uninstall first
            & $odPath /uninstall 2>&1 | Out-Null
            Write-Log "  OneDrive uninstalled via $odPath" -Level OK
        }
        catch {
            Write-Log "  OneDrive uninstall failed: $_" -Level WARN
        }
    }
}

# Remove OneDrive Start Menu shortcut
$odLnk = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk"
if (Test-Path $odLnk) {
    Remove-Item $odLnk -Force -ErrorAction SilentlyContinue
    Write-Log "  Removed OneDrive Start Menu shortcut" -Level OK
}

# -----------------------------------------------------------------------
# Outlook (new) - disable auto-install via UScheduler
# -----------------------------------------------------------------------
Write-Log "  Disabling Outlook (new) auto-install" -Level INFO

$uschedulerPaths = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate"
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate"
)
foreach ($uPath in $uschedulerPaths) {
    if (Test-Path $uPath) {
        try {
            Remove-Item -Path $uPath -Recurse -Force
            Write-Log "  Removed UScheduler key: $uPath" -Level OK
        }
        catch {
            Write-Log "  Failed to remove UScheduler key: $_" -Level WARN
        }
    }
}

# -----------------------------------------------------------------------
# Disable GameDVR
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" `
        -Name "AllowGameDVR" -Value 0

# -----------------------------------------------------------------------
# Disable Recall (Windows AI feature)
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" `
        -Name "DisableAIDataAnalysis" -Value 1

# -----------------------------------------------------------------------
# Search on taskbar - hide via HKLM policy (Win11 22H2+ enforcement)
# User-level SearchboxTaskbarMode alone is insufficient on newer Win11 builds;
# this policy key ensures the setting survives Windows Updates.
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" `
        -Name "SearchOnTaskbarMode" -Value 0

# -----------------------------------------------------------------------
# Start menu - hide Recommended section (Win11)
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" `
        -Name "HideRecommendedSection" -Value 1

Write-Log "Step 3 complete" -Level OK


# -----------------------------------------------------------------------
# Microsoft Edge - hide First Run Experience
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" `
        -Name "HideFirstRunExperience" -Value 1

# Also disable Edge desktop shortcut creation after install
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
        -Name "CreateDesktopShortcutDefault" -Value 0

# -----------------------------------------------------------------------
# Microsoft Edge policies
# -----------------------------------------------------------------------
$edgePath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"

# UI / first run
Set-Reg -Path $edgePath -Name "HideFirstRunExperience"    -Value 1
Set-Reg -Path $edgePath -Name "DefaultBrowserSettingEnabled" -Value 0

# New tab page / recommendations
Set-Reg -Path $edgePath -Name "NewTabPageContentEnabled"                       -Value 0
Set-Reg -Path $edgePath -Name "ShowRecommendationsEnabled"                     -Value 0
Set-Reg -Path $edgePath -Name "SpotlightExperiencesAndRecommendationsEnabled"  -Value 0
Set-Reg -Path $edgePath -Name "PersonalizationReportingEnabled"                -Value 0

# Shopping / rewards / sidebar
Set-Reg -Path $edgePath -Name "EdgeShoppingAssistantEnabled" -Value 0
Set-Reg -Path $edgePath -Name "ShowMicrosoftRewards"         -Value 0
Set-Reg -Path $edgePath -Name "HubsSidebarEnabled"           -Value 0

# Search suggestions
Set-Reg -Path $edgePath -Name "SearchSuggestEnabled"  -Value 0
Set-Reg -Path $edgePath -Name "ImportOnEachLaunch"    -Value 0

# Telemetry / feedback
Set-Reg -Path $edgePath -Name "DiagnosticData"                  -Value 0
Set-Reg -Path $edgePath -Name "FeedbackSurveysEnabled"          -Value 0
Set-Reg -Path $edgePath -Name "EdgeCollectionsEnabled"          -Value 0

# Toolbar buttons - show
Set-Reg -Path $edgePath -Name "FavoritesBarEnabled"        -Value 1  # Favorites bar always visible
Set-Reg -Path $edgePath -Name "DownloadsButtonEnabled"     -Value 1
Set-Reg -Path $edgePath -Name "HistoryButtonEnabled"       -Value 1

# Toolbar buttons - hide
Set-Reg -Path $edgePath -Name "HomeButtonEnabled"          -Value 0
Set-Reg -Path $edgePath -Name "SplitScreenEnabled"         -Value 0
Set-Reg -Path $edgePath -Name "EdgeEDropEnabled"           -Value 0  # Drop
Set-Reg -Path $edgePath -Name "WebCaptureEnabled"          -Value 0  # Screenshot
Set-Reg -Path $edgePath -Name "ShareAllowed"               -Value 0  # Share

# Default search engine: Google
# SearchProviderEnabled must be 1, SearchProviderName + URL set the provider
Set-Reg -Path $edgePath -Name "DefaultSearchProviderEnabled" -Value 1 -Type "DWord"
Set-Reg -Path $edgePath -Name "DefaultSearchProviderName"    -Value "Google" -Type "String"
Set-Reg -Path $edgePath -Name "DefaultSearchProviderSearchURL" `
        -Value "https://www.google.com/search?q={searchTerms}" -Type "String"
# Remove other search engines (empty list = no other providers besides default)
Set-Reg -Path $edgePath -Name "ManagedSearchEngines" `
        -Value '[{"is_default":true,"name":"Google","search_url":"https://www.google.com/search?q={searchTerms}","keyword":"google.com"}]' `
        -Type "String"

# Disable desktop shortcut on install/update
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
        -Name "CreateDesktopShortcutDefault" -Value 0


The file /opt/xetup/scripts/03-system-registry.ps1 has been updated successfully.

# -----------------------------------------------------------------------
# Microsoft Edge - hide First Run Experience
# -----------------------------------------------------------------------
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" `
        -Name "HideFirstRunExperience" -Value 1

# Also disable Edge desktop shortcut creation after install
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
        -Name "CreateDesktopShortcutDefault" -Value 0

# -----------------------------------------------------------------------
# Microsoft Edge policies
# -----------------------------------------------------------------------
$edgePath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"

# UI / first run
Set-Reg -Path $edgePath -Name "HideFirstRunExperience"    -Value 1
Set-Reg -Path $edgePath -Name "DefaultBrowserSettingEnabled" -Value 0

# New tab page / recommendations
Set-Reg -Path $edgePath -Name "NewTabPageContentEnabled"                       -Value 0
Set-Reg -Path $edgePath -Name "ShowRecommendationsEnabled"                     -Value 0
Set-Reg -Path $edgePath -Name "SpotlightExperiencesAndRecommendationsEnabled"  -Value 0
Set-Reg -Path $edgePath -Name "PersonalizationReportingEnabled"                -Value 0

# Shopping / rewards / sidebar
Set-Reg -Path $edgePath -Name "EdgeShoppingAssistantEnabled" -Value 0
Set-Reg -Path $edgePath -Name "ShowMicrosoftRewards"         -Value 0
Set-Reg -Path $edgePath -Name "HubsSidebarEnabled"           -Value 0

# Search suggestions
Set-Reg -Path $edgePath -Name "SearchSuggestEnabled"  -Value 0
Set-Reg -Path $edgePath -Name "ImportOnEachLaunch"    -Value 0

# Telemetry / feedback
Set-Reg -Path $edgePath -Name "DiagnosticData"                  -Value 0
Set-Reg -Path $edgePath -Name "FeedbackSurveysEnabled"          -Value 0
Set-Reg -Path $edgePath -Name "EdgeCollectionsEnabled"          -Value 0

# Toolbar buttons - show
Set-Reg -Path $edgePath -Name "FavoritesBarEnabled"        -Value 1  # Favorites bar always visible
Set-Reg -Path $edgePath -Name "DownloadsButtonEnabled"     -Value 1
Set-Reg -Path $edgePath -Name "HistoryButtonEnabled"       -Value 1

# Toolbar buttons - hide
Set-Reg -Path $edgePath -Name "HomeButtonEnabled"          -Value 0
Set-Reg -Path $edgePath -Name "SplitScreenEnabled"         -Value 0
Set-Reg -Path $edgePath -Name "EdgeEDropEnabled"           -Value 0  # Drop
Set-Reg -Path $edgePath -Name "WebCaptureEnabled"          -Value 0  # Screenshot
Set-Reg -Path $edgePath -Name "ShareAllowed"               -Value 0  # Share

# Default search engine: Google
# SearchProviderEnabled must be 1, SearchProviderName + URL set the provider
Set-Reg -Path $edgePath -Name "DefaultSearchProviderEnabled" -Value 1 -Type "DWord"
Set-Reg -Path $edgePath -Name "DefaultSearchProviderName"    -Value "Google" -Type "String"
Set-Reg -Path $edgePath -Name "DefaultSearchProviderSearchURL" `
        -Value "https://www.google.com/search?q={searchTerms}" -Type "String"
# Remove other search engines (empty list = no other providers besides default)
Set-Reg -Path $edgePath -Name "ManagedSearchEngines" `
        -Value '[{"is_default":true,"name":"Google","search_url":"https://www.google.com/search?q={searchTerms}","keyword":"google.com"}]' `
        -Type "String"

# Disable desktop shortcut on install/update
Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
        -Name "CreateDesktopShortcutDefault" -Value 0

-# Microsoft Edge - hide First Run Experience

-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" `

-        -Name "HideFirstRunExperience" -Value 1

-# Also disable Edge desktop shortcut creation after install

+Set-Reg -Path $edgePath -Name "HideFirstRunExperience"    -Value 1

+Set-Reg -Path $edgePath -Name "DefaultBrowserSettingEnabled" -Value 0

+Set-Reg -Path $edgePath -Name "NewTabPageContentEnabled"                       -Value 0

+Set-Reg -Path $edgePath -Name "ShowRecommendationsEnabled"                     -Value 0

+Set-Reg -Path $edgePath -Name "SpotlightExperiencesAndRecommendationsEnabled"  -Value 0

+Set-Reg -Path $edgePath -Name "PersonalizationReportingEnabled"                -Value 0

+Set-Reg -Path $edgePath -Name "EdgeShoppingAssistantEnabled" -Value 0

+Set-Reg -Path $edgePath -Name "ShowMicrosoftRewards"         -Value 0

+Set-Reg -Path $edgePath -Name "HubsSidebarEnabled"           -Value 0

+Set-Reg -Path $edgePath -Name "SearchSuggestEnabled"  -Value 0

+Set-Reg -Path $edgePath -Name "ImportOnEachLaunch"    -Value 0

+Set-Reg -Path $edgePath -Name "DiagnosticData"                  -Value 0

+Set-Reg -Path $edgePath -Name "FeedbackSurveysEnabled"          -Value 0

+Set-Reg -Path $edgePath -Name "EdgeCollectionsEnabled"          -Value 0

+Set-Reg -Path $edgePath -Name "FavoritesBarEnabled"        -Value 1  # Favorites bar always visible

+Set-Reg -Path $edgePath -Name "DownloadsButtonEnabled"     -Value 1

+Set-Reg -Path $edgePath -Name "HistoryButtonEnabled"       -Value 1

+Set-Reg -Path $edgePath -Name "HomeButtonEnabled"          -Value 0

+Set-Reg -Path $edgePath -Name "SplitScreenEnabled"         -Value 0

+Set-Reg -Path $edgePath -Name "EdgeEDropEnabled"           -Value 0  # Drop

+Set-Reg -Path $edgePath -Name "WebCaptureEnabled"          -Value 0  # Screenshot

+Set-Reg -Path $edgePath -Name "ShareAllowed"               -Value 0  # Share

+# SearchProviderEnabled must be 1, SearchProviderName + URL set the provider

+Set-Reg -Path $edgePath -Name "DefaultSearchProviderEnabled" -Value 1 -Type "DWord"

+Set-Reg -Path $edgePath -Name "DefaultSearchProviderName"    -Value "Google" -Type "String"

+Set-Reg -Path $edgePath -Name "DefaultSearchProviderSearchURL" `

+        -Value "https://www.google.com/search?q={searchTerms}" -Type "String"

+# Remove other search engines (empty list = no other providers besides default)

+Set-Reg -Path $edgePath -Name "ManagedSearchEngines" `

+        -Value '[{"is_default":true,"name":"Google","search_url":"https://www.google.com/search?q={searchTerms}","keyword":"google.com"}]' `

+# Disable desktop shortcut on install/update


Teď aktualizuji header skriptu a spec stránku pro Edge políčka: