#Requires -RunAsAdministrator # GuruRMM Agent Install Diagnostic # Run on GND-SERVER after MSI install attempt $out = [System.Collections.Generic.List[string]]::new() function Log($msg) { $out.Add($msg); Write-Host $msg } function Section($title) { Log ""; Log ("=" * 60); Log " $title"; Log ("=" * 60) } Section "SYSTEM INFO" Log "Hostname: $env:COMPUTERNAME" Log "Date/Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" Log "OS: $((Get-CimInstance Win32_OperatingSystem).Caption)" Log "Arch: $env:PROCESSOR_ARCHITECTURE" Section "SERVICE STATUS" $svc = Get-Service -Name "gururmm*" -ErrorAction SilentlyContinue if ($svc) { foreach ($s in $svc) { Log "Name: $($s.Name)" Log "DisplayName: $($s.DisplayName)" Log "Status: $($s.Status)" Log "StartType: $($s.StartType)" } } else { Log "[NOT FOUND] No service matching 'gururmm*'" } Section "SERVICE BINARY" $svcWmi = Get-WmiObject Win32_Service -Filter "Name LIKE 'gururmm%'" -ErrorAction SilentlyContinue if ($svcWmi) { Log "PathName: $($svcWmi.PathName)" Log "StartName: $($svcWmi.StartName)" $binPath = $svcWmi.PathName -replace '"','' if (Test-Path $binPath) { $bin = Get-Item $binPath Log "Binary: $($bin.FullName)" Log "Size: $($bin.Length) bytes" Log "Modified: $($bin.LastWriteTime)" $ver = (Get-Item $binPath).VersionInfo Log "FileVersion: $($ver.FileVersion)" } else { Log "[NOT FOUND] Binary path does not exist: $binPath" } } else { Log "[NOT FOUND] No WMI service entry for gururmm" } Section "REGISTRY" $regPath = "HKLM:\SOFTWARE\GuruRMM" if (Test-Path $regPath) { Log "Key exists: $regPath" Get-ItemProperty $regPath -ErrorAction SilentlyContinue | ForEach-Object { $_.PSObject.Properties | Where-Object { $_.Name -notmatch '^PS' } | ForEach-Object { Log " $($_.Name) = $($_.Value)" } } } else { Log "[NOT FOUND] $regPath does not exist" } Section "INSTALLED PROGRAMS (MSI)" $rmm = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ` -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -match "GuruRMM|gururmm" } if ($rmm) { foreach ($r in $rmm) { Log "DisplayName: $($r.DisplayName)" Log "DisplayVersion: $($r.DisplayVersion)" Log "InstallDate: $($r.InstallDate)" Log "InstallLocation:$($r.InstallLocation)" Log "Publisher: $($r.Publisher)" } } else { Log "[NOT FOUND] No GuruRMM entry in Add/Remove Programs" } Section "MSI EVENT LOG (last 20 MsiInstaller events)" Get-WinEvent -FilterHashtable @{ LogName = 'Application' ProviderName = 'MsiInstaller' } -MaxEvents 20 -ErrorAction SilentlyContinue | ForEach-Object { Log "$($_.TimeCreated) [$($_.Id)] $($_.Message -replace '\r?\n',' ' | Select-Object -First 1)" } Section "APPLICATION EVENT LOG (gururmm, last 30 entries)" Get-WinEvent -FilterHashtable @{ LogName = 'Application' StartTime = (Get-Date).AddHours(-4) } -ErrorAction SilentlyContinue | Where-Object { $_.Message -match "gururmm|GuruRMM" -or $_.ProviderName -match "gururmm" } | Select-Object -Last 30 | ForEach-Object { Log "$($_.TimeCreated) [$($_.LevelDisplayName)] $($_.ProviderName): $($_.Message -replace '\r?\n',' ')" } Section "SYSTEM EVENT LOG (service control, last 20)" Get-WinEvent -FilterHashtable @{ LogName = 'System' StartTime = (Get-Date).AddHours(-4) Id = @(7000,7001,7009,7023,7031,7034,7036,7040,7045) } -ErrorAction SilentlyContinue | Where-Object { $_.Message -match "gururmm|GuruRMM" } | Select-Object -Last 20 | ForEach-Object { Log "$($_.TimeCreated) [ID $($_.Id)] $($_.Message -replace '\r?\n',' ')" } Section "AGENT LOG FILES" $searchPaths = @( "$env:ProgramData\GuruRMM", "$env:ProgramFiles\GuruRMM", "$env:ProgramFiles\gururmm-agent", "C:\Program Files\GuruRMM", "C:\ProgramData\GuruRMM" ) $foundAny = $false foreach ($p in $searchPaths) { if (Test-Path $p) { $foundAny = $true Log "Found: $p" Get-ChildItem $p -Recurse -ErrorAction SilentlyContinue | ForEach-Object { Log " $($_.FullName) ($($_.Length) bytes)" } # Print last 50 lines of any .log files Get-ChildItem $p -Recurse -Filter "*.log" -ErrorAction SilentlyContinue | ForEach-Object { Log "" Log "--- $($_.FullName) (last 50 lines) ---" Get-Content $_.FullName -Tail 50 -ErrorAction SilentlyContinue | ForEach-Object { Log $_ } } } } if (-not $foundAny) { Log "[NOT FOUND] No agent data directories found" } Section "NETWORK CONNECTIVITY" $targets = @( @{Host="rmm.azcomputerguru.com"; Port=443; Label="RMM HTTPS"}, @{Host="172.16.3.30"; Port=3001; Label="RMM API (internal)"}, @{Host="8.8.8.8"; Port=53; Label="DNS (Google)"} ) foreach ($t in $targets) { $hp = "$($t.Host):$($t.Port)" try { $tcp = [System.Net.Sockets.TcpClient]::new() $r = $tcp.BeginConnect($t.Host, $t.Port, $null, $null) $ok = $r.AsyncWaitHandle.WaitOne(3000) $tcp.Close() if ($ok) { Log "[OK] $($t.Label) ($hp)" } else { Log "[FAIL] $($t.Label) ($hp) -- timeout" } } catch { Log "[FAIL] $($t.Label) ($hp) -- $($_.Exception.Message)" } } Section "FIREWALL (outbound rules for gururmm)" Get-NetFirewallRule -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -match "gururmm|GuruRMM" } | ForEach-Object { Log "$($_.DisplayName) [$($_.Direction)] [$($_.Action)] [$($_.Enabled)]" } # Write output file $outFile = "$env:TEMP\gururmm-diag-$env:COMPUTERNAME-$(Get-Date -Format 'yyyyMMdd-HHmmss').txt" $out | Set-Content $outFile -Encoding UTF8 Write-Host "" Write-Host "Diagnostic saved to: $outFile" Write-Host "Copy it back with: type `"$outFile`""