add debug
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user