param( [string]$ReportPath = "G:\Gitea_Clone\homelab-infra\ops\windows-reinstall\docs\baerchen-app-license-readiness-2026-06-06.md" ) $ErrorActionPreference = "Stop" function Get-InstalledProgram { param([string[]]$NamePattern) $roots = @( "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" ) Get-ItemProperty $roots -ErrorAction SilentlyContinue | Where-Object { $display = $_.DisplayName if (-not $display) { return $false } foreach ($pattern in $NamePattern) { if ($display -like $pattern) { return $true } } return $false } | Sort-Object DisplayName | Select-Object DisplayName,DisplayVersion,Publisher,InstallDate } function Test-PathSummary { param([string]$Path) $item = Get-Item -LiteralPath $Path -ErrorAction SilentlyContinue if (-not $item) { return [pscustomobject]@{ Path = $Path Exists = $false Type = "" LastWriteTime = "" Bytes = "" } } $bytes = "" if ($item.PSIsContainer) { $measure = Get-ChildItem -LiteralPath $Path -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum $bytes = [int64]($measure.Sum) } else { $bytes = [int64]$item.Length } [pscustomobject]@{ Path = $Path Exists = $true Type = $(if ($item.PSIsContainer) { "Directory" } else { "File" }) LastWriteTime = $item.LastWriteTime.ToString("s") Bytes = $bytes } } function ConvertTo-MarkdownTable { param( [Parameter(ValueFromPipeline = $true)]$InputObject, [string[]]$Columns ) begin { $rows = @() } process { $rows += $InputObject } end { if (-not $rows -or $rows.Count -eq 0) { return "_Keine Treffer._" } $lines = @() $lines += "| " + ($Columns -join " | ") + " |" $lines += "| " + (($Columns | ForEach-Object { "---" }) -join " | ") + " |" foreach ($row in $rows) { $values = foreach ($column in $Columns) { $value = [string]$row.$column $value.Replace("|", "\|") } $lines += "| " + ($values -join " | ") + " |" } $lines -join "`n" } } $programGroups = [ordered]@{ "Passwortmanager / Browser" = @("*Bitwarden*", "*Vaultwarden*", "*1Password*", "*KeePass*", "*KeePassXC*", "*Chrome*", "*Microsoft Edge*", "*Brave*", "*Firefox*") "Banking4 / Subsembly" = @("*Banking4*", "*Subsembly*") "WISO / Buhl" = @("*WISO*", "*Buhl*") "Microsoft 365 / Office / OneDrive" = @("*Microsoft 365*", "*Microsoft Office*", "*Office 16*", "*OneDrive*") } $pathChecks = @( "C:\Users\michi\AppData\Local\Subsembly", "C:\Users\michi\AppData\Local\Buhl", "C:\Users\michi\AppData\Local\Buhl Data Service GmbH", "C:\ProgramData\Buhl Data Service GmbH", "C:\Users\michi\Documents\steuer", "C:\Users\michi\Desktop\Banking", "C:\Users\michi\OneDrive", "D:\30_Finanzen", "D:\30_Finanzen\Recovery-Codes", "D:\30_Finanzen\BitLocker-RecoveryKey-baerchen-2026-06-06.txt" ) $oneDriveProcess = Get-Process OneDrive -ErrorAction SilentlyContinue | Select-Object ProcessName,Id,StartTime $oneDriveAccounts = Get-ChildItem "HKCU:\Software\Microsoft\OneDrive\Accounts" -ErrorAction SilentlyContinue | Select-Object PSChildName $officeCscript = @( "$env:ProgramFiles\Microsoft Office\Office16\OSPP.VBS", "${env:ProgramFiles(x86)}\Microsoft Office\Office16\OSPP.VBS" ) | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1 $officeStatus = @() if ($officeCscript) { $raw = & cscript.exe //Nologo $officeCscript /dstatus 2>$null $officeStatus = $raw | Where-Object { $_ -match "LICENSE NAME|LICENSE STATUS|ERROR CODE|Last 5 characters" } | ForEach-Object { $_.Trim() } } $lines = @() $lines += "# baerchen App-/Lizenz-Readiness - 2026-06-06" $lines += "" $lines += "Automatisch erzeugter lokaler Check. Keine Lizenzkeys, Passwoerter, Tokens oder Recovery-Code-Werte wurden ausgelesen oder ins Repo geschrieben." $lines += "" $lines += "## Ergebnis" $lines += "" $lines += "- Technische Inventarisierung: erledigt" $lines += "- Manuelle Konto-/Recovery-Bestaetigung: weiterhin Operator-Schritt" $lines += "" $lines += "## Installierte Programme" $lines += "" foreach ($group in $programGroups.Keys) { $lines += "### $group" $lines += "" $programs = Get-InstalledProgram -NamePattern $programGroups[$group] $lines += ($programs | ConvertTo-MarkdownTable -Columns DisplayName,DisplayVersion,Publisher,InstallDate) $lines += "" } $lines += "## Relevante Datenpfade" $lines += "" $pathResults = $pathChecks | ForEach-Object { Test-PathSummary $_ } $lines += ($pathResults | ConvertTo-MarkdownTable -Columns Path,Exists,Type,LastWriteTime,Bytes) $lines += "" $lines += "## OneDrive / Microsoft 365 Indikatoren" $lines += "" $lines += "### OneDrive Prozess" $lines += "" $lines += ($oneDriveProcess | ConvertTo-MarkdownTable -Columns ProcessName,Id,StartTime) $lines += "" $lines += "### OneDrive Accounts Registry" $lines += "" $lines += ($oneDriveAccounts | ConvertTo-MarkdownTable -Columns PSChildName) $lines += "" $lines += "### Office Aktivierungsindikatoren" $lines += "" if ($officeStatus.Count -gt 0) { $lines += '```text' $lines += $officeStatus $lines += '```' } else { $lines += "_Keine Office-OSPP-Aktivierungsdaten gefunden oder Office nicht klassisch installiert._" } $lines += "" $lines += "## Manuell noch zu bestaetigen" $lines += "" $lines += "- [ ] Passwortmanager laesst sich oeffnen und enthaelt Homelab-/Banking-/Provider-Eintraege." $lines += "- [ ] 2FA-Recovery-Codes fuer Microsoft, Hetzner, Cloudflare, Tailscale, Gitea/GitHub und Banken sind offline oder in Vaultwarden auffindbar." $lines += "- [ ] Banking4 oeffnet den aktuellen Datentresor; ein frischer Backup-/Exportpfad ist bekannt." $lines += '- [ ] WISO Steuer 2026 oeffnet, Buhl-Konto/Lizenz ist aktiv, Steuerdateien unter `C:\Users\michi\Documents\steuer` bzw. neuem Zielpfad sind sichtbar.' $lines += "- [ ] Microsoft-Konto zeigt aktives M365/Office-Installationsrecht." $lines += "- [ ] OneDrive-Sync ist angemeldet und synchronisiert die erwarteten Ordner." $lines += "" $lines += "## Bewertung" $lines += "" $lines += 'Dieses Dokument ersetzt nicht die manuelle Kontoanmeldung. Es belegt nur, welche lokalen Programme, Datenpfade und Aktivierungsindikatoren auf `baerchen` sichtbar waren.' New-Item -ItemType Directory -Force -Path (Split-Path -Parent $ReportPath) | Out-Null $lines -join "`r`n" | Set-Content -LiteralPath $ReportPath -Encoding UTF8 Write-Host "Report written: $ReportPath"