# ============================================================ # PC / Laptop Audit Report # Generates one clean HTML report on Desktop # Includes: # Brand / Model / Serial Number / CPU / RAM / Storage / Storage % # GPU / Windows / BIOS / Battery Design Capacity / Battery Health # ============================================================ $ReportTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $Desktop = [Environment]::GetFolderPath("Desktop") $OutputFile = Join-Path $Desktop "PC-Audit-Report.html" $OfficialBatteryReport = Join-Path $env:TEMP "official-battery-report.html" function Get-SafeValue { param( $Value, $Fallback = "N/A" ) if ($null -eq $Value -or $Value -eq "") { return $Fallback } return $Value } function Convert-ToHtmlSafe { param($Value) if ($null -eq $Value -or $Value -eq "") { return "N/A" } $Text = [string]$Value $Text = $Text -replace "&", "&" $Text = $Text -replace "<", "<" $Text = $Text -replace ">", ">" $Text = $Text -replace '"', """ $Text = $Text -replace "'", "'" return $Text } function Get-BatteryReportValue { param( [string]$HtmlContent, [string]$Label ) if ($null -eq $HtmlContent -or $HtmlContent -eq "") { return "N/A" } $Pattern = "(?is)]*>\s*(?:]*>)?\s*$Label\s*(?:)?\s*\s*]*>\s*(.*?)\s*" if ($HtmlContent -match $Pattern) { return ($matches[1] -replace "<.*?>", "").Trim() } return "N/A" } function Convert-CapacityToNumber { param([string]$CapacityText) if ($null -eq $CapacityText -or $CapacityText -eq "N/A") { return $null } $NumberOnly = ($CapacityText -replace "[^\d]", "") if ($NumberOnly) { return [double]$NumberOnly } return $null } function Get-PercentUsed { param( [double]$Size, [double]$FreeSpace ) if ($Size -gt 0) { $Used = $Size - $FreeSpace return [math]::Round(($Used / $Size) * 100, 1) } return "N/A" } # ============================================================ # Generate official Windows battery report # ============================================================ $BatteryReportContent = "" try { powercfg /batteryreport /output $OfficialBatteryReport | Out-Null $BatteryReportContent = Get-Content $OfficialBatteryReport -Raw -ErrorAction SilentlyContinue } catch { $BatteryReportContent = "" } # ============================================================ # Basic system info # ============================================================ $ComputerSystem = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue $BIOS = Get-CimInstance Win32_BIOS -ErrorAction SilentlyContinue $OS = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue $CPU = Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue | Select-Object -First 1 $ComputerName = Get-SafeValue $env:COMPUTERNAME $Manufacturer = Get-SafeValue $ComputerSystem.Manufacturer $Model = Get-SafeValue $ComputerSystem.Model $SerialNumber = Get-SafeValue $BIOS.SerialNumber $CpuName = Get-SafeValue $CPU.Name $CpuCores = Get-SafeValue $CPU.NumberOfCores $CpuThreads = Get-SafeValue $CPU.NumberOfLogicalProcessors $BiosDate = "N/A" if ($BIOS.ReleaseDate) { try { $BiosDate = [Management.ManagementDateTimeConverter]::ToDateTime($BIOS.ReleaseDate).ToString("yyyy-MM-dd") } catch { $BiosDate = "N/A" } } $BiosInfo = "$(Get-SafeValue $BIOS.SMBIOSBIOSVersion) / $BiosDate" $WindowsInfo = "$(Get-SafeValue $OS.Caption) - Build $(Get-SafeValue $OS.BuildNumber) - $(Get-SafeValue $OS.OSArchitecture)" $PlatformRole = switch ($ComputerSystem.PCSystemType) { 1 { "Desktop" } 2 { "Laptop / Mobile" } 3 { "Workstation" } 4 { "Enterprise Server" } 5 { "SOHO Server" } 6 { "Appliance PC" } 7 { "Performance Server" } 8 { "Maximum" } default { "Unknown" } } # ============================================================ # RAM info # ============================================================ $RamModules = Get-CimInstance Win32_PhysicalMemory -ErrorAction SilentlyContinue if ($RamModules) { $TotalRamGB = [math]::Round(($RamModules | Measure-Object -Property Capacity -Sum).Sum / 1GB, 1) } else { $TotalRamGB = "N/A" } $RamRows = "" foreach ($Ram in $RamModules) { $RamSizeGB = if ($Ram.Capacity) { [math]::Round($Ram.Capacity / 1GB, 1) } else { "N/A" } $RamSpeed = Get-SafeValue $Ram.Speed $RamManufacturer = Get-SafeValue $Ram.Manufacturer $RamPartNumber = Get-SafeValue $Ram.PartNumber $RamSlot = Get-SafeValue $Ram.DeviceLocator $RamRows += "$(Convert-ToHtmlSafe $RamSlot)$RamSizeGB GB$RamSpeed MHz$(Convert-ToHtmlSafe $RamManufacturer)$(Convert-ToHtmlSafe $RamPartNumber)`n" } if ($RamRows -eq "") { $RamRows = "N/A" } # ============================================================ # Physical storage info # ============================================================ $DiskDrives = Get-CimInstance Win32_DiskDrive -ErrorAction SilentlyContinue $DiskRows = "" foreach ($Disk in $DiskDrives) { $DiskModel = Get-SafeValue $Disk.Model $DiskSizeGB = if ($Disk.Size) { [math]::Round($Disk.Size / 1GB, 1) } else { "N/A" } $DiskType = Get-SafeValue $Disk.MediaType $DiskInterface = Get-SafeValue $Disk.InterfaceType $DiskSerial = Get-SafeValue $Disk.SerialNumber $DiskRows += "$(Convert-ToHtmlSafe $DiskModel)$DiskSizeGB GB$(Convert-ToHtmlSafe $DiskType)$(Convert-ToHtmlSafe $DiskInterface)$(Convert-ToHtmlSafe $DiskSerial)`n" } if ($DiskRows -eq "") { $DiskRows = "N/A" } # ============================================================ # Drive usage / storage percentage # ============================================================ $LogicalDisks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" -ErrorAction SilentlyContinue $DriveRows = "" foreach ($Drive in $LogicalDisks) { $DriveLetter = Get-SafeValue $Drive.DeviceID $VolumeName = Get-SafeValue $Drive.VolumeName $SizeGB = if ($Drive.Size) { [math]::Round($Drive.Size / 1GB, 1) } else { "N/A" } $FreeGB = if ($Drive.FreeSpace) { [math]::Round($Drive.FreeSpace / 1GB, 1) } else { "N/A" } $UsedPercent = if ($Drive.Size) { Get-PercentUsed -Size $Drive.Size -FreeSpace $Drive.FreeSpace } else { "N/A" } $DriveRows += "$(Convert-ToHtmlSafe $DriveLetter)$(Convert-ToHtmlSafe $VolumeName)$SizeGB GB$FreeGB GB$UsedPercent%`n" } if ($DriveRows -eq "") { $DriveRows = "N/A" } # ============================================================ # GPU info # ============================================================ $GPUs = Get-CimInstance Win32_VideoController -ErrorAction SilentlyContinue $GpuRows = "" foreach ($GPU in $GPUs) { $GpuName = Get-SafeValue $GPU.Name $GpuRamGB = if ($GPU.AdapterRAM -and $GPU.AdapterRAM -gt 0) { [math]::Round($GPU.AdapterRAM / 1GB, 1) } else { "N/A" } $GpuDriver = Get-SafeValue $GPU.DriverVersion $GpuRows += "$(Convert-ToHtmlSafe $GpuName)$GpuRamGB GB$(Convert-ToHtmlSafe $GpuDriver)`n" } if ($GpuRows -eq "") { $GpuRows = "No GPU information found" } # ============================================================ # Battery info # ============================================================ $BatteryStatic = Get-CimInstance -Namespace root\wmi -ClassName BatteryStaticData -ErrorAction SilentlyContinue | Select-Object -First 1 $WinBattery = Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue | Select-Object -First 1 $BatteryName = Get-SafeValue $WinBattery.Name $BatteryManufacturer = Get-SafeValue $BatteryStatic.ManufactureName $BatterySerial = Get-SafeValue $BatteryStatic.SerialNumber $BatteryChemistry = Get-SafeValue $WinBattery.Chemistry switch ($BatteryChemistry) { 2 { $BatteryChemistryText = "Unknown" } 3 { $BatteryChemistryText = "Lead Acid" } 4 { $BatteryChemistryText = "NiCd" } 5 { $BatteryChemistryText = "NiMH" } 6 { $BatteryChemistryText = "Li-ion" } 7 { $BatteryChemistryText = "Zinc Air" } 8 { $BatteryChemistryText = "Li-Polymer" } default { $BatteryChemistryText = Get-SafeValue $BatteryChemistry } } $DesignCapacity = Get-BatteryReportValue $BatteryReportContent "DESIGN CAPACITY" $FullChargeCapacity = Get-BatteryReportValue $BatteryReportContent "FULL CHARGE CAPACITY" $CycleCount = Get-BatteryReportValue $BatteryReportContent "CYCLE COUNT" $DesignNumber = Convert-CapacityToNumber $DesignCapacity $FullNumber = Convert-CapacityToNumber $FullChargeCapacity if ($DesignNumber -and $FullNumber -and $DesignNumber -gt 0) { $BatteryHealth = [math]::Round(($FullNumber / $DesignNumber) * 100, 1) $BatteryHealthText = "$BatteryHealth%" } else { $BatteryHealthText = "N/A" } # ============================================================ # HTML report # ============================================================ $Html = @" PC Audit Report

