-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathWatch-ComputerStatus.ps1
More file actions
113 lines (92 loc) · 4.69 KB
/
Copy pathWatch-ComputerStatus.ps1
File metadata and controls
113 lines (92 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
function Watch-ComputerStatus {
<#
.SYNOPSIS
Live auto-refreshing console dashboard showing status of a set of computers.
.DESCRIPTION
Polls each computer via Invoke-Command every -RefreshSeconds seconds, collecting
free disk %, uptime in days, and OS ReleaseID. Results are displayed as a
colour-coded console table — green for OK, red for thresholds exceeded or offline.
Runs indefinitely until stopped with Ctrl+C.
Requires WinRM/PSRemoting on the target computers. Machines that fail Invoke-Command
are shown as OFFLINE in red.
.PARAMETER ComputerName
One or more hostnames or IPs to monitor.
.PARAMETER LabelMap
Optional hashtable mapping hostnames to friendly display names.
e.g. @{ "PC01" = "Room A"; "PC02" = "Boardroom" }
.PARAMETER RefreshSeconds
How often to refresh the dashboard. Default: 300 (5 minutes).
.PARAMETER MinFreeDiskPct
Free disk % below this value is shown in red. Default: 10.
.PARAMETER MaxUptimeDays
Uptime above this many days is shown in red. Default: 5.
.EXAMPLE
Watch-ComputerStatus -ComputerName "PC01","PC02","PC03"
Monitor three machines with default thresholds.
.EXAMPLE
Watch-ComputerStatus -ComputerName "PC01","PC02" -LabelMap @{PC01="Boardroom"; PC02="Huddle Room"} -RefreshSeconds 60
Monitor with friendly names, refreshing every minute.
.EXAMPLE
Get-ADComputer -Filter * -SearchBase "OU=Labs,DC=contoso,DC=com" |
Select-Object -ExpandProperty Name |
Watch-ComputerStatus -MaxUptimeDays 7
Pull computer list from AD and monitor with a 7-day uptime alert.
.NOTES
Stop with Ctrl+C.
OS column shows the Windows ReleaseID registry value (e.g. 22H2, 23H2).
Requires WinRM enabled on targets.
#>
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string[]]$ComputerName,
[hashtable]$LabelMap = @{},
[int]$RefreshSeconds = 300,
[int]$MinFreeDiskPct = 10,
[int]$MaxUptimeDays = 5
)
begin { $allComputers = [System.Collections.Generic.List[string]]::new() }
process { $allComputers.AddRange($ComputerName) }
end {
$colorCol = {
param($val, $bad)
$e = [char]27
$color = if ($bad) { "91" } else { "92" }
"$e[${color}m$val${e}[0m"
}
$columns = @(
@{ Label = "Label"; Expression = { & $colorCol ($_.Label.PadRight(16)) ($_.Online -eq "OFFLINE") } }
@{ Label = "Hostname"; Expression = { & $colorCol ($_.Hostname.PadRight(16)) ($_.Online -eq "OFFLINE") } }
@{ Label = "Online"; Expression = { & $colorCol ($_.Online.PadRight(10)) ($_.Online -eq "OFFLINE") } }
@{ Label = "FreeDisk"; Expression = { & $colorCol ("$($_.FreeDisk)%".PadRight(10)) ($null -ne $_.FreeDisk -and $_.FreeDisk -lt $MinFreeDiskPct) } }
@{ Label = "Uptime"; Expression = { & $colorCol ("$($_.Uptime) days".PadRight(12)) ($null -ne $_.Uptime -and $_.Uptime -gt $MaxUptimeDays) } }
@{ Label = "OS"; Expression = { $_.OS } }
)
Write-Host "Starting dashboard — press Ctrl+C to stop."
while ($true) {
$results = Invoke-Command -ComputerName $allComputers -ErrorAction SilentlyContinue -ErrorVariable NoReach -ScriptBlock {
[pscustomobject]@{
Hostname = $env:COMPUTERNAME
Online = "OK"
FreeDisk = [math]::Round(
(Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'" |
ForEach-Object { $_.FreeSpace / $_.Size * 100 }), 1)
Uptime = ((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime).Days
OS = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ReleaseID -ErrorAction SilentlyContinue).ReleaseID
Label = $null
}
}
$offline = $NoReach.CategoryInfo.TargetName | ForEach-Object {
[pscustomobject]@{ Hostname = $_; Online = "OFFLINE"; FreeDisk = $null; Uptime = $null; OS = $null; Label = $null }
}
$results = @($results) + @($offline)
foreach ($r in $results) {
$r.Label = if ($LabelMap.ContainsKey($r.Hostname)) { $LabelMap[$r.Hostname] } else { $r.Hostname }
}
Clear-Host
Write-Host "Updated: $(Get-Date) [refresh every ${RefreshSeconds}s — Ctrl+C to stop]"
$results | Sort-Object Label | Format-Table -Property $columns -HideTableHeaders |
Out-String | ForEach-Object { $_.Trim() } | Write-Host
Start-Sleep -Seconds $RefreshSeconds
}
}
}