CCCPaste

93ec6dce4cf3e

#Requires -RunAsAdministrator

<#
.SYNOPSIS
    Comprehensive Thunderbolt/Docking Station Diagnostic Scanner
    
.DESCRIPTION
    Scans all relevant settings, drivers, registry keys, and configurations
    that affect Thunderbolt dock Ethernet connectivity at pre-login.
    
.NOTES
    Author: System Diagnostic Tool
    Version: 1.0
    Run this on BOTH the working HP image AND your custom image for comparison
#>

# Set output file
$outputPath = "$env:USERPROFILE\Desktop\TB_Dock_Diagnostic_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
$jsonPath = "$env:USERPROFILE\Desktop\TB_Dock_Diagnostic_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"

# Function to write both to console and file
function Write-Output-Both {
    param([string]$Message)
    Write-Host $Message
    Add-Content -Path $outputPath -Value $Message
}

# Start transcript
Start-Transcript -Path "$env:USERPROFILE\Desktop\TB_Dock_Transcript_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"

Write-Output-Both "============================================"
Write-Output-Both "THUNDERBOLT DOCK DIAGNOSTIC SCANNER"
Write-Output-Both "Scan Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Output-Both "Computer: $env:COMPUTERNAME"
Write-Output-Both "============================================`n"

# Create hashtable for JSON export
$diagnosticData = @{}

# ============================================
# 1. SYSTEM INFORMATION
# ============================================
Write-Output-Both "`n[1] === SYSTEM INFORMATION ===`n"

$computerInfo = Get-ComputerInfo | Select-Object `
    WindowsProductName, WindowsVersion, WindowsBuildLabEx, `
    OsHardwareAbstractionLayer, BiosFirmwareType, BiosVersion, `
    BiosManufacturer, CsManufacturer, CsModel

$diagnosticData['SystemInfo'] = $computerInfo
$computerInfo | Format-List | Out-String | Write-Output-Both

# BIOS Version
$bios = Get-CimInstance -ClassName Win32_BIOS
Write-Output-Both "BIOS Version: $($bios.SMBIOSBIOSVersion)"
Write-Output-Both "BIOS Release Date: $($bios.ReleaseDate)"
$diagnosticData['BIOS'] = @{
    Version = $bios.SMBIOSBIOSVersion
    ReleaseDate = $bios.ReleaseDate
}

# ============================================
# 2. KERNEL DMA PROTECTION STATUS
# ============================================
Write-Output-Both "`n[2] === KERNEL DMA PROTECTION STATUS ===`n"

$dmaProtection = Get-CimInstance -Namespace root\Microsoft\Windows\DeviceGuard -ClassName Win32_DeviceGuard -ErrorAction SilentlyContinue
if ($dmaProtection) {
    Write-Output-Both "Kernel DMA Protection Available: $($dmaProtection.VirtualizationBasedSecurityStatus -ne 0)"
    $diagnosticData['KernelDMAProtection'] = @{
        Available = $dmaProtection.VirtualizationBasedSecurityStatus -ne 0
        Status = $dmaProtection
    }
}

# Check via msinfo32 alternative
$msinfo = systeminfo | Select-String "Kernel DMA Protection"
Write-Output-Both $msinfo

# ============================================
# 3. REGISTRY KEYS - DMA & THUNDERBOLT
# ============================================
Write-Output-Both "`n[3] === CRITICAL REGISTRY KEYS ===`n"

$registryKeys = @{
    # Kernel DMA Protection
    'DMA_DeviceEnumerationPolicy' = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection'
    
    # BitLocker DMA Settings
    'BitLocker_DMA' = 'HKLM:\SOFTWARE\Policies\Microsoft\FVE'
    
    # Device Guard / VBS
    'DeviceGuard' = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard'
    
    # Power Settings
    'PowerSettings' = 'HKLM:\SYSTEM\CurrentControlSet\Control\Power'
    
    # Thunderbolt Settings
    'Thunderbolt_DTBT' = 'HKLM:\SYSTEM\CurrentControlSet\Services\DTBT'
    'Thunderbolt_Policy' = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Thunderbolt'
    
    # Fast Startup
    'FastStartup' = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power'
    
    # Network related
    'Dot3Svc' = 'HKLM:\SYSTEM\CurrentControlSet\Services\dot3svc'
    'Wired AutoConfig' = 'HKLM:\SYSTEM\CurrentControlSet\Services\dot3svc'
}

$diagnosticData['RegistryKeys'] = @{}

foreach ($key in $registryKeys.GetEnumerator()) {
    Write-Output-Both "`n--- $($key.Key) ---"
    Write-Output-Both "Path: $($key.Value)"
    
    if (Test-Path $key.Value) {
        $regValues = Get-ItemProperty -Path $key.Value -ErrorAction SilentlyContinue
        $regValues | Format-List | Out-String | Write-Output-Both
        $diagnosticData['RegistryKeys'][$key.Key] = $regValues
    } else {
        Write-Output-Both "Registry path does not exist"
        $diagnosticData['RegistryKeys'][$key.Key] = "NOT_FOUND"
    }
}

