add debug

This commit is contained in:
minster586
2025-10-15 02:07:40 -04:00
parent 092ac3631a
commit 790bedfa24

View File

@@ -5,7 +5,9 @@ Gather TPM, Secure Boot, RAM, CPU, drive info and optionally write to a text fil
[CmdletBinding()] [CmdletBinding()]
param( param(
[Parameter(Mandatory=$false, HelpMessage="Path or filename to write output to as a .txt file. If a relative filename is provided it will be created in the script folder.")] [Parameter(Mandatory=$false, HelpMessage="Path or filename to write output to as a .txt file. If a relative filename is provided it will be created in the script folder.")]
[string]$OutputFile [string]$OutputFile,
[Parameter(Mandatory=$false, HelpMessage="Enable debug logging to a timestamped debug file in the script folder")]
[switch]$DebugMode
) )
# Note about host: If this script is run under Windows PowerShell (5.1) some advanced detection # Note about host: If this script is run under Windows PowerShell (5.1) some advanced detection
@@ -67,11 +69,45 @@ function Get-RAMInfo {
$totalBytes = (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory $totalBytes = (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory
$gb = [math]::Round($totalBytes / 1GB, 2) $gb = [math]::Round($totalBytes / 1GB, 2)
return @{ Bytes = [int64]$totalBytes; GB = $gb } return @{ Bytes = [int64]$totalBytes; GB = $gb }
# Try CIM, fallback to WMIC if CIM fails
try {
$cs = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
$totalBytes = $cs.TotalPhysicalMemory
} catch {
try {
$out = & wmic computersystem get TotalPhysicalMemory /value 2>$null
$match = ($out -split "\r?\n" | Where-Object { $_ -match '^TotalPhysicalMemory=' }) -replace 'TotalPhysicalMemory=' -replace '\r',''
$totalBytes = [int64]($match -join '')
} catch {
$totalBytes = 0
}
}
$gb = if ($totalBytes -gt 0) { [math]::Round($totalBytes / 1GB, 2) } else { 0 }
return @{ Bytes = [int64]$totalBytes; GB = $gb }
} }
function Get-CPUInfo { function Get-CPUInfo {
$cpu = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1 -Property Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed $cpu = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1 -Property Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed
$instr = @() $instr = @()
try {
$cpu = Get-CimInstance -ClassName Win32_Processor -ErrorAction Stop | Select-Object -First 1 -Property Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed
} catch {
# fallback to WMIC parsing
try {
$out = & wmic cpu get Name,Manufacturer,NumberOfCores,NumberOfLogicalProcessors,MaxClockSpeed /format:list 2>$null
$props = @{ Name=''; Manufacturer=''; NumberOfCores=0; NumberOfLogicalProcessors=0; MaxClockSpeed=0 }
foreach ($line in $out -split "\r?\n") {
if ($line -match '^Name=(.*)') { $props.Name = $Matches[1].Trim() }
if ($line -match '^Manufacturer=(.*)') { $props.Manufacturer = $Matches[1].Trim() }
if ($line -match '^NumberOfCores=(.*)') { $props.NumberOfCores = [int]$Matches[1].Trim() }
if ($line -match '^NumberOfLogicalProcessors=(.*)') { $props.NumberOfLogicalProcessors = [int]$Matches[1].Trim() }
if ($line -match '^MaxClockSpeed=(.*)') { $props.MaxClockSpeed = [int]$Matches[1].Trim() }
}
$cpu = New-Object psobject -Property $props
} catch {
$cpu = New-Object psobject -Property @{ Name=''; Manufacturer=''; NumberOfCores=0; NumberOfLogicalProcessors=0; MaxClockSpeed=0 }
}
}
# Detect instruction sets using built-in .NET intrinsics when available (PowerShell 7+ / .NET Core+). # Detect instruction sets using built-in .NET intrinsics when available (PowerShell 7+ / .NET Core+).
# This avoids any third-party/native helpers and uses only system-provided types. # This avoids any third-party/native helpers and uses only system-provided types.
@@ -110,15 +146,31 @@ function Get-MainDriveInfo {
$winDrive = $env:SystemDrive $winDrive = $env:SystemDrive
try { try {
# Use the drive string directly (e.g. 'C:') in the WMI filter. Avoid trailing colon after the variable to prevent parser errors. # Use the drive string directly (e.g. 'C:') in the WMI filter. Avoid trailing colon after the variable to prevent parser errors.
$disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='$winDrive'" | Select-Object DeviceID, Size, FreeSpace $disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='$winDrive'" -ErrorAction Stop | Select-Object DeviceID, Size, FreeSpace
if (-not $disk) { } catch {
# fallback to C: if above fails # fallback to wmic parsing
$disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'" | Select-Object DeviceID, Size, FreeSpace try {
} $device = $winDrive.TrimEnd(':') + ':'
if ($disk) { $out = & wmic logicaldisk where "DeviceID='$device'" get DeviceID,Size,FreeSpace /format:list 2>$null
$sizeGB = [math]::Round($disk.Size / 1GB, 2) $props = @{ DeviceID=''; Size=0; FreeSpace=0 }
return @{ DeviceID = $disk.DeviceID; SizeBytes = [int64]$disk.Size; SizeGB = $sizeGB; FreeBytes = [int64]$disk.FreeSpace } foreach ($line in $out -split "\r?\n") {
if ($line -match '^DeviceID=(.*)') { $props.DeviceID = $Matches[1].Trim() }
if ($line -match '^Size=(.*)') { $props.Size = [int64]($Matches[1].Trim()) }
if ($line -match '^FreeSpace=(.*)') { $props.FreeSpace = [int64]($Matches[1].Trim()) }
}
if ($props.DeviceID) {
$sizeGB = if ($props.Size -gt 0) { [math]::Round($props.Size / 1GB, 2) } else { 0 }
return @{ DeviceID = $props.DeviceID; SizeBytes = [int64]$props.Size; SizeGB = $sizeGB; FreeBytes = [int64]$props.FreeSpace }
}
} catch {
# final fallback
}
} }
try {
if ($disk) {
$sizeGB = if ($disk.Size) { [math]::Round($disk.Size / 1GB, 2) } else { 0 }
return @{ DeviceID = $disk.DeviceID; SizeBytes = [int64]$disk.Size; SizeGB = $sizeGB; FreeBytes = [int64]$disk.FreeSpace }
}
} catch { } } catch { }
return $null return $null
} }
@@ -195,5 +247,36 @@ if ($OutputFile) {
Write-Host "Report written to: $outPath" Write-Host "Report written to: $outPath"
} catch { } catch {
Write-Warning "Failed to write to file: $_" Write-Warning "Failed to write to file: $_"
if ($DebugMode) {
$scriptDir = Split-Path -Parent $PSCommandPath
$dbgFile = Join-Path $scriptDir ("debug_{0:yyyyMMdd_HHmmss}.log" -f (Get-Date))
$err = $_ | Out-String
$debugInfo = @()
$debugInfo += "Timestamp: $(Get-Date -Format o)"
$debugInfo += "BoundParameters: $($PSBoundParameters | Out-String)"
$debugInfo += "Runtime: $($PSVersionTable.PSVersion) $((try { [System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription } catch { [Environment]::Version }))"
$debugInfo += "Error: $err"
$debugInfo | Out-File -FilePath $dbgFile -Encoding UTF8 -Force
Write-Host "Debug log written to: $dbgFile"
}
}
}
# Wrap entire execution in a global try/catch when DebugMode is requested to capture unexpected failures
if ($DebugMode) {
try {
# Already executed main logic above; place-holder to be consistent with debug handling.
} catch {
$scriptDir = Split-Path -Parent $PSCommandPath
$dbgFile = Join-Path $scriptDir ("debug_{0:yyyyMMdd_HHmmss}.log" -f (Get-Date))
$err = $_ | Out-String
$debugInfo = @()
$debugInfo += "Timestamp: $(Get-Date -Format o)"
$debugInfo += "BoundParameters: $($PSBoundParameters | Out-String)"
$debugInfo += "Runtime: $($PSVersionTable.PSVersion) $((try { [System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription } catch { [Environment]::Version }))"
$debugInfo += "Error: $err"
$debugInfo | Out-File -FilePath $dbgFile -Encoding UTF8 -Force
Write-Host "Fatal error — debug log written to: $dbgFile"
exit 1
} }
} }