From 3479a341becf3b97d66ac508404752d483edf6d2 Mon Sep 17 00:00:00 2001 From: Atlas Corp Date: Tue, 23 Jun 2026 15:04:06 +0200 Subject: [PATCH] feat: fleet provisioning kit v2 - debug logging + edition fix --- .gitignore | 5 + Scripts/Setup-Laptop.ps1 | 385 +++++++++++++++++++++++++++++++++++ Scripts/fleet.config.example | 4 + autounattend.xml | 260 +++++++++++++++++++++++ docs/SETUP.md | 52 +++++ 5 files changed, 706 insertions(+) create mode 100644 .gitignore create mode 100644 Scripts/Setup-Laptop.ps1 create mode 100644 Scripts/fleet.config.example create mode 100644 autounattend.xml create mode 100644 docs/SETUP.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bacfdb4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Nooit echte keys committen +Scripts/fleet.config +Scripts/HPImageAssistant.exe +*.exe +AtlasLogs/ diff --git a/Scripts/Setup-Laptop.ps1 b/Scripts/Setup-Laptop.ps1 new file mode 100644 index 0000000..fb7b97c --- /dev/null +++ b/Scripts/Setup-Laptop.ps1 @@ -0,0 +1,385 @@ +# ============================================================= +# Atlas HP EliteBook Auto-Setup Script v3 +# Draait als Administrator via autounattend FirstLogonCommands. +# ============================================================= + +$global:AtlasMutex = New-Object System.Threading.Mutex($false, "Global\AtlasSetupOnce") +if (-not $global:AtlasMutex.WaitOne(0)) { exit } + +$host.UI.RawUI.WindowTitle = "*** ATLAS LAPTOP SETUP - LEES DIT VENSTER ***" + +$DebugDir = "C:\AtlasDebug" +$null = New-Item -Type Directory -Force $DebugDir, "C:\Atlas" -ErrorAction SilentlyContinue + +$TranscriptFile = "$DebugDir\setup-transcript_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt" +Start-Transcript -Path $TranscriptFile -Force -ErrorAction SilentlyContinue + +$LogFile = "$DebugDir\setup-log.txt" + +function Write-Log { + param([string]$Message, [string]$Color = "White") + $ts = Get-Date -Format "HH:mm:ss" + $line = "[$ts] $Message" + Write-Host $line -ForegroundColor $Color + Add-Content -Path $LogFile -Value $line -ErrorAction SilentlyContinue +} + +function Write-Phase { + param([string]$Phase) + $ts = Get-Date -Format "s" + Add-Content "$DebugDir\setup-phases.log" "[$ts] $Phase" -ErrorAction SilentlyContinue + Write-Log "=== $Phase ===" "Cyan" +} + +function Export-HardwareInfo { + try { + $hw = @("=== Atlas Hardware Dump ===", "Datum: $(Get-Date)", "") + $bios = Get-CimInstance Win32_BIOS -ErrorAction SilentlyContinue + $sys = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue + $cpu = Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue | Select-Object -First 1 + $os = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue + $hw += "Fabrikant : $($sys.Manufacturer)" + $hw += "Model : $($sys.Model)" + $hw += "Serienummer: $($bios.SerialNumber)" + $hw += "BIOS versie: $($bios.SMBIOSBIOSVersion) Datum: $($bios.ReleaseDate)" + $hw += "CPU: $($cpu.Name) Cores: $($cpu.NumberOfCores) LP: $($cpu.NumberOfLogicalProcessors)" + $hw += "RAM: $([math]::Round($sys.TotalPhysicalMemory/1GB,1)) GB totaal" + $hw += "OS: $($os.Caption) $($os.OSArchitecture) build $($os.BuildNumber)" + $editie = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -ErrorAction SilentlyContinue).EditionID + $hw += "Editie: $editie" + $lic = Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" -ErrorAction SilentlyContinue | + Where-Object { $_.PartialProductKey } | Select-Object -First 1 + $hw += "LicenseStatus: $($lic.LicenseStatus) Key(deels): $($lic.PartialProductKey)" + $hw += "" + $hw += "=== Schijven ===" + Get-CimInstance Win32_DiskDrive -ErrorAction SilentlyContinue | ForEach-Object { + $hw += " $($_.Caption) | $([math]::Round($_.Size/1GB,0)) GB | $($_.MediaType)" + } + $hw += "" + $hw += "=== Netwerk adapters ===" + Get-NetAdapter -ErrorAction SilentlyContinue | ForEach-Object { + $hw += " $($_.Name) | $($_.InterfaceDescription) | $($_.Status) | MAC: $($_.MacAddress)" + } + $hw | Set-Content "$DebugDir\hardware-info.txt" -Encoding UTF8 + Write-Log "Hardware dump: $DebugDir\hardware-info.txt" "Green" + } catch { Write-Log "Hardware dump fout: $($_.Exception.Message)" "Red" } +} + +function Export-LogsToUSB { + param([string]$Label = "OK") + Write-Log "Logs exporteren naar USB..." "Cyan" + $usbDrive = $null + foreach ($d in [char[]](68..90)) { + if ((Test-Path "${d}:\Scripts\Setup-Laptop.ps1") -or + (Test-Path "${d}:\scripts\Setup-Laptop.ps1") -or + (Test-Path "${d}:\autounattend.xml")) { + $usbDrive = "${d}:\" + break + } + } + if (-not $usbDrive) { + Write-Log "USB niet gevonden voor log-export." "Yellow" + return + } + $stamp = Get-Date -Format "yyyyMMdd_HHmmss" + $name = $env:COMPUTERNAME + $destDir = "${usbDrive}AtlasLogs\${name}_${Label}_${stamp}" + $null = New-Item -Type Directory -Force $destDir -ErrorAction SilentlyContinue + Copy-Item "$DebugDir\*" $destDir -Recurse -Force -ErrorAction SilentlyContinue + Write-Log "Logs geexporteerd naar: $destDir" "Green" + Write-Log "USB mag eruit. Logs staan in AtlasLogs\ op de USB." "Green" +} + +try { + +Write-Phase "Atlas HP EliteBook Setup v3 Gestart" +Write-Log "Draait als: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" "Green" +Write-Log "Transcript: $TranscriptFile" "Green" + +Export-HardwareInfo +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Setup-Laptop.ps1 gestart" + +try { net user Atlas "" | Out-Null; Write-Log "Atlas wachtwoord verwijderd" "Green" } catch {} + +# ============================================================= +# STAP 0: Toetsenbord kiezen +# ============================================================= +Write-Phase "STAP 0: Toetsenbord kiezen" + +function Set-AtlasProfileKeyboard { + param([string]$Keuze) + $hive = "C:\Users\Atlas\NTUSER.DAT" + if (-not (Test-Path $hive)) { return } + reg load "HKU\AtlasTemp" "$hive" | Out-Null + if ($LASTEXITCODE -ne 0) { return } + Start-Sleep -Milliseconds 500 + if ($Keuze -eq "AZERTY") { + reg add "HKU\AtlasTemp\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "0000080c" /f | Out-Null + reg add "HKU\AtlasTemp\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00020409" /f | Out-Null + } else { + reg add "HKU\AtlasTemp\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00020409" /f | Out-Null + reg add "HKU\AtlasTemp\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "0000080c" /f | Out-Null + } + [gc]::Collect(); Start-Sleep -Seconds 1; reg unload "HKU\AtlasTemp" | Out-Null +} + +function Set-KeyboardLayout { + Write-Host "" + Write-Host " =============================================" -ForegroundColor Cyan + Write-Host " KIES HET STANDAARD TOETSENBORD" -ForegroundColor Cyan + Write-Host " =============================================" -ForegroundColor Cyan + Write-Host " [1] = AZERTY (Belgisch) [2] = QWERTY (US-Internationaal)" -ForegroundColor White + Write-Host " Geen keuze binnen 60 sec = QWERTY" -ForegroundColor DarkGray + Write-Host "" + $keuze = $null + try { + $deadline = (Get-Date).AddSeconds(60) + while (-not $keuze -and (Get-Date) -lt $deadline) { + if ($Host.UI.RawUI.KeyAvailable) { + $k = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") + switch ($k.VirtualKeyCode) { + 49 { $keuze = "AZERTY" }; 97 { $keuze = "AZERTY" } + 50 { $keuze = "QWERTY" }; 98 { $keuze = "QWERTY" } + } + } + Start-Sleep -Milliseconds 150 + } + } catch {} + if (-not $keuze) { $keuze = "QWERTY" } + try { + $az = "080C:0000080C"; $qw = "0409:00020409" + $list = New-WinUserLanguageList -Language "nl-NL" + $list[0].InputMethodTips.Clear() + if ($keuze -eq "AZERTY") { + $list[0].InputMethodTips.Add($az); $list[0].InputMethodTips.Add($qw); $def = $az + } else { + $list[0].InputMethodTips.Add($qw); $list[0].InputMethodTips.Add($az); $def = $qw + } + Set-WinUserLanguageList $list -Force + Set-WinDefaultInputMethodOverride -InputTip $def -ErrorAction SilentlyContinue + } catch { Write-Log "Toetsenbord fout: $($_.Exception.Message)" "Red" } + return $keuze +} + +$GekozenToetsenbord = Set-KeyboardLayout +Write-Log "Toetsenbord: $GekozenToetsenbord" "Green" +Set-AtlasProfileKeyboard -Keuze $GekozenToetsenbord +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 0 OK: kb=$GekozenToetsenbord" + +# ============================================================= +# STAP 1: WiFi +# ============================================================= +Write-Phase "STAP 1: WiFi" +$WifiNaam = "MET_Wifi"; $WifiWW = "Metmet2021" +$WifiXml = "$WifiNaam$WifiNaamESSautoWPA2PSKAESfalsepassPhrasefalse$WifiWW" +$pf = "C:\Windows\Temp\MET_Wifi.xml"; $WifiXml | Out-File $pf -Encoding ASCII +$wifiOk = $false +try { + Set-Service WlanSvc -StartupType Automatic -ErrorAction SilentlyContinue + Start-Service WlanSvc -ErrorAction SilentlyContinue + Start-Sleep 3 + $wa = Get-NetAdapter -ErrorAction SilentlyContinue | + Where-Object { $_.PhysicalMediaType -match 'Native 802.11|Wireless' -or $_.InterfaceDescription -match 'Wi-Fi|Wireless|WLAN' } + if ($wa) { Write-Log "WiFi adapter: $($wa.InterfaceDescription)" "Green" } + else { Write-Log "GEEN WiFi adapter gevonden" "Red" } + netsh wlan add profile filename="$pf" | Out-Null + for ($i=1; $i -le 6 -and -not $wifiOk; $i++) { + netsh wlan connect name="$WifiNaam" | Out-Null; Start-Sleep 8 + $wifiOk = [bool](Get-NetConnectionProfile -ErrorAction SilentlyContinue | + Where-Object { $_.IPv4Connectivity -eq "Internet" }) + if (-not $wifiOk) { Write-Log "WiFi poging $i: geen internet" "Yellow" } + } + Write-Log "WiFi: $(if($wifiOk){'verbonden'}else{'MISLUKT'})" $(if($wifiOk){"Green"}else{"Red"}) +} catch { Write-Log "WiFi fout: $($_.Exception.Message)" "Red" } +if (Test-Path $pf) { [System.IO.File]::Delete($pf) } +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 1: WiFi=$wifiOk" + +# ============================================================= +# STAP 2: Windows Update +# ============================================================= +Write-Phase "STAP 2: Windows Update" +Set-Service wuauserv -StartupType Automatic -ErrorAction SilentlyContinue +Start-Service wuauserv -ErrorAction SilentlyContinue +Write-Log "Windows Update actief" "Green" +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 2 OK" + +# ============================================================= +# STAP 3: HP Image Assistant +# ============================================================= +Write-Phase "STAP 3: HP Image Assistant" +$HPIAPath = "C:\Windows\Temp\HPIA" +New-Item -Type Directory -Force $HPIAPath | Out-Null +$HPIALocs = @('C:\Atlas\HPImageAssistant.exe') +foreach ($d in [char[]](68..90)) { + $HPIALocs += "${d}:\Scripts\HPImageAssistant.exe" + $HPIALocs += "${d}:\scripts\HPImageAssistant.exe" +} +$HPIALauncher = $HPIALocs | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1 +if ($HPIALauncher) { + Write-Log "HPIA gevonden: $HPIALauncher" "Green" + Start-Process $HPIALauncher -ArgumentList "/s /e /f `"$HPIAPath`"" -Wait +} else { + Write-Log "HPIA downloaden van HP..." "Yellow" + try { + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest "https://ftp.hp.com/pub/caps-softpaq/cmit/HPIA.exe" -OutFile "$HPIAPath\HPIA_installer.exe" -UseBasicParsing -TimeoutSec 120 + Start-Process "$HPIAPath\HPIA_installer.exe" -ArgumentList "/s /e /f `"$HPIAPath`"" -Wait + } catch { Write-Log "HPIA download mislukt: $($_.Exception.Message)" "Red" } +} +$HPIAExe = (Get-ChildItem $HPIAPath -Filter "HPImageAssistant.exe" -Recurse -ErrorAction SilentlyContinue | + Sort-Object Length -Descending | Select-Object -First 1).FullName +if ($HPIAExe) { + Write-Log "HPIA uitvoeren (10-20 min)..." "Yellow" + $rpt = "$HPIAPath\Report"; New-Item -Type Directory -Force $rpt | Out-Null + $p = Start-Process $HPIAExe -ArgumentList @("/Operation:Analyze","/Action:Install","/Selection:All", + "/Silent","/Category:Drivers","/ReportFolder:`"$rpt`"") -Wait -PassThru -NoNewWindow + Write-Log "HPIA exitcode: $($p.ExitCode)" $(if($p.ExitCode -le 1){"Green"}else{"Yellow"}) + Copy-Item $rpt "$DebugDir\HPIA-report" -Recurse -Force -ErrorAction SilentlyContinue + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 3 OK: HPIA=$($p.ExitCode)" +} else { + Write-Log "HPIA niet gevonden - install drivers handmatig via hp.com/support" "Red" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 3 FAIL: HPIA niet gevonden" +} + +# ============================================================= +# STAP 4: Windows activering +# ============================================================= +Write-Phase "STAP 4: Windows activering" +$lic = Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" -ErrorAction SilentlyContinue | + Where-Object { $_.PartialProductKey } | Select-Object -First 1 +if ($lic.LicenseStatus -eq 1) { Write-Log "Geactiveerd (digitale licentie)" "Green" } +else { + Write-Log "Activeren via HWID..." "Yellow" + Start-Process cscript.exe -ArgumentList "//B //Nologo $env:windir\System32\slmgr.vbs /ato" -Wait -WindowStyle Hidden + $lic2 = Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" -ErrorAction SilentlyContinue | + Where-Object { $_.PartialProductKey } | Select-Object -First 1 + Write-Log "Activering: $($lic2.LicenseStatus) (1=OK)" $(if($lic2.LicenseStatus -eq 1){"Green"}else{"Yellow"}) +} +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 4 OK: lic=$($lic.LicenseStatus)" + +# ============================================================= +# STAP 5: Systeem optimaliseren +# ============================================================= +Write-Phase "STAP 5: Systeem optimaliseren" +reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search" /v "AllowCortana" /t REG_DWORD /d 0 /f | Out-Null +reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection" /v "AllowTelemetry" /t REG_DWORD /d 0 /f | Out-Null +reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\OneDrive" /v "DisableFileSyncNGSC" /t REG_DWORD /d 1 /f | Out-Null +Write-Log "Cortana/telemetrie/OneDrive uitgeschakeld" "Green" +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 5 OK" + +# ============================================================= +# STAP 6: Computernaam via serienummer +# ============================================================= +Write-Phase "STAP 6: Computernaam" +$newName = "ATLAS-UNKNOWN" +try { + $serial = (Get-CimInstance Win32_BIOS -ErrorAction SilentlyContinue).SerialNumber -replace '[^A-Z0-9]','' + $suffix = if ($serial -and $serial.Length -ge 4) { + $serial.Substring([Math]::Max(0, $serial.Length - 6)) + } else { + -join ((65..90) | Get-Random -Count 6 | ForEach-Object { [char]$_ }) + } + $newName = "ATLAS-$suffix" + Rename-Computer -NewName $newName -Force -ErrorAction Stop + Write-Log "Naam: $newName (serial: $serial)" "Green" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 6 OK: naam=$newName" +} catch { + Write-Log "Naam instellen mislukt: $($_.Exception.Message)" "Red" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 6 FAIL: $($_.Exception.Message)" +} + +# ============================================================= +# STAP 7: Tailscale + MeshCentral +# ============================================================= +Write-Phase "STAP 7: Fleet enrollment (Tailscale + MeshCentral)" +$FleetConfig = $null +foreach ($d in [char[]](65..90)) { + foreach ($sub in @('Scripts','scripts')) { + $p = "${d}:\${sub}\fleet.config" + if (Test-Path $p) { $FleetConfig = $p; break } + } + if ($FleetConfig) { break } +} +if (-not $FleetConfig -and (Test-Path 'C:\Atlas\fleet.config')) { $FleetConfig = 'C:\Atlas\fleet.config' } +$TsKey = "" +if ($FleetConfig) { + $TsKey = (Get-Content $FleetConfig -ErrorAction SilentlyContinue | + Where-Object { $_ -match '^TAILSCALE_AUTHKEY=' }) -replace '^TAILSCALE_AUTHKEY=','' + Write-Log "fleet.config: $FleetConfig" "Green" +} else { Write-Log "fleet.config niet gevonden" "Yellow" } + +# Tailscale +try { + $tsInst = "C:\Windows\Temp\tailscale-setup.exe" + Write-Log "Tailscale downloaden..." "Yellow" + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest "https://pkgs.tailscale.com/stable/tailscale-setup-latest.exe" -OutFile $tsInst -UseBasicParsing -TimeoutSec 120 + Start-Process $tsInst -ArgumentList "/install /quiet /norestart" -Wait + Start-Sleep 8 + if ($TsKey) { + & "C:\Program Files\Tailscale\tailscale.exe" up --authkey=$TsKey --hostname="$newName" --accept-routes 2>&1 | + ForEach-Object { Write-Log " TS: $_" "Cyan" } + } + [System.IO.File]::Delete($tsInst) + Write-Log "Tailscale OK" "Green" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 7a OK: Tailscale" +} catch { + Write-Log "Tailscale FAIL: $($_.Exception.Message)" "Red" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 7a FAIL: $($_.Exception.Message)" +} + +# MeshCentral +try { + $meshUrl = "http://100.93.16.81:4433/meshagents?id=3&meshid=@OfhMz3DBvRqrV8eZLhEi5PaRSBuMG5DHdwkY9A9oqXfzT3oNz1UOH3TLPRxIc0Ix&installflags=0&meshinstall=6" + $meshInst = "C:\Windows\Temp\meshagent-install.exe" + Write-Log "MeshCentral downloaden..." "Yellow" + Invoke-WebRequest $meshUrl -OutFile $meshInst -UseBasicParsing -TimeoutSec 60 + Start-Process $meshInst -ArgumentList "-fullinstall" -Wait + [System.IO.File]::Delete($meshInst) + Write-Log "MeshCentral OK" "Green" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 7b OK: MeshCentral" +} catch { + Write-Log "MeshCentral FAIL: $($_.Exception.Message)" "Red" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] Stap 7b FAIL: $($_.Exception.Message)" +} + +# ============================================================= +# STAP 8: Afronden +# ============================================================= +Write-Phase "STAP 8: Afronden" +try { Add-LocalGroupMember -SID 'S-1-5-32-544' -Member 'Atlas' -ErrorAction SilentlyContinue } catch {} +net user Atlas /passwordchg:no /expires:never | Out-Null +net user Administrator /active:no | Out-Null +Write-Log "Administrator uitgeschakeld" "Green" +reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AutoAdminLogon" /t REG_SZ /d "0" /f | Out-Null +reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "DefaultPassword" /f 2>$null | Out-Null +try { Unregister-ScheduledTask -TaskName "AtlasSetup" -Confirm:$false -ErrorAction SilentlyContinue } catch {} + +Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] SETUP VOLTOOID" + +Write-Log "" "White" +Write-Log "============================================" "Cyan" +Write-Log " SETUP VOLTOOID" "Green" +Write-Log "============================================" "Cyan" +Write-Log " Account: Atlas (admin, geen wachtwoord)" "Green" +Write-Log " Naam: $newName" "Green" +Write-Log " Toetsenbord: $GekozenToetsenbord" "Green" +Write-Log " Logs: $DebugDir\" "Green" +Write-Log "" "White" + +Export-LogsToUSB -Label "OK" + +} catch { + $em = $_.Exception.Message; $st = $_.ScriptStackTrace + Write-Log "!!! SCRIPT CRASH: $em" "Red" + Write-Log $st "Red" + Add-Content "$DebugDir\setup-phases.log" "[$(Get-Date -f 's')] CRASH: $em" + "$($PSVersionTable.PSVersion)`n$(Get-Date)`n$em`n$st" | Set-Content "$DebugDir\setup-crash.txt" + Export-LogsToUSB -Label "CRASH" + Write-Log "Crash logs op USB. Stuur AtlasLogs map door." "Yellow" + Start-Sleep 30 +} + +Stop-Transcript -ErrorAction SilentlyContinue +Start-Sleep 15 +Restart-Computer -Force diff --git a/Scripts/fleet.config.example b/Scripts/fleet.config.example new file mode 100644 index 0000000..8c1c241 --- /dev/null +++ b/Scripts/fleet.config.example @@ -0,0 +1,4 @@ +# Atlas Fleet Config — gelezen door Setup-Laptop.ps1 tijdens Windows-installatie +# Hernoem naar fleet.config en vul echte key in +# Genereer key via: tailscale.com/admin/settings/keys (Reusable, 90 dagen) +TAILSCALE_AUTHKEY=tskey-auth-REPLACE_WITH_REAL_KEY diff --git a/autounattend.xml b/autounattend.xml new file mode 100644 index 0000000..98a6d33 --- /dev/null +++ b/autounattend.xml @@ -0,0 +1,260 @@ + + + + + + + + + nl-NL + OnError + + 0409:00020409;080c:0000080c + nl-NL + nl-NL + en-US + nl-NL + + + + + + + true + Atlas + Atlas Corporation + + + + + 0 + true + + + 1 + EFI + 500 + + + 2 + MSR + 128 + + + 3 + Primary + true + + + + + 1 + 1 + + FAT32 + + + 2 + 2 + + + 3 + 3 + + C + NTFS + + + + + + + + + 0 + 3 + + + OnError + + + + + + + + + + + Atlas + W. Europe Standard Time + + + + 0409:00020409;080c:0000080c + nl-NL + nl-NL + en-US + nl-NL + + + + + + + + 1 + cmd.exe /c "mkdir C:\AtlasDebug 2>nul & echo [%DATE% %TIME%] Specialize gestart > C:\AtlasDebug\setup-phases.log" + Never + + + + + 2 + powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$null=New-Item -Type Directory -Force C:\Atlas,C:\AtlasDebug -ErrorAction SilentlyContinue; $found=$false; foreach($d in [char[]](65..90)){ foreach($sub in @('Scripts','scripts')){ $s=[IO.Path]::Combine($d+':\',$sub,'Setup-Laptop.ps1'); if(Test-Path $s){ Copy-Item $s C:\Atlas\ -Force; $f=[IO.Path]::Combine($d+':\',$sub,'fleet.config'); if(Test-Path $f){Copy-Item $f C:\Atlas\ -Force}; $h=[IO.Path]::Combine($d+':\',$sub,'HPImageAssistant.exe'); if(Test-Path $h){Copy-Item $h C:\Atlas\ -Force}; Add-Content C:\AtlasDebug\setup-phases.log ('['+[DateTime]::Now.ToString('s')+'] Bestanden gekopieerd van '+$d+':\'+$sub); $found=$true; break}}; if($found){break}}; if(-not $found){Add-Content C:\AtlasDebug\setup-phases.log '[WARN] Geen USB setup-bestanden gevonden'}" + Never + + + + + + + + + + + + + + . + true + 1 + + AtlasSetup123 + true</PlainText> + </Password> + <Username>Administrator</Username> + </AutoLogon> + + <FirstLogonCommands> + + <!-- Fase loggen --> + <SynchronousCommand wcm:action="add"> + <Order>1</Order> + <CommandLine>cmd.exe /c "echo [%DATE% %TIME%] FirstLogonCommands gestart >> C:\AtlasDebug\setup-phases.log"</CommandLine> + <RequiresUserInput>false</RequiresUserInput> + </SynchronousCommand> + + <!-- Panther setup-logs kopiëren voor diagnose --> + <SynchronousCommand wcm:action="add"> + <Order>2</Order> + <CommandLine>powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$null=New-Item -Type Directory -Force C:\AtlasDebug\panther; Copy-Item C:\Windows\Panther\*.log C:\AtlasDebug\panther\ -Force -ErrorAction SilentlyContinue; Copy-Item C:\Windows\Panther\*.xml C:\AtlasDebug\panther\ -ErrorAction SilentlyContinue; Add-Content C:\AtlasDebug\setup-phases.log ('['+[DateTime]::Now.ToString('s')+'] Panther logs gekopieerd')"</CommandLine> + <RequiresUserInput>false</RequiresUserInput> + </SynchronousCommand> + + <!-- Fallback: bestanden kopiëren als specialize dat niet deed --> + <SynchronousCommand wcm:action="add"> + <Order>3</Order> + <CommandLine>powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "if(-not(Test-Path 'C:\Atlas\Setup-Laptop.ps1')){ $null=New-Item -Type Directory -Force C:\Atlas; foreach($d in [char[]](68..90)){ foreach($sub in @('Scripts','scripts')){ $s=[IO.Path]::Combine($d+':\',$sub,'Setup-Laptop.ps1'); if(Test-Path $s){ Copy-Item $s C:\Atlas\ -Force; $f=[IO.Path]::Combine($d+':\',$sub,'fleet.config'); if(Test-Path $f){Copy-Item $f C:\Atlas\ -Force}; $h=[IO.Path]::Combine($d+':\',$sub,'HPImageAssistant.exe'); if(Test-Path $h){Copy-Item $h C:\Atlas\ -Force}; break}}}}"</CommandLine> + <RequiresUserInput>false</RequiresUserInput> + </SynchronousCommand> + + <!-- Setup-script uitvoeren --> + <SynchronousCommand wcm:action="add"> + <Order>4</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -NoProfile -WindowStyle Normal -File "C:\Atlas\Setup-Laptop.ps1"</CommandLine> + <Description>Atlas Laptop Setup</Description> + <RequiresUserInput>false</RequiresUserInput> + </SynchronousCommand> + + </FirstLogonCommands> + + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideLocalAccountScreen>true</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Home</NetworkLocation> + <ProtectYourPC>3</ProtectYourPC> + </OOBE> + + <TimeZone>W. Europe Standard Time</TimeZone> + + <UserAccounts> + <AdministratorPassword> + <Value>AtlasSetup123</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <DisplayName>Atlas</DisplayName> + <Group>Administrators</Group> + <Name>Atlas</Name> + <Password> + <Value>Atlas</Value> + <PlainText>true</PlainText> + </Password> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + + </component> + + <component name="Microsoft-Windows-International-Core" + processorArchitecture="amd64" + publicKeyToken="31bf3856ad364e35" + language="neutral" + versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> + <InputLocale>0409:00020409;080c:0000080c</InputLocale> + <SystemLocale>nl-NL</SystemLocale> + <UILanguage>nl-NL</UILanguage> + <UILanguageFallback>en-US</UILanguageFallback> + <UserLocale>nl-NL</UserLocale> + </component> + + </settings> + +</unattend> diff --git a/docs/SETUP.md b/docs/SETUP.md new file mode 100644 index 0000000..39df194 --- /dev/null +++ b/docs/SETUP.md @@ -0,0 +1,52 @@ +# USB Kit Setup Guide + +## Vereisten + +- Bootable Windows USB (gemaakt via Rufus of Media Creation Tool) +- HP EliteBook (of andere HP laptop met digitale Pro-licentie in BIOS) + +## Stap 1: Bestanden op USB zetten + +Kopieer naar de **root** van de USB: +- `autounattend.xml` + +Kopieer naar **Scripts/** op de USB: +- `Scripts/Setup-Laptop.ps1` +- `Scripts/fleet.config` (hernoem van fleet.config.example, vul echte Tailscale key in) +- `Scripts/HPImageAssistant.exe` (download van hp.com/support als je HPIA wilt) + +## Stap 2: Boot van USB + +1. HP: F9 voor boot menu +2. Kies de USB +3. Windows installeert volledig automatisch (geen klikken) + +## Stap 3: Setup-Laptop.ps1 + +Start automatisch na Windows-installatie: +1. Kies toetsenbord (AZERTY/QWERTY, 60s timeout = QWERTY) +2. WiFi verbinding (MET_Wifi / Metmet2021) +3. Windows Update inschakelen +4. HP Image Assistant: alle drivers installeren +5. Windows activering via BIOS digitale licentie +6. Computernaam instellen: ATLAS-[serienummer laatste 6 chars] +7. Tailscale enrollen + MeshCentral agent installeren +8. Administrator uitschakelen, opruimen, herstart + +## Debug: wat ging er fout? + +Na een mislukte of geslaagde install staan logs op: +- `C:\AtlasDebug\setup-phases.log` — welke stap succesvol/mislukt +- `C:\AtlasDebug\setup-transcript_*.txt` — volledige console output +- `C:\AtlasDebug\hardware-info.txt` — BIOS model, serial, editie, activering +- `C:\AtlasDebug\panther\*.log` — Windows PE setup logs + +**Als USB aanwezig is bij einde setup:** logs worden auto-gekopieerd naar `E:\AtlasLogs`. + +## Bekende bugs (opgelost in v2) + +| Bug | Symptoom | Oplossing | +|---|---|---| +| Core edition key op Pro BIOS | Setup crasht zonder foutmelding | Geen ProductKey in XML — BIOS bepaalt editie | +| Path-concatenatie fout in specialize | fleet.config niet gekopieerd | [IO.Path]::Combine() gebruikt | +| Geen logging | Bij crash weet je niks | Start-Transcript + hardware dump + USB export |