Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Requires -RunAsAdministrator
- <#
- .SYNOPSIS
- Compares two Thunderbolt Dock diagnostic JSON files
- .DESCRIPTION
- Compares the working HP image configuration with your custom image
- and highlights all differences with color-coded output.
- .PARAMETER WorkingImageJson
- Path to JSON file from the WORKING HP image
- .PARAMETER CustomImageJson
- Path to JSON file from your CUSTOM image
- .EXAMPLE
- .\Compare-TBConfig.ps1 -WorkingImageJson "C:\Desktop\TB_Dock_Diagnostic_WORKING.json" -CustomImageJson "C:\Desktop\TB_Dock_Diagnostic_CUSTOM.json"
- #>
- param(
- [Parameter(Mandatory=$false)]
- [string]$WorkingImageJson,
- [Parameter(Mandatory=$false)]
- [string]$CustomImageJson
- )
- # If parameters not provided, use file picker
- Add-Type -AssemblyName System.Windows.Forms
- if (-not $WorkingImageJson) {
- Write-Host "Select the JSON file from the WORKING HP Image..." -ForegroundColor Yellow
- $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
- $openFileDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
- $openFileDialog.Title = "Select WORKING HP Image JSON"
- $openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
- if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
- $WorkingImageJson = $openFileDialog.FileName
- } else {
- Write-Error "No file selected for Working Image. Exiting."
- exit
- }
- }
- if (-not $CustomImageJson) {
- Write-Host "Select the JSON file from your CUSTOM Image..." -ForegroundColor Yellow
- $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
- $openFileDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
- $openFileDialog.Title = "Select CUSTOM Image JSON"
- $openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
- if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
- $CustomImageJson = $openFileDialog.FileName
- } else {
- Write-Error "No file selected for Custom Image. Exiting."
- exit
- }
- }
- # Verify files exist
- if (-not (Test-Path $WorkingImageJson)) {
- Write-Error "Working Image JSON not found: $WorkingImageJson"
- exit
- }
- if (-not (Test-Path $CustomImageJson)) {
- Write-Error "Custom Image JSON not found: $CustomImageJson"
- exit
- }
- # Output file
- $comparisonReport = "$env:USERPROFILE\Desktop\TB_Comparison_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
- $comparisonText = "$env:USERPROFILE\Desktop\TB_Comparison_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
- Write-Host "`n============================================" -ForegroundColor Cyan
- Write-Host "THUNDERBOLT DOCK CONFIGURATION COMPARISON" -ForegroundColor Cyan
- Write-Host "============================================`n" -ForegroundColor Cyan
- Write-Host "Working Image: " -NoNewline
- Write-Host $WorkingImageJson -ForegroundColor Green
- Write-Host "Custom Image: " -NoNewline
- Write-Host $CustomImageJson -ForegroundColor Yellow
- Write-Host ""
- # Load JSON files
- try {
- $workingConfig = Get-Content -Path $WorkingImageJson -Raw | ConvertFrom-Json
- $customConfig = Get-Content -Path $CustomImageJson -Raw | ConvertFrom-Json
- } catch {
- Write-Error "Failed to parse JSON files: $_"
- exit
- }
- # Initialize comparison results
- $differences = @()
- $criticalDifferences = @()
- $warnings = @()
- # Helper function to compare objects recursively
- function Compare-Objects {
- param(
- [Parameter(Mandatory=$true)]
- $Working,
- [Parameter(Mandatory=$true)]
- $Custom,
- [Parameter(Mandatory=$true)]
- [string]$Path,
- [Parameter(Mandatory=$false)]
- [string]$Level = "INFO"
- )
- $results = @()
- # Handle null cases
- if ($null -eq $Working -and $null -eq $Custom) {
- return $results
- }
- if ($null -eq $Working -and $null -ne $Custom) {
- $results += [PSCustomObject]@{
- Path = $Path
- WorkingValue = "NOT SET"
- CustomValue = $Custom
- Level = $Level
- Message = "Setting exists in Custom but not in Working image"
- }
- return $results
- }
- if ($null -ne $Working -and $null -eq $Custom) {
- $results += [PSCustomObject]@{
- Path = $Path
- WorkingValue = $Working
- CustomValue = "NOT SET"
- Level = $Level
- Message = "Setting exists in Working but not in Custom image"
- }
- return $results
- }
- # Get type
- $workingType = $Working.GetType().Name
- $customType = $Custom.GetType().Name
- # If types differ
- if ($workingType -ne $customType) {
- $results += [PSCustomObject]@{
- Path = $Path
- WorkingValue = "$Working ($workingType)"
- CustomValue = "$Custom ($customType)"
- Level = "WARNING"
- Message = "Different data types"
- }
- return $results
- }
- # Handle different types
- if ($Working -is [System.Management.Automation.PSCustomObject]) {
- $workingProps = $Working.PSObject.Properties.Name
- $customProps = $Custom.PSObject.Properties.Name
- $allProps = ($workingProps + $customProps) | Select-Object -Unique
- foreach ($prop in $allProps) {
- $newPath = if ($Path) { "$Path.$prop" } else { $prop }
- if ($workingProps -contains $prop -and $customProps -contains $prop) {
- $results += Compare-Objects -Working $Working.$prop -Custom $Custom.$prop -Path $newPath -Level $Level
- } elseif ($workingProps -contains $prop) {
- $results += [PSCustomObject]@{
- Path = $newPath
- WorkingValue = $Working.$prop
- CustomValue = "MISSING"
- Level = $Level
- Message = "Property missing in Custom image"
- }
- } else {
- $results += [PSCustomObject]@{
- Path = $newPath
- WorkingValue = "MISSING"
- CustomValue = $Custom.$prop
- Level = $Level
- Message = "Property missing in Working image"
- }
- }
- }
- } elseif ($Working -is [Array]) {
- if ($Working.Count -ne $Custom.Count) {
- $results += [PSCustomObject]@{
- Path = $Path
- WorkingValue = "Array with $($Working.Count) items"
- CustomValue = "Array with $($Custom.Count) items"
- Level = "WARNING"
- Message = "Different array lengths"
- }
- }
- # Compare array items (simplified - just compare count and first few items)
- $maxCompare = [Math]::Min($Working.Count, $Custom.Count)
- for ($i = 0; $i -lt $maxCompare; $i++) {
- $results += Compare-Objects -Working $Working[$i] -Custom $Custom[$i] -Path "$Path[$i]" -Level $Level
- }
- } else {
- # Simple value comparison
- if ($Working -ne $Custom) {
- $results += [PSCustomObject]@{
- Path = $Path
- WorkingValue = $Working
- CustomValue = $Custom
- Level = $Level
- Message = "Values differ"
- }
- }
- }
- return $results
- }
- # Start comparison
- Write-Host "Comparing configurations..." -ForegroundColor Cyan
- # Define critical sections with their importance level
- $criticalSections = @{
- 'SpecificPolicies' = 'CRITICAL'
- 'RegistryKeys' = 'CRITICAL'
- 'KernelDMAProtection' = 'CRITICAL'
- 'Services' = 'HIGH'
- 'BIOS' = 'HIGH'
- 'ThunderboltControllers' = 'HIGH'
- 'USB4Routers' = 'HIGH'
- 'DockNICs' = 'HIGH'
- 'NetworkAdapters' = 'MEDIUM'
- 'BitLocker' = 'MEDIUM'
- 'DeviceGuard' = 'MEDIUM'
- 'BCDEdit' = 'MEDIUM'
- 'DriverStore' = 'LOW'
- 'SystemInfo' = 'INFO'
- }
- # Compare each section
- foreach ($section in $criticalSections.Keys) {
- if ($workingConfig.PSObject.Properties.Name -contains $section) {
- Write-Host "Analyzing: $section..." -ForegroundColor Gray
- $sectionDiffs = Compare-Objects `
- -Working $workingConfig.$section `
- -Custom $customConfig.$section `
- -Path $section `
- -Level $criticalSections[$section]
- if ($sectionDiffs.Count -gt 0) {
- $differences += $sectionDiffs
- if ($criticalSections[$section] -eq 'CRITICAL') {
- $criticalDifferences += $sectionDiffs
- } elseif ($criticalSections[$section] -in @('HIGH', 'MEDIUM')) {
- $warnings += $sectionDiffs
- }
- }
- }
- }
- # Display results
- Write-Host "`n============================================" -ForegroundColor Cyan
- Write-Host "COMPARISON RESULTS" -ForegroundColor Cyan
- Write-Host "============================================`n" -ForegroundColor Cyan
- Write-Host "Total Differences Found: " -NoNewline
- Write-Host $differences.Count -ForegroundColor $(if ($differences.Count -eq 0) { "Green" } else { "Yellow" })
- Write-Host "Critical Differences: " -NoNewline
- Write-Host $criticalDifferences.Count -ForegroundColor $(if ($criticalDifferences.Count -eq 0) { "Green" } else { "Red" })
- Write-Host "High/Medium Priority: " -NoNewline
- Write-Host $warnings.Count -ForegroundColor $(if ($warnings.Count -eq 0) { "Green" } else { "Yellow" })
- # Display Critical Differences
- if ($criticalDifferences.Count -gt 0) {
- Write-Host "`n`n=== CRITICAL DIFFERENCES (ACTION REQUIRED) ===" -ForegroundColor Red -BackgroundColor Black
- Write-Host "These settings are most likely causing your issue:`n" -ForegroundColor Red
- foreach ($diff in $criticalDifferences) {
- Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Red
- Write-Host "Path: " -NoNewline
- Write-Host $diff.Path -ForegroundColor White
- Write-Host "Working Image: " -NoNewline -ForegroundColor Green
- Write-Host $diff.WorkingValue -ForegroundColor White
- Write-Host "Custom Image: " -NoNewline -ForegroundColor Yellow
- Write-Host $diff.CustomValue -ForegroundColor White
- Write-Host "Note: $($diff.Message)" -ForegroundColor Gray
- Write-Host ""
- }
- }
- # Display Warnings
- if ($warnings.Count -gt 0) {
- Write-Host "`n`n=== HIGH/MEDIUM PRIORITY DIFFERENCES ===" -ForegroundColor Yellow
- Write-Host "These may also affect functionality:`n" -ForegroundColor Yellow
- foreach ($diff in ($warnings | Select-Object -First 20)) {
- Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow
- Write-Host "Path: " -NoNewline
- Write-Host $diff.Path -ForegroundColor White
- Write-Host "Working Image: " -NoNewline -ForegroundColor Green
- Write-Host $diff.WorkingValue -ForegroundColor White
- Write-Host "Custom Image: " -NoNewline -ForegroundColor Yellow
- Write-Host $diff.CustomValue -ForegroundColor White
- Write-Host ""
- }
- if ($warnings.Count -gt 20) {
- Write-Host "... and $($warnings.Count - 20) more differences (see full report)" -ForegroundColor Gray
- }
- }
- # Generate HTML Report
- $htmlContent = @"
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Thunderbolt Dock Configuration Comparison</title>
- <style>
- body {
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
- margin: 20px;
- background-color: #f5f5f5;
- }
- h1 {
- color: #0078d4;
- border-bottom: 3px solid #0078d4;
- padding-bottom: 10px;
- }
- h2 {
- color: #333;
- margin-top: 30px;
- background-color: #e8e8e8;
- padding: 10px;
- border-left: 5px solid #0078d4;
- }
- .summary {
- background-color: white;
- padding: 20px;
- border-radius: 5px;
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
- margin-bottom: 20px;
- }
- .summary-item {
- display: inline-block;
- margin: 10px 20px 10px 0;
- padding: 10px 20px;
- border-radius: 5px;
- font-weight: bold;
- }
- .critical-count {
- background-color: #ffebee;
- color: #c62828;
- }
- .warning-count {
- background-color: #fff3e0;
- color: #ef6c00;
- }
- .info-count {
- background-color: #e3f2fd;
- color: #1565c0;
- }
- table {
- width: 100%;
- border-collapse: collapse;
- background-color: white;
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
- margin-bottom: 30px;
- }
- th {
- background-color: #0078d4;
- color: white;
- padding: 12px;
- text-align: left;
- font-weight: bold;
- }
- td {
- padding: 10px;
- border-bottom: 1px solid #ddd;
- }
- tr:hover {
- background-color: #f5f5f5;
- }
- .level-CRITICAL {
- background-color: #ffebee;
- border-left: 5px solid #c62828;
- }
- .level-HIGH {
- background-color: #fff3e0;
- border-left: 5px solid #ef6c00;
- }
- .level-MEDIUM {
- background-color: #fff9c4;
- border-left: 5px solid #f57f17;
- }
- .level-LOW, .level-INFO {
- border-left: 5px solid #0078d4;
- }
- .value {
- font-family: 'Courier New', monospace;
- background-color: #f5f5f5;
- padding: 5px;
- border-radius: 3px;
- }
- .path {
- font-family: 'Courier New', monospace;
- color: #0078d4;
- font-weight: bold;
- }
- .working {
- color: #2e7d32;
- }
- .custom {
- color: #d84315;
- }
- .recommendation {
- background-color: #e8f5e9;
- border: 1px solid #4caf50;
- padding: 15px;
- border-radius: 5px;
- margin: 20px 0;
- }
- .recommendation h3 {
- color: #2e7d32;
- margin-top: 0;
- }
- </style>
- </head>
- <body>
- <h1>🔍 Thunderbolt Dock Configuration Comparison Report</h1>
- <div class="summary">
- <h3>Summary</h3>
- <div class="summary-item critical-count">Critical: $($criticalDifferences.Count)</div>
- <div class="summary-item warning-count">High/Medium: $($warnings.Count)</div>
- <div class="summary-item info-count">Total Differences: $($differences.Count)</div>
- <p><strong>Working Image:</strong> $WorkingImageJson</p>
- <p><strong>Custom Image:</strong> $CustomImageJson</p>
- <p><strong>Report Generated:</strong> $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p>
- </div>
- "@
- if ($criticalDifferences.Count -gt 0) {
- $htmlContent += @"
- <h2>🔴 Critical Differences (Action Required)</h2>
- <div class="recommendation">
- <h3>⚠️ These settings are most likely causing your Ethernet pre-login issue!</h3>
- <p>Focus on fixing these registry keys and policies first.</p>
- </div>
- <table>
- <tr>
- <th>Setting Path</th>
- <th>Working Image (✓)</th>
- <th>Your Custom Image (✗)</th>
- <th>Note</th>
- </tr>
- "@
- foreach ($diff in $criticalDifferences) {
- $htmlContent += @"
- <tr class="level-$($diff.Level)">
- <td class="path">$($diff.Path)</td>
- <td class="value working">$($diff.WorkingValue)</td>
- <td class="value custom">$($diff.CustomValue)</td>
- <td>$($diff.Message)</td>
- </tr>
- "@
- }
- $htmlContent += "</table>"
- }
- if ($warnings.Count -gt 0) {
- $htmlContent += @"
- <h2>⚠️ High/Medium Priority Differences</h2>
- <table>
- <tr>
- <th>Setting Path</th>
- <th>Working Image</th>
- <th>Custom Image</th>
- <th>Note</th>
- </tr>
- "@
- foreach ($diff in $warnings) {
- $htmlContent += @"
- <tr class="level-$($diff.Level)">
- <td class="path">$($diff.Path)</td>
- <td class="value working">$($diff.WorkingValue)</td>
- <td class="value custom">$($diff.CustomValue)</td>
- <td>$($diff.Message)</td>
- </tr>
- "@
- }
- $htmlContent += "</table>"
- }
- $otherDiffs = $differences | Where-Object { $_.Level -notin @('CRITICAL', 'HIGH', 'MEDIUM') }
- if ($otherDiffs.Count -gt 0) {
- $htmlContent += @"
- <h2>ℹ️ Other Differences (Lower Priority)</h2>
- <table>
- <tr>
- <th>Setting Path</th>
- <th>Working Image</th>
- <th>Custom Image</th>
- <th>Note</th>
- </tr>
- "@
- foreach ($diff in $otherDiffs) {
- $htmlContent += @"
- <tr class="level-$($diff.Level)">
- <td class="path">$($diff.Path)</td>
- <td class="value working">$($diff.WorkingValue)</td>
- <td class="value custom">$($diff.CustomValue)</td>
- <td>$($diff.Message)</td>
- </tr>
- "@
- }
- $htmlContent += "</table>"
- }
- $htmlContent += @"
- </body>
- </html>
- "@
- # Save HTML report
- $htmlContent | Out-File -FilePath $comparisonReport -Encoding UTF8
- # Save text report
- $textReport = @"
- ============================================
- THUNDERBOLT DOCK CONFIGURATION COMPARISON
- ============================================
- Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
- Working Image: $WorkingImageJson
- Custom Image: $CustomImageJson
- SUMMARY
- -------
- Total Differences: $($differences.Count)
- Critical: $($criticalDifferences.Count)
- High/Medium: $($warnings.Count)
- "@
- if ($criticalDifferences.Count -gt 0) {
- $textReport += @"
- ========================================
- CRITICAL DIFFERENCES (ACTION REQUIRED)
- ========================================
- "@
- foreach ($diff in $criticalDifferences) {
- $textReport += @"
- Path: $($diff.Path)
- Working Image: $($diff.WorkingValue)
- Custom Image: $($diff.CustomValue)
- Note: $($diff.Message)
- ----------------------------------------
- "@
- }
- }
- if ($warnings.Count -gt 0) {
- $textReport += @"
- ========================================
- HIGH/MEDIUM PRIORITY DIFFERENCES
- ========================================
- "@
- foreach ($diff in $warnings) {
- $textReport += @"
- Path: $($diff.Path)
- Working Image: $($diff.WorkingValue)
- Custom Image: $($diff.CustomValue)
- Note: $($diff.Message)
- ----------------------------------------
- "@
- }
- }
- $textReport | Out-File -FilePath $comparisonText -Encoding UTF8
- # Final output
- Write-Host "`n============================================" -ForegroundColor Cyan
- Write-Host "REPORTS GENERATED" -ForegroundColor Cyan
- Write-Host "============================================`n" -ForegroundColor Cyan
- Write-Host "HTML Report: " -NoNewline
- Write-Host $comparisonReport -ForegroundColor Green
- Write-Host "Text Report: " -NoNewline
- Write-Host $comparisonText -ForegroundColor Green
- Write-Host "`nOpening HTML report..." -ForegroundColor Yellow
- Start-Process $comparisonReport
- Write-Host "`n✅ Comparison complete!" -ForegroundColor Green
- 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