From 5666a8df0d746acb5b86a60097e159bd824775eb Mon Sep 17 00:00:00 2001 From: buiaca Date: Wed, 29 Jul 2026 08:07:52 +0200 Subject: [PATCH] feat(Hermmes): DebugDetails fuer Get-SCCMAppDeployment hinzufuegen - neue Option -DebugDetails - zeigt Pruefung der ChBcPfade, Log-Zugriff, Zeilen-/Trefferanzahlen - zeigt Fallbeispiele aus AppEnforce, wenn keine Anwendung erkannt wird - zeigt fuer jede Anwendung Detailzaehler fuer Regex, Cache, Detection --- Hermes/Get-SCCMAppDeployment.ps1 | 100 ++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/Hermes/Get-SCCMAppDeployment.ps1 b/Hermes/Get-SCCMAppDeployment.ps1 index c2b9d75..d075c28 100644 --- a/Hermes/Get-SCCMAppDeployment.ps1 +++ b/Hermes/Get-SCCMAppDeployment.ps1 @@ -2,20 +2,12 @@ .SYNOPSIS Liest den SCCM/MECM-Deployment-Status der letzten Anwendungen auf einem entfernten Client aus. .DESCRIPTION - Das Skript greift ueber dieAdmin-Freigabe C$ auf die CCM-Logs zu und fragt + Das Skript greift ueber die Admin-Freigabe C$ auf die CCM-Logs zu und fragt zu Beginn immer nach Benutzername und Passwort. - Es zeigt standardmaessig die letzten Anwendungen mit Deployment-Aktivitaet an: - - Ob der Content bereits "angekommen" ist (Download abgeschlossen) - - In welchem Cache-Ordner der Content liegt - - Welche Erkennungsmethode (Detection) greift und deren Ergebnis - - Ob die Installation bereits begonnen hat, erfolgreich war oder warum nicht - (Fehlercode + begruendende Log-Zeilen) - - Quellen: - - AppDiscovery.log - - AppEnforce.log - - CAS.log + Es zeigt standardmaessig die letzten Anwendungen mit Deployment-Aktivitaet an. + Mit -DebugDetails werden zusaetzliche Pruefschritte ausgegeben, damit man + erkennen kann, wo Log-Zugriff, App-Erkennung oder Regex-Parsing fehlschlaegt. .PARAMETER ComputerName Name oder IP des Ziel-Clients. .PARAMETER CCMPath @@ -24,10 +16,12 @@ Anzahl der letzten Anwendungen, die angezeigt werden sollen (Default: 5). .PARAMETER Detailed Schaltet zusaetzliche Roh-Logauszuege ein. +.PARAMETER DebugDetails + Schaltet Debug-Ausgaben zu Zugriff, Logs, Regex und Auswahl ein. .EXAMPLE .\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01 .EXAMPLE - .\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01 -Last 10 -Detailed + .\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01 -Last 10 -Detailed -DebugDetails #> [CmdletBinding()] @@ -39,7 +33,9 @@ param( [int]$Last = 5, - [switch]$Detailed + [switch]$Detailed, + + [switch]$DebugDetails ) #region Nachschlagetabellen --------------------------------------------------- @@ -107,9 +103,10 @@ function Parse-SCCMLog { [CmdletBinding()] param([Parameter(Mandatory)][string[]]$Content) $re = '^.*?)\]LOG\]!>[^"]*)" date="(?[^"]*)" component="(?[^"]*)" context="[^"]*" type="(?\d)" thread="[^"]*" file="[^"]*">' + $parsed = @() foreach ($line in $Content) { if ($line -match $re) { - [PSCustomObject]@{ + $parsed += [PSCustomObject]@{ Time = "$($Matches.date) $($Matches.time)" Component = $Matches.comp Type = [int]$Matches.type @@ -117,6 +114,14 @@ function Parse-SCCMLog { } } } + return $parsed +} + +function Write-DebugLine { + param([string]$Message) + if ($DebugDetails) { + Write-Host "[DEBUG] $Message" -ForegroundColor DarkYellow + } } function Get-RemoteCCMLog { @@ -126,6 +131,8 @@ function Get-RemoteCCMLog { [string]$LogName ) $path = "\\$ComputerName\C$\Windows\CCM\Logs\$LogName" + Write-DebugLine "Pruefe Log-Pfad: $path" + if (-not (Test-Path $path)) { Write-Warning "Log nicht vorhanden: $path" return @() @@ -163,7 +170,9 @@ function Get-RemoteCCMLog { } } + Write-DebugLine "$LogName geladen: $($content.Count) Zeilen" $entries = Parse-SCCMLog -Content $content + Write-DebugLine "$LogName geparst: $($entries.Count) Eintraege" return $entries } @@ -189,14 +198,21 @@ else { } } +$credPassPlain = $credPass + #endregion #region Logs laden ------------------------------------------------------------ +Write-Host "`n=== Lade Logs ===" -ForegroundColor Cyan $appAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'AppDiscovery.log' $appEnfAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'AppEnforce.log' $casAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'CAS.log' +Write-DebugLine "AppDiscovery: $($appAll.Count) Eintraege" +Write-DebugLine "AppEnforce: $($appEnfAll.Count) Eintraege" +Write-DebugLine "CAS: $($casAll.Count) Eintraege" + #endregion #region Apps ueber Logs ermitteln --------------------------------------------- @@ -204,8 +220,14 @@ $casAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'CAS.log' $appsWithChanges = @() $appNames = @{} +Write-DebugLine "Suche Application-Namen in AppEnforce..." +$sampleAppMatches = 0 foreach ($entry in $appEnfAll) { if ($entry.Message -match '(?i)application\s+"([^"]+)"') { + $sampleAppMatches++ + if ($sampleAppMatches -le 5) { + Write-DebugLine "Match: $($Matches[1])" + } $name = $Matches[1] if (-not $appNames.ContainsKey($name)) { $appNames[$name] = $true @@ -216,10 +238,21 @@ foreach ($entry in $appEnfAll) { } } } +Write-DebugLine "AppEnforce-Matches gesamt: $sampleAppMatches" +Write-DebugLine "Eindeutige Anwendungsnamen: $($appNames.Count)" + +if ($appsWithChanges.Count -eq 0) { + Write-Warning "Keine Anwendungen ueber Regex in AppEnforce gefunden." + Write-Host "`n=== DEBUG: Fallbeispiele AppEnforce ===" -ForegroundColor Yellow + $appEnfAll | Select-Object -First 20 | ForEach-Object { Write-Host $_.Message } + Write-Host "=== Ende DEBUG ===`n" -ForegroundColor Yellow +} $appsWithChanges = $appsWithChanges | Sort-Object -Property LastChange -Descending $selectedApps = $appsWithChanges | Select-Object -First $Last +Write-DebugLine "Ausgewaehlte Anwendungen: $($selectedApps.Count)" + #endregion #region Auswertung ------------------------------------------------------------- @@ -229,6 +262,10 @@ $results = foreach ($entry in $selectedApps) { $appEnf = $appEnfAll | Where-Object { $_.Message -like "*$ApplicationName*" } $appDisc = $appAll | Where-Object { $_.Message -like "*$ApplicationName*" } + Write-DebugLine "Auswerte: $ApplicationName" + Write-DebugLine " AppEnforce-Zeilen: $($appEnf.Count)" + Write-DebugLine " AppDiscovery-Zeilen: $($appDisc.Count)" + # Content $contentIds = @() foreach ($e in $appEnf) { @@ -236,6 +273,7 @@ $results = foreach ($entry in $selectedApps) { elseif ($e.Message -match 'ContentId ([A-Fa-f0-9-]{8,})') { $contentIds += $Matches[1] } } $contentIds = $contentIds | Sort-Object -Unique + Write-DebugLine " ContentIds gefunden: $($contentIds.Count)" $cachePaths = @() foreach ($cid in $contentIds) { @@ -244,6 +282,7 @@ $results = foreach ($entry in $selectedApps) { } } $cachePaths = $cachePaths | Sort-Object -Unique + Write-DebugLine " Cache-Pfade gefunden: $($cachePaths.Count)" $arrivedInCache = $cachePaths.Count -gt 0 $cacheFolder = $cachePaths -join "`n" @@ -253,6 +292,7 @@ $results = foreach ($entry in $selectedApps) { if ($cacheParts) { $cacheFolder = ($cacheParts -join "`n") $arrivedInCache = $true + Write-DebugLine " Cache ueber Keywords erkannt" } } @@ -295,20 +335,26 @@ $results = foreach ($entry in $selectedApps) { #region Ausgabe ---------------------------------------------------------------- Write-Host "`n===== SCCM-Deployment-Status: letzte $Last Anwendungen @ $ComputerName =====" -ForegroundColor Cyan -foreach ($r in $results) { - Write-Host ("`nAnwendung : {0}" -f $r.Application) -ForegroundColor Cyan - Write-Host ("InstallState : {0}" -f $r.InstallState) - Write-Host ("Angekommen/Cache : {0}" -f $(if ($r.Angekommen) { 'JA' } else { 'NEIN' })) -ForegroundColor $(if ($r.Angekommen) { 'Green' } else { 'Yellow' }) - Write-Host ("Cache-Pfad : {0}" -f $r.CachePfad) - Write-Host ("Detection : {0}" -f $r.DetectionErgebnis) - Write-Host ("Install gestartet: {0}" -f $(if ($r.InstallStarted) { 'JA' } else { 'NEIN' })) - Write-Host ("Install fertig : {0}" -f $(if ($r.InstallAbgeschlossen) { 'JA' } else { 'NEIN' })) - Write-Host ("Letzte Aenderung : {0}" -f $r.LetzteAenderung) - Write-Host ("Grund/Status : {0}" -f $r.Grund) -ForegroundColor $(if ($r.Grund -match 'Erfolg|abgeschlossen|erfolgreich|erkannt') { 'Green' } else { 'Yellow' }) - if ($Detailed) { - Write-Host ("Fehlerdetails : {0}" -f $r.InstallFehler) -ForegroundColor DarkGray +if ($results) { + foreach ($r in $results) { + Write-Host ("`nAnwendung : {0}" -f $r.Application) -ForegroundColor Cyan + Write-Host ("InstallState : {0}" -f $r.InstallState) + Write-Host ("Angekommen/Cache : {0}" -f $(if ($r.Angekommen) { 'JA' } else { 'NEIN' })) -ForegroundColor $(if ($r.Angekommen) { 'Green' } else { 'Yellow' }) + Write-Host ("Cache-Pfad : {0}" -f $r.CachePfad) + Write-Host ("Detection : {0}" -f $r.DetectionErgebnis) + Write-Host ("Install gestartet: {0}" -f $(if ($r.InstallStarted) { 'JA' } else { 'NEIN' })) + Write-Host ("Install fertig : {0}" -f $(if ($r.InstallAbgeschlossen) { 'JA' } else { 'NEIN' })) + Write-Host ("Letzte Aenderung : {0}" -f $r.LetzteAenderung) + Write-Host ("Grund/Status : {0}" -f $r.Grund) -ForegroundColor $(if ($r.Grund -match 'Erfolg|abgeschlossen|erfolgreich|erkannt') { 'Green' } else { 'Yellow' }) + if ($Detailed) { + Write-Host ("Fehlerdetails : {0}" -f $r.InstallFehler) -ForegroundColor DarkGray + } } } +else { + Write-Host "Es wurden keine Anwendungen zur Anzeige ausgewaehlt." -ForegroundColor Red + Write-Host "Hinweis: Starte das Script mit -DebugDetails, um zu sehen, wo es haengt." -ForegroundColor Yellow +} Write-Host "" # Als Objekte zurueckgeben