#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`""
