xetup/scripts/00-admin-account.ps1
Filip Zubik 7e6095d1bd Fixes, Windows Update (step 12), auto-reboot, PS window hide
- Write-Log creates C:\Windows\Setup\Scripts\ automatically (was failing on fresh install)
- Step 12: PSWindowsUpdate first pass + X9-WindowsUpdate scheduled task for post-reboot rounds
  (handles typical 2-3 reboot cycles on fresh Windows, task self-deletes when up to date)
- GUI summary: 60s countdown auto-reboot with "Restartovat ted" / "Zrusit restart" buttons
- runner: HideWindow=true prevents PS console from appearing over GUI
- runner: skipPSNoiseLine filters PS error metadata (CategoryInfo, FullyQualifiedErrorId etc.)
- web: fix curl command to include https:// prefix
2026-04-16 14:49:41 +02:00

126 lines
5.5 KiB
PowerShell

<#
.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"
$null = New-Item -ItemType Directory -Force -Path (Split-Path $LogFile -Parent) -ErrorAction SilentlyContinue
Add-Content -Path $LogFile -Value $line -Encoding UTF8
}
# -----------------------------------------------------------------------
# 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
}
# -----------------------------------------------------------------------
# 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