Autologon: Rueckmeldung nicht mehr verschlucken, Registry-Weg als Ausweg

Zwei Fehler in meinem Direkt-Zweig, beide behoben:
 (a) '& $exe ...' WARTET bei GUI-Anwendungen NICHT — das Skript las die
     Registry, bevor Autologon fertig war. Jetzt Start-Process -Wait -PassThru.
 (b) '$null = ... 2>&1' hat die Rueckmeldung verschluckt — genau die
     Information, die zur Diagnose noetig war, wurde weggeworfen. Jetzt werden
     ExitCode und Ausgabe gezeigt.

Zusaetzlich diagnostiziert: Autologon64.exe startet nur elevated (direkter
Aufruf aus einer normalen Sitzung scheitert mit 'erfordert erhoehte Rechte').
Der Windows-11-Blocker DevicePasswordLessBuildVersion ist NICHT gesetzt, war
also nicht die Ursache.

Neu als letzter Ausweg: der Registry-Weg, aber nur nach ausdruecklicher
Zustimmung und mit klarer Warnung — dort landet das Passwort im KLARTEXT unter
HKLM\...\Winlogon\DefaultPassword. Er funktioniert dafuer immer. Die
Entscheidung gehoert dem Nutzer, nicht dem Skript; das Entfernen-Kommando wird
gleich mit ausgegeben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-07 06:54:54 +02:00
co-authored by Claude Opus 5
parent b35f27541f
commit bdff39a278
+58 -7
View File
@@ -86,7 +86,24 @@ function Invoke-DirektAktivierung {
return $false
}
Write-Host " Aktiviere Auto-Logon ..."
$null = & $exe $env:USERNAME $env:COMPUTERNAME $pw /accepteula 2>&1
# ⚠⚠ ZWEI FEHLER AUS DEM VORIGEN VERSUCH, hier behoben:
# (a) `& $exe ...` WARTET BEI GUI-ANWENDUNGEN NICHT — das Skript las die
# Registry, bevor Autologon ueberhaupt fertig war.
# (b) `$null = ... 2>&1` hat die Rueckmeldung VERSCHLUCKT. Genau die
# Information, die zur Diagnose noetig war, wurde weggeworfen.
# Jetzt: warten, Exit-Code auswerten, Ausgabe zeigen.
$log = Join-Path $env:TEMP 'autologon_out.txt'
$p = Start-Process -FilePath $exe `
-ArgumentList $env:USERNAME, $env:COMPUTERNAME, $pw `
-Wait -PassThru -RedirectStandardOutput $log `
-RedirectStandardError "$log.err" -WindowStyle Hidden
Write-Host " Autologon ExitCode: $($p.ExitCode)"
foreach ($f in @($log, "$log.err")) {
if ((Test-Path $f) -and (Get-Item $f).Length -gt 0) {
Write-Host " Ausgabe: $((Get-Content $f -Raw).Trim())"
}
Remove-Item $f -EA SilentlyContinue
}
return $true
} finally {
# Klartext so kurz wie moeglich im Speicher halten
@@ -137,16 +154,50 @@ if (-not $aktiv -and -not $Direkt) {
}
}
# ── Letzter Ausweg: Registry-Weg ────────────────────────────────────────
# ⚠⚠ BEWUSST ALS LETZTE OPTION und nur nach ausdruecklicher Zustimmung. Hier
# landet das Passwort im KLARTEXT unter HKLM\...\Winlogon\DefaultPassword —
# lesbar fuer jeden lokalen Administrator und in jedem Backup-Image. Der einzige
# Vorteil: er funktioniert immer, ohne Fremdprogramm. Wenn Autologon (der
# sichere Weg) partout nicht greift, ist das die Alternative — die Entscheidung
# gehoert dem Nutzer, nicht dem Skript.
if (-not $aktiv) {
Write-Host ""
Write-Host " ==> AUTO-LOGON IST NICHT AKTIV." -ForegroundColor Yellow
Write-Host " Haeufigster Grund: falsches Passwort (Autologon meldet das"
Write-Host " nicht zurueck) oder Dialog nicht bestaetigt."
Write-Host " Erneut versuchen:" -ForegroundColor Cyan
Write-Host " powershell -ExecutionPolicy Bypass -File tools\autologon_einrichten.ps1 -Direkt" -ForegroundColor Cyan
Write-Host " Sysinternals Autologon hat nichts geschrieben."
Write-Host ""
Write-Host " Schritt 2 wird uebersprungen - eine Sperr-Aufgabe ohne"
Write-Host " Auto-Logon waere nur laestig."
Write-Host " ALTERNATIVE: der Registry-Weg." -ForegroundColor Cyan
Write-Host " ⚠ Dabei steht das Passwort im KLARTEXT in der Registry" -ForegroundColor Yellow
Write-Host " (HKLM\...\Winlogon\DefaultPassword). Jeder lokale Admin und"
Write-Host " jedes Backup-Image kann es lesen. Er funktioniert dafuer immer."
$a = Read-Host " Registry-Weg jetzt verwenden? (j/n)"
if ($a -notmatch '^[jJyY]') {
Write-Host " Abgebrochen. Schritt 2 uebersprungen."
exit 1
}
$sec = Read-Host " Passwort fuer $env:USERNAME (Eingabe bleibt unsichtbar)" -AsSecureString
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)
try {
$pw2 = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
if (-not $pw2) { Write-Host " Kein Passwort." -ForegroundColor Red; exit 1 }
Set-ItemProperty -Path $k -Name AutoAdminLogon -Value '1' -Type String
Set-ItemProperty -Path $k -Name DefaultUserName -Value $env:USERNAME -Type String
Set-ItemProperty -Path $k -Name DefaultDomainName -Value $env:COMPUTERNAME -Type String
Set-ItemProperty -Path $k -Name DefaultPassword -Value $pw2 -Type String
} finally {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
Remove-Variable pw2 -EA SilentlyContinue
}
$an = (Get-ItemProperty -Path $k -Name AutoAdminLogon -EA SilentlyContinue).AutoAdminLogon
$aktiv = ($an -eq '1')
Write-Host ""
Write-Host " AutoAdminLogon : $an"
Write-Host " ⚠ DefaultPassword steht jetzt im KLARTEXT in der Registry." -ForegroundColor Yellow
Write-Host " Entfernen mit: Remove-ItemProperty -Path '$k' -Name DefaultPassword"
}
if (-not $aktiv) {
Write-Host " ==> Auch das hat nicht gegriffen. Schritt 2 uebersprungen." -ForegroundColor Red
exit 1
}