PSPowerShell · Lesson 7 of 8
Mini Project: System Info Script
Build a script that gathers system information and outputs a clean, formatted report. Something you could actually run on a new machine.
PowerShell
#!/usr/bin/env pwsh
# sysinfo.ps1 — System information report
function Get-SizeString {
param([long]$Bytes)
switch ($Bytes) {
{ $_ -gt 1GB } { return "{0:F1} GB" -f ($_ / 1GB) }
{ $_ -gt 1MB } { return "{0:F1} MB" -f ($_ / 1MB) }
{ $_ -gt 1KB } { return "{0:F1} KB" -f ($_ / 1KB) }
default { return "$_ B" }
}
}
function Write-Section {
param([string]$Title)
Write-Host ""
Write-Host "═══ $Title " -NoNewline -ForegroundColor Cyan
Write-Host ("═" * (50 - $Title.Length - 5)) -ForegroundColor Cyan
}
Write-Host ""
Write-Host " SYSTEM INFORMATION REPORT" -ForegroundColor White
Write-Host " Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray
# ─── Operating System ───────────────────────────────────────────────────────
Write-Section "Operating System"
$os = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue
if ($os) {
Write-Host " OS: $($os.Caption)"
Write-Host " Version: $($os.Version)"
Write-Host " Uptime: $([math]::Round((Get-Date - $os.LastBootUpTime).TotalHours, 1)) hours"
} else {
# Cross-platform fallback
Write-Host " Platform: $([System.Runtime.InteropServices.RuntimeInformation]::OSDescription)"
Write-Host " PowerShell: $($PSVersionTable.PSVersion)"
}
# ─── CPU ────────────────────────────────────────────────────────────────────
Write-Section "CPU"
$cpu = Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue
if ($cpu) {
Write-Host " Name: $($cpu.Name.Trim())"
Write-Host " Cores: $($cpu.NumberOfCores) cores / $($cpu.NumberOfLogicalProcessors) threads"
Write-Host " Speed: $($cpu.MaxClockSpeed) MHz"
}
# CPU load (cross-platform)
$loadPct = (Get-Process | Measure-Object -Property CPU -Sum).Sum
Write-Host " CPU Sum: $([math]::Round($loadPct, 1))s (cumulative)"
# ─── Memory ─────────────────────────────────────────────────────────────────
Write-Section "Memory"
if ($os) {
$totalRAM = $os.TotalVisibleMemorySize * 1KB
$freeRAM = $os.FreePhysicalMemory * 1KB
$usedRAM = $totalRAM - $freeRAM
$pctUsed = [math]::Round(($usedRAM / $totalRAM) * 100)
Write-Host " Total: $(Get-SizeString $totalRAM)"
Write-Host " Used: $(Get-SizeString $usedRAM) ($pctUsed%)"
Write-Host " Free: $(Get-SizeString $freeRAM)"
}
# ─── Disk ───────────────────────────────────────────────────────────────────
Write-Section "Disks"
Get-PSDrive -PSProvider FileSystem | ForEach-Object {
if ($_.Used -or $_.Free) {
$total = $_.Used + $_.Free
$pct = if ($total -gt 0) { [math]::Round(($_.Used / $total) * 100) } else { 0 }
Write-Host (" {0,-6} {1,8} used / {2,8} total ({3}%)" -f `
"$($_.Name):", (Get-SizeString ($_.Used)), (Get-SizeString $total), $pct)
}
}
# ─── Top Processes ──────────────────────────────────────────────────────────
Write-Section "Top 5 Processes by Memory"
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 5 |
ForEach-Object {
Write-Host (" {0,-20} {1,8}" -f $_.Name, (Get-SizeString $_.WorkingSet))
}
# ─── Network ────────────────────────────────────────────────────────────────
Write-Section "Network"
$hostname = [System.Net.Dns]::GetHostName()
Write-Host " Hostname: $hostname"
[System.Net.Dns]::GetHostAddresses($hostname) |
Where-Object { $_.AddressFamily -eq "InterNetwork" } |
ForEach-Object { Write-Host " IP: $($_.IPAddressToString)" }
Write-Host ""PowerShell
# Run it:
.sysinfo.ps1
# On Linux/macOS (some sections will be skipped):
pwsh ./sysinfo.ps1