icky17

Untitled

Oct 9th, 2025 (edited)
754
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #Requires -RunAsAdministrator
  2.  
  3. <#
  4. .SYNOPSIS
  5.     Compares two Thunderbolt Dock diagnostic JSON files
  6.    
  7. .DESCRIPTION
  8.     Compares the working HP image configuration with your custom image
  9.     and highlights all differences with color-coded output.
  10.    
  11. .PARAMETER WorkingImageJson
  12.     Path to JSON file from the WORKING HP image
  13.    
  14. .PARAMETER CustomImageJson
  15.     Path to JSON file from your CUSTOM image
  16.    
  17. .EXAMPLE
  18.     .\Compare-TBConfig.ps1 -WorkingImageJson "C:\Desktop\TB_Dock_Diagnostic_WORKING.json" -CustomImageJson "C:\Desktop\TB_Dock_Diagnostic_CUSTOM.json"
  19. #>
  20.  
  21. param(
  22.     [Parameter(Mandatory=$false)]
  23.     [string]$WorkingImageJson,
  24.    
  25.     [Parameter(Mandatory=$false)]
  26.     [string]$CustomImageJson
  27. )
  28.  
  29. # If parameters not provided, use file picker
  30. Add-Type -AssemblyName System.Windows.Forms
  31.  
  32. if (-not $WorkingImageJson) {
  33.     Write-Host "Select the JSON file from the WORKING HP Image..." -ForegroundColor Yellow
  34.     $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
  35.     $openFileDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
  36.     $openFileDialog.Title = "Select WORKING HP Image JSON"
  37.     $openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
  38.    
  39.     if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
  40.         $WorkingImageJson = $openFileDialog.FileName
  41.     } else {
  42.         Write-Error "No file selected for Working Image. Exiting."
  43.         exit
  44.     }
  45. }
  46.  
  47. if (-not $CustomImageJson) {
  48.     Write-Host "Select the JSON file from your CUSTOM Image..." -ForegroundColor Yellow
  49.     $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
  50.     $openFileDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
  51.     $openFileDialog.Title = "Select CUSTOM Image JSON"
  52.     $openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
  53.    
  54.     if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
  55.         $CustomImageJson = $openFileDialog.FileName
  56.     } else {
  57.         Write-Error "No file selected for Custom Image. Exiting."
  58.         exit
  59.     }
  60. }
  61.  
  62. # Verify files exist
  63. if (-not (Test-Path $WorkingImageJson)) {
  64.     Write-Error "Working Image JSON not found: $WorkingImageJson"
  65.     exit
  66. }
  67.  
  68. if (-not (Test-Path $CustomImageJson)) {
  69.     Write-Error "Custom Image JSON not found: $CustomImageJson"
  70.     exit
  71. }
  72.  
  73. # Output file
  74. $comparisonReport = "$env:USERPROFILE\Desktop\TB_Comparison_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
  75. $comparisonText = "$env:USERPROFILE\Desktop\TB_Comparison_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
  76.  
  77. Write-Host "`n============================================" -ForegroundColor Cyan
  78. Write-Host "THUNDERBOLT DOCK CONFIGURATION COMPARISON" -ForegroundColor Cyan
  79. Write-Host "============================================`n" -ForegroundColor Cyan
  80.  
  81. Write-Host "Working Image: " -NoNewline
  82. Write-Host $WorkingImageJson -ForegroundColor Green
  83. Write-Host "Custom Image:  " -NoNewline
  84. Write-Host $CustomImageJson -ForegroundColor Yellow
  85. Write-Host ""
  86.  
  87. # Load JSON files
  88. try {
  89.     $workingConfig = Get-Content -Path $WorkingImageJson -Raw | ConvertFrom-Json
  90.     $customConfig = Get-Content -Path $CustomImageJson -Raw | ConvertFrom-Json
  91. } catch {
  92.     Write-Error "Failed to parse JSON files: $_"
  93.     exit
  94. }
  95.  
  96. # Initialize comparison results
  97. $differences = @()
  98. $criticalDifferences = @()
  99. $warnings = @()
  100.  
  101. # Helper function to compare objects recursively
  102. function Compare-Objects {
  103.     param(
  104.         [Parameter(Mandatory=$true)]
  105.         $Working,
  106.        
  107.         [Parameter(Mandatory=$true)]
  108.         $Custom,
  109.        
  110.         [Parameter(Mandatory=$true)]
  111.         [string]$Path,
  112.        
  113.         [Parameter(Mandatory=$false)]
  114.         [string]$Level = "INFO"
  115.     )
  116.    
  117.     $results = @()
  118.    
  119.     # Handle null cases
  120.     if ($null -eq $Working -and $null -eq $Custom) {
  121.         return $results
  122.     }
  123.    
  124.     if ($null -eq $Working -and $null -ne $Custom) {
  125.         $results += [PSCustomObject]@{
  126.             Path = $Path
  127.             WorkingValue = "NOT SET"
  128.             CustomValue = $Custom
  129.             Level = $Level
  130.             Message = "Setting exists in Custom but not in Working image"
  131.         }
  132.         return $results
  133.     }
  134.    
  135.     if ($null -ne $Working -and $null -eq $Custom) {
  136.         $results += [PSCustomObject]@{
  137.             Path = $Path
  138.             WorkingValue = $Working
  139.             CustomValue = "NOT SET"
  140.             Level = $Level
  141.             Message = "Setting exists in Working but not in Custom image"
  142.         }
  143.         return $results
  144.     }
  145.    
  146.     # Get type
  147.     $workingType = $Working.GetType().Name
  148.     $customType = $Custom.GetType().Name
  149.    
  150.     # If types differ
  151.     if ($workingType -ne $customType) {
  152.         $results += [PSCustomObject]@{
  153.             Path = $Path
  154.             WorkingValue = "$Working ($workingType)"
  155.             CustomValue = "$Custom ($customType)"
  156.             Level = "WARNING"
  157.             Message = "Different data types"
  158.         }
  159.         return $results
  160.     }
  161.    
  162.     # Handle different types
  163.     if ($Working -is [System.Management.Automation.PSCustomObject]) {
  164.         $workingProps = $Working.PSObject.Properties.Name
  165.         $customProps = $Custom.PSObject.Properties.Name
  166.        
  167.         $allProps = ($workingProps + $customProps) | Select-Object -Unique
  168.        
  169.         foreach ($prop in $allProps) {
  170.             $newPath = if ($Path) { "$Path.$prop" } else { $prop }
  171.            
  172.             if ($workingProps -contains $prop -and $customProps -contains $prop) {
  173.                 $results += Compare-Objects -Working $Working.$prop -Custom $Custom.$prop -Path $newPath -Level $Level
  174.             } elseif ($workingProps -contains $prop) {
  175.                 $results += [PSCustomObject]@{
  176.                     Path = $newPath
  177.                     WorkingValue = $Working.$prop
  178.                     CustomValue = "MISSING"
  179.                     Level = $Level
  180.                     Message = "Property missing in Custom image"
  181.                 }
  182.             } else {
  183.                 $results += [PSCustomObject]@{
  184.                     Path = $newPath
  185.                     WorkingValue = "MISSING"
  186.                     CustomValue = $Custom.$prop
  187.                     Level = $Level
  188.                     Message = "Property missing in Working image"
  189.                 }
  190.             }
  191.         }
  192.     } elseif ($Working -is [Array]) {
  193.         if ($Working.Count -ne $Custom.Count) {
  194.             $results += [PSCustomObject]@{
  195.                 Path = $Path
  196.                 WorkingValue = "Array with $($Working.Count) items"
  197.                 CustomValue = "Array with $($Custom.Count) items"
  198.                 Level = "WARNING"
  199.                 Message = "Different array lengths"
  200.             }
  201.         }
  202.        
  203.         # Compare array items (simplified - just compare count and first few items)
  204.         $maxCompare = [Math]::Min($Working.Count, $Custom.Count)
  205.         for ($i = 0; $i -lt $maxCompare; $i++) {
  206.             $results += Compare-Objects -Working $Working[$i] -Custom $Custom[$i] -Path "$Path[$i]" -Level $Level
  207.         }
  208.     } else {
  209.         # Simple value comparison
  210.         if ($Working -ne $Custom) {
  211.             $results += [PSCustomObject]@{
  212.                 Path = $Path
  213.                 WorkingValue = $Working
  214.                 CustomValue = $Custom
  215.                 Level = $Level
  216.                 Message = "Values differ"
  217.             }
  218.         }
  219.     }
  220.    
  221.     return $results
  222. }
  223.  
  224. # Start comparison
  225. Write-Host "Comparing configurations..." -ForegroundColor Cyan
  226.  
  227. # Define critical sections with their importance level
  228. $criticalSections = @{
  229.     'SpecificPolicies' = 'CRITICAL'
  230.     'RegistryKeys' = 'CRITICAL'
  231.     'KernelDMAProtection' = 'CRITICAL'
  232.     'Services' = 'HIGH'
  233.     'BIOS' = 'HIGH'
  234.     'ThunderboltControllers' = 'HIGH'
  235.     'USB4Routers' = 'HIGH'
  236.     'DockNICs' = 'HIGH'
  237.     'NetworkAdapters' = 'MEDIUM'
  238.     'BitLocker' = 'MEDIUM'
  239.     'DeviceGuard' = 'MEDIUM'
  240.     'BCDEdit' = 'MEDIUM'
  241.     'DriverStore' = 'LOW'
  242.     'SystemInfo' = 'INFO'
  243. }
  244.  
  245. # Compare each section
  246. foreach ($section in $criticalSections.Keys) {
  247.     if ($workingConfig.PSObject.Properties.Name -contains $section) {
  248.         Write-Host "Analyzing: $section..." -ForegroundColor Gray
  249.        
  250.         $sectionDiffs = Compare-Objects `
  251.             -Working $workingConfig.$section `
  252.             -Custom $customConfig.$section `
  253.             -Path $section `
  254.             -Level $criticalSections[$section]
  255.        
  256.         if ($sectionDiffs.Count -gt 0) {
  257.             $differences += $sectionDiffs
  258.            
  259.             if ($criticalSections[$section] -eq 'CRITICAL') {
  260.                 $criticalDifferences += $sectionDiffs
  261.             } elseif ($criticalSections[$section] -in @('HIGH', 'MEDIUM')) {
  262.                 $warnings += $sectionDiffs
  263.             }
  264.         }
  265.     }
  266. }
  267.  
  268. # Display results
  269. Write-Host "`n============================================" -ForegroundColor Cyan
  270. Write-Host "COMPARISON RESULTS" -ForegroundColor Cyan
  271. Write-Host "============================================`n" -ForegroundColor Cyan
  272.  
  273. Write-Host "Total Differences Found: " -NoNewline
  274. Write-Host $differences.Count -ForegroundColor $(if ($differences.Count -eq 0) { "Green" } else { "Yellow" })
  275.  
  276. Write-Host "Critical Differences: " -NoNewline
  277. Write-Host $criticalDifferences.Count -ForegroundColor $(if ($criticalDifferences.Count -eq 0) { "Green" } else { "Red" })
  278.  
  279. Write-Host "High/Medium Priority: " -NoNewline
  280. Write-Host $warnings.Count -ForegroundColor $(if ($warnings.Count -eq 0) { "Green" } else { "Yellow" })
  281.  
  282. # Display Critical Differences
  283. if ($criticalDifferences.Count -gt 0) {
  284.     Write-Host "`n`n=== CRITICAL DIFFERENCES (ACTION REQUIRED) ===" -ForegroundColor Red -BackgroundColor Black
  285.     Write-Host "These settings are most likely causing your issue:`n" -ForegroundColor Red
  286.    
  287.     foreach ($diff in $criticalDifferences) {
  288.         Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Red
  289.         Write-Host "Path: " -NoNewline
  290.         Write-Host $diff.Path -ForegroundColor White
  291.         Write-Host "Working Image: " -NoNewline -ForegroundColor Green
  292.         Write-Host $diff.WorkingValue -ForegroundColor White
  293.         Write-Host "Custom Image:  " -NoNewline -ForegroundColor Yellow
  294.         Write-Host $diff.CustomValue -ForegroundColor White
  295.         Write-Host "Note: $($diff.Message)" -ForegroundColor Gray
  296.         Write-Host ""
  297.     }
  298. }
  299.  
  300. # Display Warnings
  301. if ($warnings.Count -gt 0) {
  302.     Write-Host "`n`n=== HIGH/MEDIUM PRIORITY DIFFERENCES ===" -ForegroundColor Yellow
  303.     Write-Host "These may also affect functionality:`n" -ForegroundColor Yellow
  304.    
  305.     foreach ($diff in ($warnings | Select-Object -First 20)) {
  306.         Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow
  307.         Write-Host "Path: " -NoNewline
  308.         Write-Host $diff.Path -ForegroundColor White
  309.         Write-Host "Working Image: " -NoNewline -ForegroundColor Green
  310.         Write-Host $diff.WorkingValue -ForegroundColor White
  311.         Write-Host "Custom Image:  " -NoNewline -ForegroundColor Yellow
  312.         Write-Host $diff.CustomValue -ForegroundColor White
  313.         Write-Host ""
  314.     }
  315.    
  316.     if ($warnings.Count -gt 20) {
  317.         Write-Host "... and $($warnings.Count - 20) more differences (see full report)" -ForegroundColor Gray
  318.     }
  319. }
  320.  
  321. # Generate HTML Report
  322. $htmlContent = @"
  323. <!DOCTYPE html>
  324. <html>
  325. <head>
  326.    <meta charset="UTF-8">
  327.    <title>Thunderbolt Dock Configuration Comparison</title>
  328.    <style>
  329.        body {
  330.            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  331.            margin: 20px;
  332.            background-color: #f5f5f5;
  333.        }
  334.        h1 {
  335.            color: #0078d4;
  336.            border-bottom: 3px solid #0078d4;
  337.            padding-bottom: 10px;
  338.        }
  339.        h2 {
  340.            color: #333;
  341.            margin-top: 30px;
  342.            background-color: #e8e8e8;
  343.            padding: 10px;
  344.            border-left: 5px solid #0078d4;
  345.        }
  346.        .summary {
  347.            background-color: white;
  348.            padding: 20px;
  349.            border-radius: 5px;
  350.            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
  351.            margin-bottom: 20px;
  352.        }
  353.        .summary-item {
  354.            display: inline-block;
  355.            margin: 10px 20px 10px 0;
  356.            padding: 10px 20px;
  357.            border-radius: 5px;
  358.            font-weight: bold;
  359.        }
  360.        .critical-count {
  361.            background-color: #ffebee;
  362.            color: #c62828;
  363.        }
  364.        .warning-count {
  365.            background-color: #fff3e0;
  366.            color: #ef6c00;
  367.        }
  368.        .info-count {
  369.            background-color: #e3f2fd;
  370.            color: #1565c0;
  371.        }
  372.        table {
  373.            width: 100%;
  374.            border-collapse: collapse;
  375.            background-color: white;
  376.            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
  377.            margin-bottom: 30px;
  378.        }
  379.        th {
  380.            background-color: #0078d4;
  381.            color: white;
  382.            padding: 12px;
  383.            text-align: left;
  384.            font-weight: bold;
  385.        }
  386.        td {
  387.            padding: 10px;
  388.            border-bottom: 1px solid #ddd;
  389.        }
  390.        tr:hover {
  391.            background-color: #f5f5f5;
  392.        }
  393.        .level-CRITICAL {
  394.            background-color: #ffebee;
  395.            border-left: 5px solid #c62828;
  396.        }
  397.        .level-HIGH {
  398.            background-color: #fff3e0;
  399.            border-left: 5px solid #ef6c00;
  400.        }
  401.        .level-MEDIUM {
  402.            background-color: #fff9c4;
  403.            border-left: 5px solid #f57f17;
  404.        }
  405.        .level-LOW, .level-INFO {
  406.            border-left: 5px solid #0078d4;
  407.        }
  408.        .value {
  409.            font-family: 'Courier New', monospace;
  410.            background-color: #f5f5f5;
  411.            padding: 5px;
  412.            border-radius: 3px;
  413.        }
  414.        .path {
  415.            font-family: 'Courier New', monospace;
  416.            color: #0078d4;
  417.            font-weight: bold;
  418.        }
  419.        .working {
  420.            color: #2e7d32;
  421.        }
  422.        .custom {
  423.            color: #d84315;
  424.        }
  425.        .recommendation {
  426.            background-color: #e8f5e9;
  427.            border: 1px solid #4caf50;
  428.            padding: 15px;
  429.            border-radius: 5px;
  430.            margin: 20px 0;
  431.        }
  432.        .recommendation h3 {
  433.            color: #2e7d32;
  434.            margin-top: 0;
  435.        }
  436.    </style>
  437. </head>
  438. <body>
  439.    <h1>🔍 Thunderbolt Dock Configuration Comparison Report</h1>
  440.    
  441.    <div class="summary">
  442.        <h3>Summary</h3>
  443.        <div class="summary-item critical-count">Critical: $($criticalDifferences.Count)</div>
  444.        <div class="summary-item warning-count">High/Medium: $($warnings.Count)</div>
  445.        <div class="summary-item info-count">Total Differences: $($differences.Count)</div>
  446.        <p><strong>Working Image:</strong> $WorkingImageJson</p>
  447.        <p><strong>Custom Image:</strong> $CustomImageJson</p>
  448.        <p><strong>Report Generated:</strong> $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p>
  449.    </div>
  450. "@
  451.  
  452. if ($criticalDifferences.Count -gt 0) {
  453.     $htmlContent += @"
  454.    <h2>🔴 Critical Differences (Action Required)</h2>
  455.    <div class="recommendation">
  456.        <h3>⚠️ These settings are most likely causing your Ethernet pre-login issue!</h3>
  457.        <p>Focus on fixing these registry keys and policies first.</p>
  458.    </div>
  459.    <table>
  460.        <tr>
  461.            <th>Setting Path</th>
  462.            <th>Working Image (✓)</th>
  463.            <th>Your Custom Image (✗)</th>
  464.            <th>Note</th>
  465.        </tr>
  466. "@
  467.     foreach ($diff in $criticalDifferences) {
  468.         $htmlContent += @"
  469.        <tr class="level-$($diff.Level)">
  470.            <td class="path">$($diff.Path)</td>
  471.            <td class="value working">$($diff.WorkingValue)</td>
  472.            <td class="value custom">$($diff.CustomValue)</td>
  473.            <td>$($diff.Message)</td>
  474.        </tr>
  475. "@
  476.     }
  477.     $htmlContent += "</table>"
  478. }
  479.  
  480. if ($warnings.Count -gt 0) {
  481.     $htmlContent += @"
  482.    <h2>⚠️ High/Medium Priority Differences</h2>
  483.    <table>
  484.        <tr>
  485.            <th>Setting Path</th>
  486.            <th>Working Image</th>
  487.            <th>Custom Image</th>
  488.            <th>Note</th>
  489.        </tr>
  490. "@
  491.     foreach ($diff in $warnings) {
  492.         $htmlContent += @"
  493.        <tr class="level-$($diff.Level)">
  494.            <td class="path">$($diff.Path)</td>
  495.            <td class="value working">$($diff.WorkingValue)</td>
  496.            <td class="value custom">$($diff.CustomValue)</td>
  497.            <td>$($diff.Message)</td>
  498.        </tr>
  499. "@
  500.     }
  501.     $htmlContent += "</table>"
  502. }
  503.  
  504. $otherDiffs = $differences | Where-Object { $_.Level -notin @('CRITICAL', 'HIGH', 'MEDIUM') }
  505. if ($otherDiffs.Count -gt 0) {
  506.     $htmlContent += @"
  507.    <h2>ℹ️ Other Differences (Lower Priority)</h2>
  508.    <table>
  509.        <tr>
  510.            <th>Setting Path</th>
  511.            <th>Working Image</th>
  512.            <th>Custom Image</th>
  513.            <th>Note</th>
  514.        </tr>
  515. "@
  516.     foreach ($diff in $otherDiffs) {
  517.         $htmlContent += @"
  518.        <tr class="level-$($diff.Level)">
  519.            <td class="path">$($diff.Path)</td>
  520.            <td class="value working">$($diff.WorkingValue)</td>
  521.            <td class="value custom">$($diff.CustomValue)</td>
  522.            <td>$($diff.Message)</td>
  523.        </tr>
  524. "@
  525.     }
  526.     $htmlContent += "</table>"
  527. }
  528.  
  529. $htmlContent += @"
  530. </body>
  531. </html>
  532. "@
  533.  
  534. # Save HTML report
  535. $htmlContent | Out-File -FilePath $comparisonReport -Encoding UTF8
  536.  
  537. # Save text report
  538. $textReport = @"
  539. ============================================
  540. THUNDERBOLT DOCK CONFIGURATION COMPARISON
  541. ============================================
  542. Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
  543.  
  544. Working Image: $WorkingImageJson
  545. Custom Image:  $CustomImageJson
  546.  
  547. SUMMARY
  548. -------
  549. Total Differences: $($differences.Count)
  550. Critical:          $($criticalDifferences.Count)
  551. High/Medium:       $($warnings.Count)
  552.  
  553. "@
  554.  
  555. if ($criticalDifferences.Count -gt 0) {
  556.     $textReport += @"
  557.  
  558. ========================================
  559. CRITICAL DIFFERENCES (ACTION REQUIRED)
  560. ========================================
  561.  
  562. "@
  563.     foreach ($diff in $criticalDifferences) {
  564.         $textReport += @"
  565. Path: $($diff.Path)
  566. Working Image: $($diff.WorkingValue)
  567. Custom Image:  $($diff.CustomValue)
  568. Note: $($diff.Message)
  569. ----------------------------------------
  570.  
  571. "@
  572.     }
  573. }
  574.  
  575. if ($warnings.Count -gt 0) {
  576.     $textReport += @"
  577.  
  578. ========================================
  579. HIGH/MEDIUM PRIORITY DIFFERENCES
  580. ========================================
  581.  
  582. "@
  583.     foreach ($diff in $warnings) {
  584.         $textReport += @"
  585. Path: $($diff.Path)
  586. Working Image: $($diff.WorkingValue)
  587. Custom Image:  $($diff.CustomValue)
  588. Note: $($diff.Message)
  589. ----------------------------------------
  590.  
  591. "@
  592.     }
  593. }
  594.  
  595. $textReport | Out-File -FilePath $comparisonText -Encoding UTF8
  596.  
  597. # Final output
  598. Write-Host "`n============================================" -ForegroundColor Cyan
  599. Write-Host "REPORTS GENERATED" -ForegroundColor Cyan
  600. Write-Host "============================================`n" -ForegroundColor Cyan
  601.  
  602. Write-Host "HTML Report: " -NoNewline
  603. Write-Host $comparisonReport -ForegroundColor Green
  604.  
  605. Write-Host "Text Report: " -NoNewline
  606. Write-Host $comparisonText -ForegroundColor Green
  607.  
  608. Write-Host "`nOpening HTML report..." -ForegroundColor Yellow
  609. Start-Process $comparisonReport
  610.  
  611. Write-Host "`n✅ Comparison complete!" -ForegroundColor Green
  612. Write-Host "`n💡 TIP: Focus on the CRITICAL differences first - these are most likely causing your issue!" -ForegroundColor Yellow
Advertisement
Add Comment
Please, Sign In to add comment