xetup/scripts/00-admin-account.ps1
X9 Dev 108a22e7cb Fix all remaining mustfix items + Edge policies
00-admin-account: empty password (SecureString), FullName via ADSI SetInfo()
07-backinfo: new script replacing 07-desktop-info - copies assets, sets
  registry OSName, creates Startup shortcut, launches BackInfo immediately
Deploy-Windows.ps1: step 7 now calls 07-backinfo.ps1 (desktopInfo->backinfo)
03-system-registry: full Edge policy set - favorites bar, Google search,
  show/hide toolbar buttons per spec, telemetry/content policies, removed
  old Edge policies TODO note
web/spec: step-00 OK, step-07 OK, step-03 Edge rows updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 09:45:49 +02:00

125 lines
5.3 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"
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