195 lines
6.2 KiB
PowerShell
195 lines
6.2 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Windows Device Health Audit with Auto-Elevation
|
|
.DESCRIPTION
|
|
Performs comprehensive system checks with automatic admin elevation when needed.
|
|
Logs to: C:\Logs\DeviceAudit\AUDIT_[HOSTNAME]_[DATE].log
|
|
.NOTES
|
|
Version: 1.2
|
|
Author: Your Name
|
|
.EXAMPLE
|
|
# Basic check (non-admin):
|
|
.\WindowsHealthAudit.ps1
|
|
.EXAMPLE
|
|
# Full check (auto-elevates to admin if needed):
|
|
.\WindowsHealthAudit.ps1 -Full
|
|
#>
|
|
|
|
param(
|
|
[switch]$Full = $false
|
|
)
|
|
|
|
#region Initial Setup
|
|
# ------------------
|
|
$logDir = "C:\Logs\DeviceAudit"
|
|
$logFile = "$logDir\AUDIT_$($env:COMPUTERNAME)_$(Get-Date -Format 'ddMMyyyy').log"
|
|
|
|
# Create log directory if missing
|
|
if (-not (Test-Path $logDir)) {
|
|
New-Item -Path $logDir -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
# Clear previous log
|
|
if (Test-Path $logFile) {
|
|
Clear-Content $logFile
|
|
}
|
|
#endregion
|
|
|
|
#region Logging Function
|
|
# ---------------------
|
|
function Write-Log {
|
|
param (
|
|
[string]$Message,
|
|
[string]$Level = "INFO"
|
|
)
|
|
$timestamp = Get-Date -Format "dd-MM-yyyy HH:mm:ss"
|
|
$logEntry = "$timestamp $Level`: $Message"
|
|
Write-Output $logEntry
|
|
$logEntry | Out-File -FilePath $logFile -Append -Encoding UTF8
|
|
}
|
|
#endregion
|
|
|
|
#region Self-Elevation
|
|
# -------------------
|
|
$isAdmin = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')
|
|
|
|
if ($Full -and (-not $isAdmin)) {
|
|
Write-Host "Re-launching as administrator..." -ForegroundColor Yellow
|
|
try {
|
|
$scriptPath = $MyInvocation.MyCommand.Path
|
|
Start-Process pwsh -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`" -Full" -Verb RunAs -WindowStyle Hidden
|
|
exit
|
|
} catch {
|
|
Write-Host "Failed to elevate! Running in basic mode." -ForegroundColor Red
|
|
$Full = $false
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Main Audit
|
|
# ---------------
|
|
Write-Log "=== WINDOWS DEVICE HEALTH AUDIT ==="
|
|
Write-Log "Host: $($env:COMPUTERNAME)"
|
|
Write-Log "User: $($env:USERNAME)"
|
|
Write-Log "Mode: $(if ($Full) {'FULL (Admin)'} else {'BASIC (Non-Admin)'})"
|
|
Write-Log "Date: $(Get-Date -Format 'dd-MM-yyyy HH:mm:ss')"
|
|
Write-Log ""
|
|
|
|
# 1. System Information
|
|
Write-Log "=== SYSTEM INFORMATION ==="
|
|
$os = Get-CimInstance Win32_OperatingSystem
|
|
$computer = Get-CimInstance Win32_ComputerSystem
|
|
$uptime = (Get-Date) - $os.LastBootUpTime
|
|
|
|
Write-Log "OS: $($os.Caption) (Build: $($os.BuildNumber))"
|
|
Write-Log "Uptime: $($uptime.Days)d $($uptime.Hours)h $($uptime.Minutes)m"
|
|
Write-Log "Manufacturer: $($computer.Manufacturer)"
|
|
Write-Log "Model: $($computer.Model)"
|
|
Write-Log "RAM: $([math]::Round($computer.TotalPhysicalMemory / 1GB, 2)) GB"
|
|
Write-Log ""
|
|
|
|
# 2. Performance Metrics
|
|
Write-Log "=== PERFORMANCE ==="
|
|
$cpuLoad = (Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Average).Average
|
|
$memory = Get-CimInstance Win32_OperatingSystem
|
|
$usedMem = [math]::Round(($memory.TotalVisibleMemorySize - $memory.FreePhysicalMemory) / 1MB, 2)
|
|
$totalMem = [math]::Round($memory.TotalVisibleMemorySize / 1MB, 2)
|
|
|
|
Write-Log "CPU Load: $cpuLoad%"
|
|
Write-Log "Memory Usage: $usedMem/$totalMem GB ($([math]::Round(($usedMem/$totalMem)*100))% used)"
|
|
Write-Log ""
|
|
|
|
# 3. Disk Information
|
|
Write-Log "=== DISK STORAGE ==="
|
|
Get-CimInstance Win32_LogicalDisk -Filter "DriveType = 3" | ForEach-Object {
|
|
$freeGB = [math]::Round($_.FreeSpace / 1GB, 2)
|
|
$totalGB = [math]::Round($_.Size / 1GB, 2)
|
|
$pctUsed = [math]::Round(($totalGB - $freeGB) / $totalGB * 100, 2)
|
|
|
|
if ($pctUsed -gt 90) {
|
|
Write-Log "WARNING: $($_.DeviceID) low space: $freeGB GB free ($pctUsed% used)" -Level "WARNING"
|
|
} else {
|
|
Write-Log "$($_.DeviceID): $freeGB GB free of $totalGB GB ($pctUsed% used)"
|
|
}
|
|
}
|
|
Write-Log ""
|
|
|
|
# 4. Admin-Only Checks
|
|
if ($Full) {
|
|
Write-Log "=== ADMIN CHECKS ==="
|
|
|
|
# Disk Health (SMART)
|
|
try {
|
|
$disks = Get-PhysicalDisk | Select-Object FriendlyName, HealthStatus, OperationalStatus
|
|
$disks | ForEach-Object {
|
|
if ($_.HealthStatus -ne "Healthy") {
|
|
Write-Log "Disk health alert: $($_.FriendlyName) is $($_.HealthStatus)" -Level "ERROR"
|
|
} else {
|
|
Write-Log "Disk health: $($_.FriendlyName) is Healthy"
|
|
}
|
|
}
|
|
} catch {
|
|
Write-Log "WARNING: Could not retrieve disk health data" -Level "WARNING"
|
|
}
|
|
Write-Log ""
|
|
|
|
# BitLocker Status
|
|
if (Get-Command -Name Get-BitLockerVolume -ErrorAction SilentlyContinue) {
|
|
$bitlocker = Get-BitLockerVolume | Where-Object { $_.VolumeType -eq "OperatingSystem" }
|
|
if ($bitlocker.ProtectionStatus -eq "On") {
|
|
Write-Log "BitLocker: Enabled ($($bitlocker.EncryptionPercentage)% encrypted)"
|
|
} else {
|
|
Write-Log "WARNING: BitLocker is not enabled on OS drive" -Level "WARNING"
|
|
}
|
|
}
|
|
Write-Log ""
|
|
}
|
|
#endregion
|
|
|
|
#region Common Checks
|
|
# ------------------
|
|
# 5. Windows Updates
|
|
Write-Log "=== UPDATES ==="
|
|
$lastUpdate = Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 1
|
|
Write-Log "Last Update: $($lastUpdate.HotFixID) on $($lastUpdate.InstalledOn)"
|
|
Write-Log ""
|
|
|
|
# 6. Security Status
|
|
Write-Log "=== SECURITY ==="
|
|
$defender = Get-MpComputerStatus
|
|
if ($defender.AntivirusEnabled) {
|
|
Write-Log "Windows Defender: Active"
|
|
} else {
|
|
Write-Log "ERROR: Windows Defender is disabled" -Level "ERROR"
|
|
}
|
|
Write-Log ""
|
|
|
|
# 7. Event Log Errors
|
|
Write-Log "=== CRITICAL EVENTS (24h) ==="
|
|
$criticalEvents = Get-WinEvent -FilterHashtable @{
|
|
LogName = 'System','Application'
|
|
Level = 1,2
|
|
StartTime = (Get-Date).AddDays(-1)
|
|
} -MaxEvents 5 -ErrorAction SilentlyContinue
|
|
|
|
if ($criticalEvents) {
|
|
$criticalEvents | ForEach-Object {
|
|
Write-Log "Event $($_.Id) [$($_.ProviderName)]: $($_.Message)" -Level "ERROR"
|
|
}
|
|
} else {
|
|
Write-Log "No critical events found"
|
|
}
|
|
#endregion
|
|
|
|
#region Completion
|
|
# ---------------
|
|
Write-Log ""
|
|
Write-Log "=== AUDIT COMPLETE ==="
|
|
Write-Log "Mode: $(if ($Full) {'FULL (Admin)'} else {'BASIC (Non-Admin)'})"
|
|
Write-Log "Log saved to: $logFile"
|
|
|
|
# Open log file if running interactively
|
|
if ($Host.Name -match "ConsoleHost") {
|
|
Invoke-Item $logFile
|
|
}
|
|
#endregion |