Solved PowerShell script to Generate a comprehensive Windows 11 system & hardware report


FreeBooter

Well-known member
Guru
VIP
Local time
12:35 AM
Posts
5,178
OS
Windows 11
Save as Generate-PCReport.ps1. Run in an elevated PowerShell session for best results:
Right-click PowerShell -> Run as Administrator, then: .\Generate-PCReport.ps1

If this policy is still too restrictive, we can remove all restrictions with this PowerShell command:

Set-ExecutionPolicy Unrestricted

For example, the command below will run PC_Report.ps1 without modifying the execution policy:


powershell -noexit -ExecutionPolicy Bypass -File "PC_Report.ps1"


Powershell:
<#
.SYNOPSIS
  Generate a comprehensive Windows 11 system & hardware report.

.NOTES
  Save as Generate-PCReport.ps1. Run in an elevated PowerShell session for best results:
  Right-click PowerShell -> Run as Administrator, then: .\Generate-PCReport.ps1
#>

#region Helpers
function Convert-BytesToGB {
    param([long]$Bytes)
    if ($null -eq $Bytes) { return $null }
    return [math]::Round($Bytes / 1GB, 2)
}

function Safe-Export {
    param($Object, $Path, $Format = 'json')
    switch ($Format.ToLower()) {
        'json' { $Object | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path -Encoding UTF8 }
        'csv'  { $Object | Export-Csv -Path $Path -NoTypeInformation -Encoding UTF8 }
        'txt'  { $Object | Out-File -FilePath $Path -Encoding UTF8 }
        default { $Object | Out-File -FilePath $Path -Encoding UTF8 }
    }
}
#endregion

#region Prepare output folder & metadata
$base = Join-Path -Path $env:USERPROFILE -ChildPath "Documents\PC_Report"
$timestamp = (Get-Date).ToString("yyyy-MM-dd_HH-mm-ss")
$outdir = Join-Path -Path $base -ChildPath "Report_$timestamp"
New-Item -Path $outdir -ItemType Directory -Force | Out-Null

$meta = [PSCustomObject]@{
    GeneratedAt = (Get-Date).ToString("u")
    Computer    = $env:COMPUTERNAME
    User        = $env:USERNAME
    WindowsUserProfile = $env:USERPROFILE
    Elevated    = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
}
Safe-Export -Object $meta -Path (Join-Path $outdir '00_metadata.json') -Format json
#endregion

#region Collect core system info
$computerInfo = Get-ComputerInfo -Property 'CsManufacturer','CsModel','CsName','OsName','OsVersion','OsArchitecture','WindowsProductName','WindowsVersion','WindowsBuildLabEx','OsLocale','OsLanguage','OsHotFixes' -ErrorAction SilentlyContinue

$osSummary = [PSCustomObject]@{
    OSName       = $computerInfo.OsName
    OSVersion    = $computerInfo.OsVersion
    OSBuild      = $computerInfo.WindowsBuildLabEx
    Architecture = $computerInfo.OsArchitecture
    Locale       = $computerInfo.OsLocale
    ProductName  = $computerInfo.WindowsProductName
}
Safe-Export -Object $computerInfo -Path (Join-Path $outdir '01_computerinfo.json') -Format json
#endregion

