Der Dialog-Weg ist zweimal ohne Ergebnis geblieben, weil er mit ENABLE bestaetigt werden muss. Statt den Nutzer ein drittes Mal tippen zu lassen, bietet das Skript nach einem abgebrochenen Dialog jetzt direkt an, es ohne Dialog zu erledigen (j/n) — die Aktivierung steckt dafuer in einer Funktion, die von beiden Wegen aufgerufen wird. Ausserdem ehrlicher in der Fehlerursache: ein falsches Passwort meldet Autologon nicht zurueck, das Ergebnis sieht dann genauso aus wie ein abgebrochener Dialog. Beides wird jetzt genannt statt nur eines. Mit dem echten 5.1-Parser geprueft, BOM gesetzt, Scan sauber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
193 lines
9.5 KiB
PowerShell
193 lines
9.5 KiB
PowerShell
# Auto-Logon einrichten — schliesst die letzte Luecke der Boot-Pipeline.
|
|
#
|
|
# WOZU: `OilTradingServer` und `HyperliquidDashboard` haengen an einem LOGON-
|
|
# Trigger. Nach einem Windows-Update-Reboot laeuft nichts, bis sich jemand
|
|
# anmeldet — real in der Nacht zum 2026-07-20 passiert (Reboot 01:30, Server bis
|
|
# 07:42 tot, nur der broker-seitige SL schuetzte, -95,48 EUR). Ein Task ohne
|
|
# angemeldete Sitzung hilft NICHT: der Bot braucht das laufende MT5-TERMINAL,
|
|
# und das ist eine GUI-Anwendung — es braucht eine echte Desktop-Sitzung.
|
|
#
|
|
# ⚠⚠ WARUM SYSINTERNALS UND NICHT DIE REGISTRY. Der verbreitete Weg schreibt
|
|
# das Passwort als `DefaultPassword` im KLARTEXT nach HKLM\...\Winlogon — dort
|
|
# kann es jeder lokale Administrator und jedes Backup-Image lesen. Sysinternals
|
|
# `Autologon` legt es als verschluesseltes LSA-Secret ab.
|
|
#
|
|
# ⚠ RESTRISIKO, das bleibt: nach dem Reboot steht eine ANGEMELDETE Sitzung mit
|
|
# offenem MT5 und Live-Broker-Verbindung da. Schritt 2 sperrt deshalb den
|
|
# Bildschirm — aber nur nach einem Auto-Logon, nicht nach jeder Anmeldung
|
|
# (s. `autologon_lock.ps1`).
|
|
#
|
|
# AUFRUF (Fenster muss ALS ADMINISTRATOR laufen):
|
|
# powershell -ExecutionPolicy Bypass -File tools\autologon_einrichten.ps1
|
|
#
|
|
# ⚠ Das Passwort steht NICHT in dieser Datei und wird nirgends gespeichert —
|
|
# es wird im GUI-Dialog von Autologon eingegeben.
|
|
#
|
|
# ⚠⚠ ZWEI FEHLER AUS DEM ERSTEN VERSUCH (2026-08-07), hier behoben:
|
|
# 1. `$ErrorActionPreference = 'Stop'` PLUS `schtasks /Delete` auf eine noch
|
|
# nicht existierende Aufgabe = das Skript brach ab, BEVOR /Create lief.
|
|
# Native Programme schreiben nach stderr, und PowerShell macht daraus unter
|
|
# 'Stop' einen Abbruch. Jetzt wird vorher geprueft, ob es sie ueberhaupt gibt.
|
|
# 2. Die Erfolgsmeldung log: fehlendes `DefaultPassword` wurde als
|
|
# "LSA-Secret ✅" gemeldet — dabei war schlicht GAR NICHTS gesetzt. Jetzt
|
|
# ist `AutoAdminLogon = 1` die Bedingung, und erst danach wird ueberhaupt
|
|
# ueber die Speicherart geurteilt.
|
|
|
|
# AUFRUF-VARIANTEN:
|
|
# ... -File tools\autologon_einrichten.ps1 GUI-Dialog (Standard)
|
|
# ... -File tools\autologon_einrichten.ps1 -Direkt ohne Dialog, Passwort
|
|
# wird hier abgefragt
|
|
# ⚠ `-Direkt` ist der zuverlaessige Weg. Der Dialog OEFFNET sich zwar
|
|
# (Fenstertitel "Autologon - Sysinternals", verifiziert), muss aber mit ENABLE
|
|
# bestaetigt werden — wird er nur geschlossen, passiert nichts.
|
|
# ⚠ Abwaegung bei `-Direkt`: Autologon 3.10 nimmt Benutzer/Domaene/Passwort als
|
|
# Argumente. Das Passwort steht damit fuer den Moment des Aufrufs in der
|
|
# Kommandozeile des Kindprozesses (fuer Administratoren kurz sichtbar). Es wird
|
|
# NICHT in eine Datei geschrieben, nicht in die PowerShell-History (Read-Host)
|
|
# und landet anschliessend als verschluesseltes LSA-Secret — nicht im Klartext
|
|
# in der Registry.
|
|
param([switch]$Direkt)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$hier = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$k = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
|
|
$t = 'OilAutoLogonLock'
|
|
|
|
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
if (-not (New-Object Security.Principal.WindowsPrincipal($id)).IsInRole(
|
|
[Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
Write-Host " ABBRUCH: Dieses Fenster hat keine Administratorrechte." -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
$exe = Join-Path $hier 'autologon\Autologon64.exe'
|
|
if (-not (Test-Path $exe)) { $exe = Join-Path $hier 'autologon\Autologon.exe' }
|
|
if (-not (Test-Path $exe)) {
|
|
Write-Host " ABBRUCH: Autologon.exe fehlt unter tools\autologon\." -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "=================================================================="
|
|
Write-Host " SCHRITT 1 - Auto-Logon aktivieren (verschluesseltes LSA-Secret)"
|
|
Write-Host "=================================================================="
|
|
Write-Host " Benutzer: $env:USERNAME Domaene: $env:COMPUTERNAME (lokal)"
|
|
# Aktivierung ohne Dialog — als Funktion, damit sie auch als Rueckfall nach
|
|
# einem abgebrochenen Dialog aufgerufen werden kann (sonst muesste der Nutzer
|
|
# das Skript ein drittes Mal starten).
|
|
function Invoke-DirektAktivierung {
|
|
# ⚠ Read-Host -AsSecureString: die Eingabe erscheint nicht auf dem Schirm
|
|
# und landet nicht in der PowerShell-History.
|
|
$sec = Read-Host " Passwort fuer $env:USERNAME (Eingabe bleibt unsichtbar)" -AsSecureString
|
|
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)
|
|
try {
|
|
$pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
|
|
if (-not $pw) {
|
|
Write-Host " Kein Passwort eingegeben." -ForegroundColor Red
|
|
return $false
|
|
}
|
|
Write-Host " Aktiviere Auto-Logon ..."
|
|
$null = & $exe $env:USERNAME $env:COMPUTERNAME $pw /accepteula 2>&1
|
|
return $true
|
|
} finally {
|
|
# Klartext so kurz wie moeglich im Speicher halten
|
|
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
|
|
Remove-Variable pw -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
if ($Direkt) {
|
|
if (-not (Invoke-DirektAktivierung)) { exit 1 }
|
|
} else {
|
|
Write-Host " Es oeffnet sich gleich der Autologon-Dialog." -ForegroundColor Cyan
|
|
Write-Host " --> Passwort eintragen und auf ENABLE klicken." -ForegroundColor Cyan
|
|
Write-Host " (Nur schliessen reicht NICHT - dann passiert nichts."
|
|
Write-Host " Zuverlaessiger: Skript mit -Direkt aufrufen.)"
|
|
Write-Host ""
|
|
Start-Process -FilePath $exe -ArgumentList '/accepteula' -Wait
|
|
}
|
|
|
|
# ── Ergebnis ehrlich pruefen ────────────────────────────────────────────
|
|
$an = (Get-ItemProperty -Path $k -Name AutoAdminLogon -EA SilentlyContinue).AutoAdminLogon
|
|
$user = (Get-ItemProperty -Path $k -Name DefaultUserName -EA SilentlyContinue).DefaultUserName
|
|
$klartext = (Get-ItemProperty -Path $k -Name DefaultPassword -EA SilentlyContinue).DefaultPassword
|
|
$aktiv = ($an -eq '1')
|
|
|
|
Write-Host ""
|
|
Write-Host " AutoAdminLogon : $(if ($an) { $an } else { '(nicht gesetzt)' })"
|
|
Write-Host " DefaultUserName : $(if ($user) { $user } else { '(nicht gesetzt)' })"
|
|
|
|
# ⚠ RUECKFALL statt Sackgasse: schlaegt der Dialog-Weg fehl, wird hier direkt
|
|
# angeboten, es ohne Dialog zu erledigen — sonst muesste das Skript ein drittes
|
|
# Mal von Hand gestartet werden (real zweimal passiert).
|
|
if (-not $aktiv -and -not $Direkt) {
|
|
Write-Host ""
|
|
Write-Host " ==> Der Dialog wurde ohne 'Enable' geschlossen." -ForegroundColor Yellow
|
|
$a = Read-Host " Jetzt ohne Dialog erledigen? (j/n)"
|
|
if ($a -match '^[jJyY]') {
|
|
if (Invoke-DirektAktivierung) {
|
|
$an = (Get-ItemProperty -Path $k -Name AutoAdminLogon -EA SilentlyContinue).AutoAdminLogon
|
|
$user = (Get-ItemProperty -Path $k -Name DefaultUserName -EA SilentlyContinue).DefaultUserName
|
|
$klartext = (Get-ItemProperty -Path $k -Name DefaultPassword -EA SilentlyContinue).DefaultPassword
|
|
$aktiv = ($an -eq '1')
|
|
Write-Host ""
|
|
Write-Host " AutoAdminLogon : $(if ($an) { $an } else { '(nicht gesetzt)' })"
|
|
Write-Host " DefaultUserName : $(if ($user) { $user } else { '(nicht gesetzt)' })"
|
|
}
|
|
}
|
|
}
|
|
|
|
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 ""
|
|
Write-Host " Schritt 2 wird uebersprungen - eine Sperr-Aufgabe ohne"
|
|
Write-Host " Auto-Logon waere nur laestig."
|
|
exit 1
|
|
}
|
|
|
|
if ($klartext) {
|
|
Write-Host " DefaultPassword : ⚠ KLARTEXT in der Registry!" -ForegroundColor Yellow
|
|
} else {
|
|
Write-Host " DefaultPassword : nicht im Klartext (LSA-Secret) ✅" -ForegroundColor Green
|
|
}
|
|
|
|
# ── Schritt 2: Bildschirmsperre nach dem Auto-Logon ─────────────────────
|
|
Write-Host ""
|
|
Write-Host "=================================================================="
|
|
Write-Host " SCHRITT 2 - Bildschirm nach dem Auto-Logon sperren"
|
|
Write-Host "=================================================================="
|
|
|
|
# ⚠ Erst pruefen, dann loeschen. `schtasks /Delete` auf eine fehlende Aufgabe
|
|
# schreibt nach stderr und wuerde unter $ErrorActionPreference='Stop' abbrechen.
|
|
$vorhanden = $false
|
|
try {
|
|
$null = & schtasks /Query /TN $t 2>&1
|
|
$vorhanden = ($LASTEXITCODE -eq 0)
|
|
} catch { $vorhanden = $false }
|
|
if ($vorhanden) {
|
|
$null = & schtasks /Delete /TN $t /F 2>&1
|
|
Write-Host " alte Aufgabe entfernt"
|
|
}
|
|
|
|
$lock = Join-Path $hier 'autologon_lock.ps1'
|
|
$cmd = "powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$lock`""
|
|
$null = & schtasks /Create /TN $t /SC ONLOGON /RU "$env:USERNAME" /DELAY 0000:30 /TR $cmd /F 2>&1
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host " Aufgabe '$t' angelegt." -ForegroundColor Green
|
|
Write-Host " Sperrt 30 s nach der Anmeldung - aber NUR, wenn der Rechner"
|
|
Write-Host " gerade gebootet hat. Nach manueller Anmeldung passiert nichts."
|
|
Write-Host " Die Sitzung laeuft weiter: MT5 und beide Server arbeiten."
|
|
} else {
|
|
Write-Host " ⚠ Aufgabe konnte nicht angelegt werden (Code $LASTEXITCODE)." -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host " Rueckgaengig:"
|
|
Write-Host " $exe /accepteula (dann Disable)"
|
|
Write-Host " schtasks /Delete /TN $t /F"
|