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
This commit is contained in:
parent
6442edb2e2
commit
5666a8df0d
@ -2,20 +2,12 @@
|
|||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Liest den SCCM/MECM-Deployment-Status der letzten Anwendungen auf einem entfernten Client aus.
|
Liest den SCCM/MECM-Deployment-Status der letzten Anwendungen auf einem entfernten Client aus.
|
||||||
.DESCRIPTION
|
.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.
|
zu Beginn immer nach Benutzername und Passwort.
|
||||||
|
|
||||||
Es zeigt standardmaessig die letzten Anwendungen mit Deployment-Aktivitaet an:
|
Es zeigt standardmaessig die letzten Anwendungen mit Deployment-Aktivitaet an.
|
||||||
- Ob der Content bereits "angekommen" ist (Download abgeschlossen)
|
Mit -DebugDetails werden zusaetzliche Pruefschritte ausgegeben, damit man
|
||||||
- In welchem Cache-Ordner der Content liegt
|
erkennen kann, wo Log-Zugriff, App-Erkennung oder Regex-Parsing fehlschlaegt.
|
||||||
- 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
|
|
||||||
.PARAMETER ComputerName
|
.PARAMETER ComputerName
|
||||||
Name oder IP des Ziel-Clients.
|
Name oder IP des Ziel-Clients.
|
||||||
.PARAMETER CCMPath
|
.PARAMETER CCMPath
|
||||||
@ -24,10 +16,12 @@
|
|||||||
Anzahl der letzten Anwendungen, die angezeigt werden sollen (Default: 5).
|
Anzahl der letzten Anwendungen, die angezeigt werden sollen (Default: 5).
|
||||||
.PARAMETER Detailed
|
.PARAMETER Detailed
|
||||||
Schaltet zusaetzliche Roh-Logauszuege ein.
|
Schaltet zusaetzliche Roh-Logauszuege ein.
|
||||||
|
.PARAMETER DebugDetails
|
||||||
|
Schaltet Debug-Ausgaben zu Zugriff, Logs, Regex und Auswahl ein.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
.\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01
|
.\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
.\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01 -Last 10 -Detailed
|
.\Get-SCCMAppDeployment.ps1 -ComputerName CLIENT01 -Last 10 -Detailed -DebugDetails
|
||||||
#>
|
#>
|
||||||
|
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
@ -39,7 +33,9 @@ param(
|
|||||||
|
|
||||||
[int]$Last = 5,
|
[int]$Last = 5,
|
||||||
|
|
||||||
[switch]$Detailed
|
[switch]$Detailed,
|
||||||
|
|
||||||
|
[switch]$DebugDetails
|
||||||
)
|
)
|
||||||
|
|
||||||
#region Nachschlagetabellen ---------------------------------------------------
|
#region Nachschlagetabellen ---------------------------------------------------
|
||||||
@ -107,9 +103,10 @@ function Parse-SCCMLog {
|
|||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param([Parameter(Mandatory)][string[]]$Content)
|
param([Parameter(Mandatory)][string[]]$Content)
|
||||||
$re = '^<!\[LOG\[(?<msg>.*?)\]LOG\]!><time="(?<time>[^"]*)" date="(?<date>[^"]*)" component="(?<comp>[^"]*)" context="[^"]*" type="(?<type>\d)" thread="[^"]*" file="[^"]*">'
|
$re = '^<!\[LOG\[(?<msg>.*?)\]LOG\]!><time="(?<time>[^"]*)" date="(?<date>[^"]*)" component="(?<comp>[^"]*)" context="[^"]*" type="(?<type>\d)" thread="[^"]*" file="[^"]*">'
|
||||||
|
$parsed = @()
|
||||||
foreach ($line in $Content) {
|
foreach ($line in $Content) {
|
||||||
if ($line -match $re) {
|
if ($line -match $re) {
|
||||||
[PSCustomObject]@{
|
$parsed += [PSCustomObject]@{
|
||||||
Time = "$($Matches.date) $($Matches.time)"
|
Time = "$($Matches.date) $($Matches.time)"
|
||||||
Component = $Matches.comp
|
Component = $Matches.comp
|
||||||
Type = [int]$Matches.type
|
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 {
|
function Get-RemoteCCMLog {
|
||||||
@ -126,6 +131,8 @@ function Get-RemoteCCMLog {
|
|||||||
[string]$LogName
|
[string]$LogName
|
||||||
)
|
)
|
||||||
$path = "\\$ComputerName\C$\Windows\CCM\Logs\$LogName"
|
$path = "\\$ComputerName\C$\Windows\CCM\Logs\$LogName"
|
||||||
|
Write-DebugLine "Pruefe Log-Pfad: $path"
|
||||||
|
|
||||||
if (-not (Test-Path $path)) {
|
if (-not (Test-Path $path)) {
|
||||||
Write-Warning "Log nicht vorhanden: $path"
|
Write-Warning "Log nicht vorhanden: $path"
|
||||||
return @()
|
return @()
|
||||||
@ -163,7 +170,9 @@ function Get-RemoteCCMLog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-DebugLine "$LogName geladen: $($content.Count) Zeilen"
|
||||||
$entries = Parse-SCCMLog -Content $content
|
$entries = Parse-SCCMLog -Content $content
|
||||||
|
Write-DebugLine "$LogName geparst: $($entries.Count) Eintraege"
|
||||||
return $entries
|
return $entries
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,14 +198,21 @@ else {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$credPassPlain = $credPass
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Logs laden ------------------------------------------------------------
|
#region Logs laden ------------------------------------------------------------
|
||||||
|
|
||||||
|
Write-Host "`n=== Lade Logs ===" -ForegroundColor Cyan
|
||||||
$appAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'AppDiscovery.log'
|
$appAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'AppDiscovery.log'
|
||||||
$appEnfAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'AppEnforce.log'
|
$appEnfAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'AppEnforce.log'
|
||||||
$casAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'CAS.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
|
#endregion
|
||||||
|
|
||||||
#region Apps ueber Logs ermitteln ---------------------------------------------
|
#region Apps ueber Logs ermitteln ---------------------------------------------
|
||||||
@ -204,8 +220,14 @@ $casAll = Get-RemoteCCMLog -ComputerName $ComputerName -LogName 'CAS.log'
|
|||||||
$appsWithChanges = @()
|
$appsWithChanges = @()
|
||||||
$appNames = @{}
|
$appNames = @{}
|
||||||
|
|
||||||
|
Write-DebugLine "Suche Application-Namen in AppEnforce..."
|
||||||
|
$sampleAppMatches = 0
|
||||||
foreach ($entry in $appEnfAll) {
|
foreach ($entry in $appEnfAll) {
|
||||||
if ($entry.Message -match '(?i)application\s+"([^"]+)"') {
|
if ($entry.Message -match '(?i)application\s+"([^"]+)"') {
|
||||||
|
$sampleAppMatches++
|
||||||
|
if ($sampleAppMatches -le 5) {
|
||||||
|
Write-DebugLine "Match: $($Matches[1])"
|
||||||
|
}
|
||||||
$name = $Matches[1]
|
$name = $Matches[1]
|
||||||
if (-not $appNames.ContainsKey($name)) {
|
if (-not $appNames.ContainsKey($name)) {
|
||||||
$appNames[$name] = $true
|
$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
|
$appsWithChanges = $appsWithChanges | Sort-Object -Property LastChange -Descending
|
||||||
$selectedApps = $appsWithChanges | Select-Object -First $Last
|
$selectedApps = $appsWithChanges | Select-Object -First $Last
|
||||||
|
|
||||||
|
Write-DebugLine "Ausgewaehlte Anwendungen: $($selectedApps.Count)"
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Auswertung -------------------------------------------------------------
|
#region Auswertung -------------------------------------------------------------
|
||||||
@ -229,6 +262,10 @@ $results = foreach ($entry in $selectedApps) {
|
|||||||
$appEnf = $appEnfAll | Where-Object { $_.Message -like "*$ApplicationName*" }
|
$appEnf = $appEnfAll | Where-Object { $_.Message -like "*$ApplicationName*" }
|
||||||
$appDisc = $appAll | 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
|
# Content
|
||||||
$contentIds = @()
|
$contentIds = @()
|
||||||
foreach ($e in $appEnf) {
|
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] }
|
elseif ($e.Message -match 'ContentId ([A-Fa-f0-9-]{8,})') { $contentIds += $Matches[1] }
|
||||||
}
|
}
|
||||||
$contentIds = $contentIds | Sort-Object -Unique
|
$contentIds = $contentIds | Sort-Object -Unique
|
||||||
|
Write-DebugLine " ContentIds gefunden: $($contentIds.Count)"
|
||||||
|
|
||||||
$cachePaths = @()
|
$cachePaths = @()
|
||||||
foreach ($cid in $contentIds) {
|
foreach ($cid in $contentIds) {
|
||||||
@ -244,6 +282,7 @@ $results = foreach ($entry in $selectedApps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$cachePaths = $cachePaths | Sort-Object -Unique
|
$cachePaths = $cachePaths | Sort-Object -Unique
|
||||||
|
Write-DebugLine " Cache-Pfade gefunden: $($cachePaths.Count)"
|
||||||
|
|
||||||
$arrivedInCache = $cachePaths.Count -gt 0
|
$arrivedInCache = $cachePaths.Count -gt 0
|
||||||
$cacheFolder = $cachePaths -join "`n"
|
$cacheFolder = $cachePaths -join "`n"
|
||||||
@ -253,6 +292,7 @@ $results = foreach ($entry in $selectedApps) {
|
|||||||
if ($cacheParts) {
|
if ($cacheParts) {
|
||||||
$cacheFolder = ($cacheParts -join "`n")
|
$cacheFolder = ($cacheParts -join "`n")
|
||||||
$arrivedInCache = $true
|
$arrivedInCache = $true
|
||||||
|
Write-DebugLine " Cache ueber Keywords erkannt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +335,8 @@ $results = foreach ($entry in $selectedApps) {
|
|||||||
#region Ausgabe ----------------------------------------------------------------
|
#region Ausgabe ----------------------------------------------------------------
|
||||||
|
|
||||||
Write-Host "`n===== SCCM-Deployment-Status: letzte $Last Anwendungen @ $ComputerName =====" -ForegroundColor Cyan
|
Write-Host "`n===== SCCM-Deployment-Status: letzte $Last Anwendungen @ $ComputerName =====" -ForegroundColor Cyan
|
||||||
foreach ($r in $results) {
|
if ($results) {
|
||||||
|
foreach ($r in $results) {
|
||||||
Write-Host ("`nAnwendung : {0}" -f $r.Application) -ForegroundColor Cyan
|
Write-Host ("`nAnwendung : {0}" -f $r.Application) -ForegroundColor Cyan
|
||||||
Write-Host ("InstallState : {0}" -f $r.InstallState)
|
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 ("Angekommen/Cache : {0}" -f $(if ($r.Angekommen) { 'JA' } else { 'NEIN' })) -ForegroundColor $(if ($r.Angekommen) { 'Green' } else { 'Yellow' })
|
||||||
@ -308,6 +349,11 @@ foreach ($r in $results) {
|
|||||||
if ($Detailed) {
|
if ($Detailed) {
|
||||||
Write-Host ("Fehlerdetails : {0}" -f $r.InstallFehler) -ForegroundColor DarkGray
|
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 ""
|
Write-Host ""
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user