# SystemInfo.
ps1
# Custom PowerShell script to collect system information for security health checks
# Author: [Your Name]
# Date: April 30, 2025
# Set output directory and timestamp
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$OutputDir = "$env:USERPROFILE\Desktop\SystemInfo_$Timestamp"
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
$TextReport = "$OutputDir\SystemInfo_$env:COMPUTERNAME.txt"
$HtmlReport = "$OutputDir\SystemInfo_$env:COMPUTERNAME.html"
# Initialize HTML report content
$HtmlContent = "<html><head><style>body{font-family:Arial,sans-serif;}table{border-
collapse:collapse;width:100%;}th,td{border:1px solid #ddd;padding:8px;text-
align:left;}th{background-color:#f2f2f2;}tr:nth-child(even){background-
color:#f9f9f9;}</style></head><body><h2>System Information Report</h2><p>Generated
on: $(Get-Date)</p><p>Hostname: $env:COMPUTERNAME</p>"
# Initialize text report
"System Information Report" | Out-File -FilePath $TextReport
"Generated on: $(Get-Date)" | Out-File -FilePath $TextReport -Append
"Hostname: $env:COMPUTERNAME" | Out-File -FilePath $TextReport -Append
"" | Out-File -FilePath $TextReport -Append
# Function to add to reports
function Add-ReportSection {
param (
$Title,
$Data,
$CsvFileName
)
try {
# Text report
"=== $Title ===" | Out-File -FilePath $TextReport -Append
$Data | Format-Table -AutoSize | Out-File -FilePath $TextReport -Append
"" | Out-File -FilePath $TextReport -Append
# HTML report
$global:HtmlContent += "<h3>$Title</h3>"
if ($Data -is [array]) {
# Handle array of objects (e.g., multiple antivirus products)
foreach ($Item in $Data) {
$global:HtmlContent +=
"<table><tr><th>Property</th><th>Value</th></tr>"
foreach ($Property in $Item.PSObject.Properties) {
$global:HtmlContent += "<tr><td>$($Property.Name)</td><td>$
($Property.Value)</td></tr>"
}
$global:HtmlContent += "</table>"
}
}
else {
# Handle single object
$global:HtmlContent +=
"<table><tr><th>Property</th><th>Value</th></tr>"
foreach ($Property in $Data.PSObject.Properties) {
$global:HtmlContent += "<tr><td>$($Property.Name)</td><td>$
($Property.Value)</td></tr>"
}
$global:HtmlContent += "</table>"
}
# CSV report (separate file per section)
if ($CsvFileName) {
$CsvPath = "$OutputDir\$CsvFileName"
$Data | Export-Csv -Path $CsvPath -NoTypeInformation -Force
}
}
catch {
Write-Warning "Error in $Title section: $_"
"Error in ${Title}: $_" | Out-File -FilePath $TextReport -Append
}
}
# 1. Windows Version
try {
$OS = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop
$OSInfo = [PSCustomObject]@{
"Windows Version" = $OS.Caption
"Build Number" = $OS.BuildNumber
"Service Pack" = $OS.ServicePackMajorVersion
"Install Date" = $OS.InstallDate
"Last Boot Time" = $OS.LastBootUpTime
}
Add-ReportSection -Title "Operating System" -Data $OSInfo -CsvFileName
"OS_$env:COMPUTERNAME.csv"
}
catch {
Write-Warning "Failed to retrieve OS info: $_"
}
# 2. CPU Information
try {
$CPU = Get-CimInstance -ClassName Win32_Processor -ErrorAction Stop
$CPUInfo = [PSCustomObject]@{
"Processor" = $CPU.Name
"Cores" = $CPU.NumberOfCores
"Threads" = $CPU.ThreadCount
"Current Clock Speed" = "$($CPU.CurrentClockSpeed) MHz"
"Max Clock Speed" = "$($CPU.MaxClockSpeed) MHz"
}
Add-ReportSection -Title "CPU" -Data $CPUInfo -CsvFileName
"CPU_$env:COMPUTERNAME.csv"
}
catch {
Write-Warning "Failed to retrieve CPU info: $_"
}
# 3. RAM Information
try {
$OS = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop
$RAM = Get-CimInstance -ClassName Win32_PhysicalMemory -ErrorAction Stop
$TotalRAM = [math]::Round(($OS.TotalVisibleMemorySize / 1MB), 2)
$RAMInfo = [PSCustomObject]@{
"Total RAM" = "$TotalRAM GB"
"Used RAM" = "$([math]::Round(($OS.TotalVisibleMemorySize -
$OS.FreePhysicalMemory) / 1MB, 2)) GB"
"Memory Type" = $RAM[0].SMBIOSMemoryType
"Speed" = if ($RAM[0].Speed) { "$($RAM[0].Speed) MHz" } else { "Unknown" }
}
Add-ReportSection -Title "RAM" -Data $RAMInfo -CsvFileName
"RAM_$env:COMPUTERNAME.csv"
}
catch {
Write-Warning "Failed to retrieve RAM info: $_"
}
# 4. Disk Information
try {
$Disks = Get-CimInstance -ClassName Win32_LogicalDisk -ErrorAction Stop |
Where-Object {$_.DriveType -eq 3}
foreach ($Disk in $Disks) {
$DiskInfo = [PSCustomObject]@{
"Drive Letter" = $Disk.DeviceID
"Volume Name" = $Disk.VolumeName
"Total Space" = "$([math]::Round($Disk.Size / 1GB, 2)) GB"
"Free Space" = "$([math]::Round($Disk.FreeSpace / 1GB, 2)) GB"
"Used Space" = "$([math]::Round(($Disk.Size - $Disk.FreeSpace) / 1GB,
2)) GB"
}
$SafeDriveID = $Disk.DeviceID -replace ":", ""
Add-ReportSection -Title "Disk $($Disk.DeviceID)" -Data $DiskInfo -
CsvFileName "Disk_${SafeDriveID}_$env:COMPUTERNAME.csv"
}
}
catch {
Write-Warning "Failed to retrieve disk info: $_"
}
# 5. HDD/SSD Health (S.M.A.R.T. Status)
try {
$PhysicalDisks = Get-CimInstance -ClassName Win32_DiskDrive -ErrorAction Stop
foreach ($PhysicalDisk in $PhysicalDisks) {
$DiskHealth = [PSCustomObject]@{
"Model" = $PhysicalDisk.Model
"Serial Number" = $PhysicalDisk.SerialNumber
"Interface Type" = $PhysicalDisk.InterfaceType
"Status" = $PhysicalDisk.Status
}
Add-ReportSection -Title "Physical Disk $($PhysicalDisk.Index)" -Data
$DiskHealth -CsvFileName "PhysicalDisk_$
($PhysicalDisk.Index)_$env:COMPUTERNAME.csv"
}
}
catch {
Write-Warning "Failed to retrieve physical disk info: $_"
}
# 6. Antivirus Status
try {
$AntivirusProducts = Get-CimInstance -Namespace root/SecurityCenter2 -ClassName
AntiVirusProduct -ErrorAction Stop
$AntivirusInfoArray = @()
foreach ($Antivirus in $AntivirusProducts) {
$IsDefender = $Antivirus.displayName -like "*Windows Defender*"
$AntivirusInfo = [PSCustomObject]@{
"Antivirus Name" = $Antivirus.displayName
"Product State" = if ($Antivirus.productState -band 0x1000) { "Enabled"
} else { "Disabled" }
"Definition Status" = "Unknown"
"Note" = ""
}
if ($IsDefender) {
try {
$DefenderStatus = Get-MpComputerStatus -ErrorAction Stop
$AntivirusInfo."Definition Status" = if
($DefenderStatus.AntivirusSignatureLastUpdated -gt (Get-Date).AddDays(-2)) { "Up to
date" } else { "Out of date" }
$AntivirusInfo.Note = "Checked via Defender module. Last updated: $
($DefenderStatus.AntivirusSignatureLastUpdated)"
}
catch {
$AntivirusInfo."Definition Status" = "Unknown (Defender check
failed)"
$AntivirusInfo.Note = "Failed to check Defender status: $_"
}
}
else {
$AntivirusInfo."Definition Status" = if ($Antivirus.productState -band
0x10000) { "Up to date" } else { "Out of date" }
$AntivirusInfo.Note = "Checked via WMI. May be inaccurate for third-
party products."
}
$AntivirusInfoArray += $AntivirusInfo
}
Add-ReportSection -Title "Antivirus Products" -Data $AntivirusInfoArray -
CsvFileName "Antivirus_$env:COMPUTERNAME.csv"
}
catch {
Write-Warning "Failed to retrieve antivirus info: $_"
$ErrorInfo = [PSCustomObject]@{
"Antivirus Name" = "Unknown"
"Product State" = "Unknown"
"Definition Status" = "Unknown"
"Note" = "Failed to retrieve antivirus info: $_"
}
Add-ReportSection -Title "Antivirus Products" -Data $ErrorInfo -CsvFileName
"Antivirus_$env:COMPUTERNAME.csv"
}
# 7. Installed Hotfixes (Patches)
try {
$Hotfixes = Get-CimInstance -ClassName Win32_QuickFixEngineering -ErrorAction
Stop | Sort-Object InstalledOn -Descending | Select-Object -First 5
foreach ($Hotfix in $Hotfixes) {
$HotfixInfo = [PSCustomObject]@{
"Hotfix ID" = $Hotfix.HotFixID
"Description" = $Hotfix.Description
"Installed On" = $Hotfix.InstalledOn
}
$SafeHotfixID = $Hotfix.HotFixID -replace "[^a-zA-Z0-9]", "_"
Add-ReportSection -Title "Hotfix $($Hotfix.HotFixID)" -Data $HotfixInfo -
CsvFileName "Hotfix_${SafeHotfixID}_$env:COMPUTERNAME.csv"
}
}
catch {
Write-Warning "Failed to retrieve hotfix info: $_"
}
# Finalize HTML report
$HtmlContent += "</body></html>"
$HtmlContent | Out-File -FilePath $HtmlReport
# Output completion message
Write-Host "System information collected. Reports saved to:"
Write-Host "- Text: $TextReport"
Write-Host "- HTML: $HtmlReport"
Write-Host "- CSVs: $OutputDir\*.csv"