#region Hardware: CPU, Memory, Disks, Video, NICs, BIOS, Baseboard
$cpu = Get-CimInstance -ClassName Win32_Processor | Select-Object DeviceID, Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed, Architecture
$mem = Get-CimInstance -ClassName Win32_PhysicalMemory | Select-Object BankLabel, Capacity, Speed, Manufacturer, PartNumber
$memSummary = [PSCustomObject]@{
    TotalPhysicalGB = (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory | ForEach-Object { Convert-BytesToGB $_ }
    ModuleCount = ($mem | Measure-Object).Count
}
$disks = Get-CimInstance -ClassName Win32_DiskDrive | Select-Object Index, Model, InterfaceType, MediaType, @{Name='SizeGB';Expression={ Convert-BytesToGB $_.Size }}, PartitionCount
$volumes = Get-CimInstance -Query "SELECT DeviceID, DriveType, FileSystem, FreeSpace, Size, VolumeName FROM Win32_LogicalDisk WHERE DeviceID IS NOT NULL" |
    Select-Object DeviceID, DriveType, FileSystem, @{Name='FreeGB';Expression={ Convert-BytesToGB $_.FreeSpace }}, @{Name='SizeGB';Expression={ Convert-BytesToGB $_.Size }}, VolumeName
$video = Get-CimInstance -ClassName Win32_VideoController | Select-Object Name, DriverVersion, AdapterRAM, VideoProcessor
$nic = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetEnabled = true" | Select-Object Name, MACAddress, Speed, Manufacturer
$bios = Get-CimInstance -ClassName Win32_BIOS | Select-Object Manufacturer, Name, SerialNumber, ReleaseDate, SMBIOSBIOSVersion
$baseboard = Get-CimInstance -ClassName Win32_BaseBoard | Select-Object Manufacturer, Product, SerialNumber

Safe-Export -Object $cpu -Path (Join-Path $outdir '10_cpu.json') -Format json
Safe-Export -Object $mem -Path (Join-Path $outdir '11_memory_modules.json') -Format json
Safe-Export -Object $memSummary -Path (Join-Path $outdir '12_memory_summary.json') -Format json
Safe-Export -Object $disks -Path (Join-Path $outdir '13_disks.json') -Format json
Safe-Export -Object $volumes -Path (Join-Path $outdir '14_volumes.json') -Format json
Safe-Export -Object $video -Path (Join-Path $outdir '15_video.json') -Format json
Safe-Export -Object $nic -Path (Join-Path $outdir '16_network_adapters.json') -Format json
Safe-Export -Object $bios -Path (Join-Path $outdir '17_bios.json') -Format json
Safe-Export -Object $baseboard -Path (Join-Path $outdir '18_baseboard.json') -Format json
#endregion

#region Drivers, Devices, Installed Programs, Hotfixes, Power
$drivers = driverquery /v /fo csv 2>$null | ConvertFrom-Csv
$pnp = Get-PnpDevice -Status OK -ErrorAction SilentlyContinue | Select-Object Class, FriendlyName, InstanceId, Manufacturer
$installedApps = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue |
    Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
$hotfixes = Get-HotFix | Select-Object HotFixID, Description, InstalledOn
$power = @{ PowerScheme = (powercfg /getactivescheme 2>$null | Out-String).Trim() ; BatteryReport = $null }
try {
    $batteryHtml = Join-Path $outdir '30_battery_report.html'
    powercfg /batteryreport /output $batteryHtml 2>$null
    if (Test-Path $batteryHtml) { $power.BatteryReport = '30_battery_report.html' }
} catch { }

Safe-Export -Object $drivers -Path (Join-Path $outdir '20_drivers.csv') -Format csv
Safe-Export -Object $pnp -Path (Join-Path $outdir '21_pnp_devices.json') -Format json
Safe-Export -Object $installedApps -Path (Join-Path $outdir '22_installed_programs.json') -Format json
Safe-Export -Object $hotfixes -Path (Join-Path $outdir '23_hotfixes.json') -Format json
Safe-Export -Object $power -Path (Join-Path $outdir '24_power_summary.json') -Format json
#endregion

#region Network, IP, Routes
$ipconfig = ipconfig /all | Out-String
$route = route print | Out-String
Safe-Export -Object $ipconfig -Path (Join-Path $outdir '50_ipconfig.txt') -Format txt
Safe-Export -Object $route -Path (Join-Path $outdir '51_route_print.txt') -Format txt
#endregion

#region Generate human-readable summary and HTML
$summary = @()
$summary += "Report Generated: $($meta.GeneratedAt)"
$summary += "Computer: $($meta.Computer)    User: $($meta.User)    Elevated: $($meta.Elevated)"
$summary += ""
$summary += "Manufacturer: $($computerInfo.CsManufacturer)    Model: $($computerInfo.CsModel)"
$summary += "CPU: $($cpu.Name)    Cores: $($cpu.NumberOfCores)    Logical: $($cpu.NumberOfLogicalProcessors)    MaxMHz: $($cpu.MaxClockSpeed)"
$summary += ("RAM Total (GB): " + ($memSummary.TotalPhysicalGB))
$summary += "Installed physical RAM modules: " + ($mem | Measure-Object | Select-Object -ExpandProperty Count)
$summary += ""
$summary += "Disks:"
foreach ($d in $disks) {
    $summary += ("  Index {0}: {1} {2}GB {3}" -f $d.Index, $d.Model, $d.SizeGB, $d.InterfaceType)
}
$summary += ""
$summary += "Video adapters:"
foreach ($v in $video) {
    $summary += ("  {0}  RAM: {1}" -f $v.Name, (if ($v.AdapterRAM) { Convert-BytesToGB $v.AdapterRAM } else { 'N/A' }))
}
$summary += ""
$summary += "Network (enabled):"
foreach ($n in $nic) {
    $summary += ("  {0}  MAC: {1}  Speed: {2}" -f $n.Name, $n.MACAddress, $n.Speed)
}

$summaryPath = Join-Path $outdir '99_summary.txt'
$summary | Out-File -FilePath $summaryPath -Encoding UTF8

# Simple HTML
$html = @"
<!doctype html>
<html><head><meta charset='utf-8'><title>PC Report - $timestamp</title>
<style>body{font-family:Segoe UI,Arial;background:#fff;color:#111;padding:18px}h1{font-size:1.25rem}pre{background:#f7f7f7;border:1px solid #ddd;padding:12px;white-space:pre-wrap}</style>
</head><body>
<h1>PC Report</h1>
<p><strong>Generated</strong>: $($meta.GeneratedAt)</p>
<p><strong>Computer</strong>: $($meta.Computer) &nbsp; <strong>User</strong>: $($meta.User)</p>
<h2>Quick Summary</h2>
<pre>$(($summary -join "`n"))</pre>
<h2>Files</h2>
<ul>
$(Get-ChildItem -Path $outdir | ForEach-Object { "  <li>$($_.Name)</li>" })
</ul>
</body></html>
"@

$htmlPath = Join-Path $outdir '98_report.html'
$html | Out-File -FilePath $htmlPath -Encoding UTF8
#endregion

#region Final output and open folder
Write-Host "Report generated in: $outdir"
Write-Host "Summary: $summaryPath"
if ($meta.Elevated -eq $false) {
    Write-Host "Note: For the most complete information, re-run this script from an elevated PowerShell session."
}
Start-Process explorer.exe -ArgumentList $outdir
#endregion
 

Attachments

Last edited:

My Computer

System One

  • OS
    Windows 11
    Computer type
    PC/Desktop
    Manufacturer/Model
    HP Pavilion
    CPU
    AMD Ryzen 7 5700G
    Motherboard
    Erica6
    Memory
    Micron Technology DDR4-3200 16GB
    Graphics Card(s)
    NVIDIA GeForce RTX 3060
    Sound Card
    Realtek ALC671
    Monitor(s) Displays
    Samsung SyncMaster U28E590
    Screen Resolution
    3840 x 2160
    Hard Drives
    SAMSUNG MZVLQ1T0HALB-000H1
Back
Top Bottom