# Specific important values
Write-Output-Both "`n--- SPECIFIC DMA POLICY VALUES ---"
$specificKeys = @(
    @{Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection'; Name='DeviceEnumerationPolicy'},
    @{Path='HKLM:\SOFTWARE\Policies\Microsoft\FVE'; Name='DisableExternalDMAUnderLock'},
    @{Path='HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power'; Name='HiberbootEnabled'},
    @{Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard'; Name='EnableVirtualizationBasedSecurity'},
    @{Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard'; Name='HypervisorEnforcedCodeIntegrity'}
)

$diagnosticData['SpecificPolicies'] = @{}

foreach ($item in $specificKeys) {
    try {
        $value = Get-ItemProperty -Path $item.Path -Name $item.Name -ErrorAction Stop
        Write-Output-Both "$($item.Path)\$($item.Name) = $($value.$($item.Name))"
        $diagnosticData['SpecificPolicies']["$($item.Path)\$($item.Name)"] = $value.$($item.Name)
    } catch {
        Write-Output-Both "$($item.Path)\$($item.Name) = NOT SET"
        $diagnosticData['SpecificPolicies']["$($item.Path)\$($item.Name)"] = "NOT_SET"
    }
}

# ============================================
# 4. THUNDERBOLT / USB4 DRIVERS & DEVICES
# ============================================
Write-Output-Both "`n[4] === THUNDERBOLT & USB4 DRIVERS ===`n"

# Thunderbolt Controllers
$tbControllers = Get-PnpDevice -Class System | Where-Object {
    $_.FriendlyName -match "Thunderbolt|USB4|TBT|JHL"
}

Write-Output-Both "Thunderbolt/USB4 Controllers:"
$diagnosticData['ThunderboltControllers'] = @()
foreach ($ctrl in $tbControllers) {
    Write-Output-Both "`nDevice: $($ctrl.FriendlyName)"
    Write-Output-Both "Status: $($ctrl.Status)"
    Write-Output-Both "Instance ID: $($ctrl.InstanceId)"
    
    # Get driver info
    $driver = Get-PnpDeviceProperty -InstanceId $ctrl.InstanceId -KeyName DEVPKEY_Device_DriverVersion -ErrorAction SilentlyContinue
    if ($driver) {
        Write-Output-Both "Driver Version: $($driver.Data)"
    }
    
    # DMA Remapping Policy
    $dmaPolicy = Get-PnpDeviceProperty -InstanceId $ctrl.InstanceId -KeyName DEVPKEY_Device_DmaRemappingPolicy -ErrorAction SilentlyContinue
    if ($dmaPolicy) {
        Write-Output-Both "DMA Remapping Policy: $($dmaPolicy.Data)"
    }
    
    $diagnosticData['ThunderboltControllers'] += @{
        Name = $ctrl.FriendlyName
        Status = $ctrl.Status
        InstanceId = $ctrl.InstanceId
        DriverVersion = $driver.Data
        DMARemappingPolicy = $dmaPolicy.Data
    }
}

# USB4 Host Router
$usb4Routers = Get-PnpDevice | Where-Object {
    $_.FriendlyName -match "USB4.*Router"
}

Write-Output-Both "`n--- USB4 Routers ---"
$diagnosticData['USB4Routers'] = @()
foreach ($router in $usb4Routers) {
    Write-Output-Both "`nRouter: $($router.FriendlyName)"
    Write-Output-Both "Status: $($router.Status)"
    
    $routerDriver = Get-PnpDeviceProperty -InstanceId $router.InstanceId -KeyName DEVPKEY_Device_DriverVersion -ErrorAction SilentlyContinue
    Write-Output-Both "Driver Version: $($routerDriver.Data)"
    
    $diagnosticData['USB4Routers'] += @{
        Name = $router.FriendlyName
        Status = $router.Status
        DriverVersion = $routerDriver.Data
    }
}

# ============================================
# 5. NETWORK ADAPTERS (DOCK & INTERNAL)
# ============================================
Write-Output-Both "`n[5] === NETWORK ADAPTERS ===`n"

$networkAdapters = Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, MacAddress, DriverVersion, DriverProvider

Write-Output-Both "All Network Adapters:"
$networkAdapters | Format-Table -AutoSize | Out-String | Write-Output-Both

$diagnosticData['NetworkAdapters'] = $networkAdapters

# Detailed info for each adapter
foreach ($adapter in $networkAdapters) {
    Write-Output-Both "`n--- $($adapter.Name) ---"
    
    # Advanced properties
    $advProps = Get-NetAdapterAdvancedProperty -Name $adapter.Name -ErrorAction SilentlyContinue
    if ($advProps) {
        $advProps | Format-Table RegistryKeyword, DisplayValue -AutoSize | Out-String | Write-Output-Both
    }
    
    # Power Management
    $powerMgmt = Get-NetAdapterPowerManagement -Name $adapter.Name -ErrorAction SilentlyContinue
    if ($powerMgmt) {
        Write-Output-Both "Power Management Settings:"
        $powerMgmt | Format-List | Out-String | Write-Output-Both
    }
}

# Specifically check for dock NICs
$dockNics = Get-NetAdapter | Where-Object {
    $_.InterfaceDescription -match "Thunderbolt|Dock|RTL|Intel.*I219|Realtek"
}

Write-Output-Both "`n--- POTENTIAL DOCK NICS ---"
$diagnosticData['DockNICs'] = @()
foreach ($nic in $dockNics) {
    Write-Output-Both "NIC: $($nic.InterfaceDescription)"
    Write-Output-Both "Status: $($nic.Status)"
    Write-Output-Both "Driver: $($nic.DriverVersion) ($($nic.DriverProvider))"
    
    # Get PnP Device info
    $pnpDevice = Get-PnpDevice | Where-Object {
        $_.FriendlyName -eq $nic.InterfaceDescription
    } | Select-Object -First 1
    
    if ($pnpDevice) {
        # Check DMA Remapping
        $dmaRemap = Get-PnpDeviceProperty -InstanceId $pnpDevice.InstanceId -KeyName DEVPKEY_Device_DmaRemappingPolicy -ErrorAction SilentlyContinue
        Write-Output-Both "DMA Remapping Policy: $($dmaRemap.Data)"
        
        $diagnosticData['DockNICs'] += @{
            Name = $nic.InterfaceDescription
            Status = $nic.Status
            DriverVersion = $nic.DriverVersion
            DMARemapping = $dmaRemap.Data
        }
    }
}

# ============================================
# 6. SERVICES STATUS
# ============================================
Write-Output-Both "`n[6] === CRITICAL SERVICES ===`n"

$services = @(
    'dot3svc',           # Wired AutoConfig
    'WinHttpAutoProxySvc',
    'NlaSvc',            # Network Location Awareness
    'Dhcp',
    'Dnscache',
    'ThunderboltService' # If Intel TB software installed
)

$diagnosticData['Services'] = @{}

foreach ($svc in $services) {
    $service = Get-Service -Name $svc -ErrorAction SilentlyContinue
    if ($service) {
        Write-Output-Both "$($svc): Status=$($service.Status), StartType=$($service.StartType)"
        $diagnosticData['Services'][$svc] = @{
            Status = $service.Status
            StartType = $service.StartType
        }
    } else {
        Write-Output-Both "$($svc): NOT INSTALLED"
        $diagnosticData['Services'][$svc] = "NOT_INSTALLED"
    }
}

# ============================================
# 7. GROUP POLICIES
# ============================================
Write-Output-Both "`n[7] === APPLIED GROUP POLICIES ===`n"

Write-Output-Both "Running GPResult..."
$gpResult = gpresult /r /scope:computer 2>&1 | Out-String
Write-Output-Both $gpResult

# Export detailed GP report
$gpReportPath = "$env:USERPROFILE\Desktop\GPReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
gpresult /h $gpReportPath /f
Write-Output-Both "`nDetailed GP Report saved to: $gpReportPath"

# ============================================
# 8. BOOT CONFIGURATION
# ============================================
Write-Output-Both "`n[8] === BOOT CONFIGURATION ===`n"

# BCDEdit settings
Write-Output-Both "BCDEdit Settings:"
$bcdOutput = bcdedit /enum | Out-String
Write-Output-Both $bcdOutput

$diagnosticData['BCDEdit'] = $bcdOutput

# ============================================
# 9. UEFI/BIOS SETTINGS (from WMI)
# ============================================
Write-Output-Both "`n[9] === FIRMWARE SETTINGS (if available) ===`n"

# Try to get HP BIOS settings
try {
    $hpBios = Get-CimInstance -Namespace root/HP/InstrumentedBIOS -ClassName HP_BIOSSetting -ErrorAction Stop
    Write-Output-Both "HP BIOS Settings found:"
    $hpBios | Where-Object {
        $_.Name -match "Thunderbolt|Network|PXE|Wake|DMA|Virtualization|VT-d|IOMMU"
    } | Format-Table Name, Value -AutoSize | Out-String | Write-Output-Both
    
    $diagnosticData['HPBIOSSettings'] = $hpBios | Where-Object {
        $_.Name -match "Thunderbolt|Network|PXE|Wake|DMA|Virtualization|VT-d|IOMMU"
    }
} catch {
    Write-Output-Both "HP BIOS WMI namespace not accessible (normal for non-HP or restricted access)"
}

# ============================================
# 10. DRIVER STORE - ETHERNET DRIVERS
# ============================================
Write-Output-Both "`n[10] === INSTALLED ETHERNET DRIVERS (Driver Store) ===`n"

$drivers = Get-WindowsDriver -Online | Where-Object {
    $_.ClassName -match "Net" -and $_.ProviderName -match "Intel|Realtek|HP"
}

Write-Output-Both "Relevant Network Drivers in Driver Store:"
$diagnosticData['DriverStore'] = @()
foreach ($drv in $drivers) {
    Write-Output-Both "`nDriver: $($drv.Driver)"
    Write-Output-Both "Class: $($drv.ClassName)"
    Write-Output-Both "Provider: $($drv.ProviderName)"
    Write-Output-Both "Version: $($drv.Version)"
    Write-Output-Both "Date: $($drv.Date)"
    
    $diagnosticData['DriverStore'] += @{
        Driver = $drv.Driver
        Class = $drv.ClassName
        Provider = $drv.ProviderName
        Version = $drv.Version
        Date = $drv.Date
    }
}

# ============================================
# 11. INSTALLED THUNDERBOLT SOFTWARE
# ============================================
Write-Output-Both "`n[11] === THUNDERBOLT SOFTWARE ===`n"

$tbSoftware = Get-Package -Name "*Thunderbolt*","*Intel*Connection*" -ErrorAction SilentlyContinue
if ($tbSoftware) {
    Write-Output-Both "Installed Thunderbolt/Intel Software:"
    $tbSoftware | Format-Table Name, Version -AutoSize | Out-String | Write-Output-Both
    $diagnosticData['ThunderboltSoftware'] = $tbSoftware
} else {
    Write-Output-Both "No Intel Thunderbolt software detected (using Microsoft USB4 stack)"
    $diagnosticData['ThunderboltSoftware'] = "Microsoft_USB4_Stack_Only"
}

# ============================================
# 12. SECURITY FEATURES
# ============================================
Write-Output-Both "`n[12] === SECURITY FEATURES ===`n"

# Secure Boot
$secureBoot = Confirm-SecureBootUEFI
Write-Output-Both "Secure Boot: $secureBoot"

# BitLocker Status
$bitlocker = Get-BitLockerVolume -MountPoint C: -ErrorAction SilentlyContinue
if ($bitlocker) {
    Write-Output-Both "BitLocker Protection Status: $($bitlocker.ProtectionStatus)"
    Write-Output-Both "BitLocker Encryption Percentage: $($bitlocker.EncryptionPercentage)%"
    $diagnosticData['BitLocker'] = @{
        ProtectionStatus = $bitlocker.ProtectionStatus
        EncryptionPercentage = $bitlocker.EncryptionPercentage
    }
}

# Credential Guard / HVCI
$deviceGuardStatus = Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard -ErrorAction SilentlyContinue
if ($deviceGuardStatus) {
    Write-Output-Both "`nDevice Guard Status:"
    Write-Output-Both "Virtualization Based Security: $($deviceGuardStatus.VirtualizationBasedSecurityStatus)"
    Write-Output-Both "Security Services Running: $($deviceGuardStatus.SecurityServicesRunning -join ', ')"
    $diagnosticData['DeviceGuard'] = $deviceGuardStatus
}

# ============================================
# 13. CURRENT DOCK CONNECTION (if connected)
# ============================================
Write-Output-Both "`n[13] === CURRENT THUNDERBOLT DOCK CONNECTION ===`n"

$tbDevices = Get-PnpDevice -Class System,USB | Where-Object {
    $_.FriendlyName -match "Thunderbolt|TBT|Dock|G4"
}

Write-Output-Both "Connected Thunderbolt/Dock Devices:"
$diagnosticData['ConnectedDockDevices'] = @()
foreach ($dev in $tbDevices) {
    Write-Output-Both "`nDevice: $($dev.FriendlyName)"
    Write-Output-Both "Status: $($dev.Status)"
    Write-Output-Both "Instance: $($dev.InstanceId)"
    
    # Get all properties
    $allProps = Get-PnpDeviceProperty -InstanceId $dev.InstanceId
    $relevantProps = $allProps | Where-Object {
        $_.KeyName -match "FirmwareVersion|DriverVersion|HardwareId|CompatibleId|Manufacturer"
    }
    $relevantProps | Format-Table KeyName, Data -AutoSize | Out-String | Write-Output-Both
    
    $diagnosticData['ConnectedDockDevices'] += @{
        Name = $dev.FriendlyName
        Status = $dev.Status
        InstanceId = $dev.InstanceId
        Properties = $relevantProps
    }
}

# ============================================
# 14. WINDOWS UPDATE / FEATURE UPDATE
# ============================================
Write-Output-Both "`n[14] === WINDOWS UPDATE INFO ===`n"

$updateSession = New-Object -ComObject Microsoft.Update.Session
$updateSearcher = $updateSession.CreateUpdateSearcher()
$historyCount = $updateSearcher.GetTotalHistoryCount()

Write-Output-Both "Total Update History Count: $historyCount"

# Get recent updates
$recentUpdates = $updateSearcher.QueryHistory(0, 20) | Where-Object {
    $_.Title -match "Thunderbolt|Network|Driver|Firmware|USB"
} | Select-Object Title, Date, ResultCode

if ($recentUpdates) {
    Write-Output-Both "`nRecent Relevant Updates:"
    $recentUpdates | Format-Table -AutoSize | Out-String | Write-Output-Both
    $diagnosticData['RecentUpdates'] = $recentUpdates
}

# ============================================
# FINALIZE & EXPORT
# ============================================
Write-Output-Both "`n============================================"
Write-Output-Both "DIAGNOSTIC SCAN COMPLETE"
Write-Output-Both "============================================"
Write-Output-Both "`nOutput Files:"
Write-Output-Both "Text Report: $outputPath"
Write-Output-Both "JSON Data: $jsonPath"

# Export to JSON for easy comparison
$diagnosticData | ConvertTo-Json -Depth 10 | Out-File -FilePath $jsonPath -Encoding UTF8

Write-Host "`n`nDiagnostic scan complete!" -ForegroundColor Green
Write-Host "Files saved to Desktop:" -ForegroundColor Green
Write-Host "  - $outputPath" -ForegroundColor Cyan
Write-Host "  - $jsonPath" -ForegroundColor Cyan
Write-Host "`nRun this script on both your working HP image AND your custom image," -ForegroundColor Yellow
Write-Host "then compare the JSON files to find differences." -ForegroundColor Yellow

Stop-Transcript