PC Audit Report

Generated on: $(Convert-ToHtmlSafe $ReportTime)

Basic Device Information

Computer Name$(Convert-ToHtmlSafe $ComputerName)
Manufacturer / Brand$(Convert-ToHtmlSafe $Manufacturer)
Model$(Convert-ToHtmlSafe $Model)
Serial Number$(Convert-ToHtmlSafe $SerialNumber)
Platform Type$(Convert-ToHtmlSafe $PlatformRole)
BIOS$(Convert-ToHtmlSafe $BiosInfo)
Windows$(Convert-ToHtmlSafe $WindowsInfo)

CPU

Processor$(Convert-ToHtmlSafe $CpuName)
Cores$(Convert-ToHtmlSafe $CpuCores)
Threads$(Convert-ToHtmlSafe $CpuThreads)

RAM

Total RAM$TotalRamGB GB
$RamRows
Slot Capacity Speed Manufacturer Part Number

Physical Storage

$DiskRows
Model Capacity Media Type Interface Serial Number

Drive Usage

$DriveRows
Drive Volume Name Total Capacity Free Space Used Percentage

GPU

$GpuRows
GPU Name GPU Memory Driver Version

Battery

Battery Name$(Convert-ToHtmlSafe $BatteryName)
Manufacturer$(Convert-ToHtmlSafe $BatteryManufacturer)
Battery Serial Number$(Convert-ToHtmlSafe $BatterySerial)
Chemistry$(Convert-ToHtmlSafe $BatteryChemistryText)
Design Capacity$(Convert-ToHtmlSafe $DesignCapacity)
Full Charge Capacity$(Convert-ToHtmlSafe $FullChargeCapacity)
Battery Health$(Convert-ToHtmlSafe $BatteryHealthText)
Cycle Count$(Convert-ToHtmlSafe $CycleCount)
Note: Some values may show as N/A depending on the device, Windows version, BIOS permission, or whether the device has a battery.
"@ # ============================================================ # Save report # ============================================================ $Html | Out-File -FilePath $OutputFile -Encoding UTF8 # ============================================================ # Console output # ============================================================ Write-Host "" Write-Host "===== PC AUDIT REPORT GENERATED =====" -ForegroundColor Green Write-Host "Saved to: $OutputFile" -ForegroundColor Yellow Write-Host "Opening report now..." -ForegroundColor Cyan Start-Process $OutputFile