-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGet-DomainWideProcessCpuUsage.ps1
More file actions
146 lines (118 loc) · 5.26 KB
/
Copy pathGet-DomainWideProcessCpuUsage.ps1
File metadata and controls
146 lines (118 loc) · 5.26 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<#
.SYNOPSIS
Sammelt von allen Domaenenrechnern die Prozesse mit der hoechsten
CPU-Last.
.DESCRIPTION
Fragt per Invoke-Command parallel die Top-X-Prozesse je Rechner ab und
fuehrt sie in einer Tabelle zusammen. Sortiert man nach Prozessname oder
CPU-Zeit, faellt auf, wo ein Prozess flottenweit ungewoehnlich viel
verbraucht - etwa ein hakender Agent.
.NOTES
Erklaertermassen ein Proof of Concept, kein fertiges Werkzeug.
Erfordert PowerShell 7 und Administrationsrechte auf den Zielrechnern.
Die Messung ist eine Momentaufnahme: CPU-Zeit ist kumuliert seit
Prozessstart, ein lange laufender Prozess sieht dadurch teurer aus als
ein kurz aufflammender.
#>
# This script queries remotely the top X process and collect these.
# You get a view and maybe see processes which have unnormal high cpu usage on the computers
# just sort by the process name and / or the cpu usage
# this was just a Proof-Of-Concept.
# Powershell 7 is mandatory
# Import the Active Directory module if not already imported
Import-Module ActiveDirectory
# Define the credentials to use for authentication
if (-not $credential) {
$credential = Get-Credential
}
# Hole die hungrigsten Prozesse von den Servern / Rechnern
# Define the number of top CPU-consuming processes to display
$topN = 10
# Clients
$mycomputers = Get-ADComputer -Filter {OperatingSystem -notlike '*Server*' -and operatingSystem -like '*Windows*' -and Enabled -eq 'True'} -Property OperatingSystem, IPv4Address,Name | Select-Object -ExpandProperty Name
# Server
$mycomputers = Get-ADComputer -Filter {OperatingSystem -like '*Server*'} -Property OperatingSystem, IPv4Address
# $mycomputers = $mycomputers | Where {($_.Name -like "SVRCXVAD0*") -or ($_.Name -like "SVR*XEN*")}
# # Get all AD computers with a server operating system
# $servers = Get-ADComputer -Filter {OperatingSystem -like '*Server*'} -Property OperatingSystem, IPv4Address
# Computernames which are currently Online or Offline.
$mycomputersOnline = @()
# Array to hold online servers as AD Computer Object, with which is being worked
$onlineServers = @()
# $mycomputersOnline = $mycomputers | ForEach-Object -Parallel {
# Test-Connection -ComputerName $_ -Count 1 -Quiet -TimeoutSeconds 1 -ErrorAction SilentlyContinue
# }
# # Get all AD computers with a server operating system
# $servers = Get-ADComputer -Filter {OperatingSystem -like '*Server*'} -Property OperatingSystem, IPv4Address
# # Loop through each server and check if it's online
# foreach ($server in $servers) {
# #Write-Host("Try: $server.Name") -ForegroundColor Yellow
# if (Test-Connection -ComputerName $server.Name -Count 1 -Quiet -TimeoutSeconds 1) {
# $onlineServers += $server
# Write-Host("Try: $($server.Name)") -ForegroundColor Green
# } else {
# Write-Host("Try: $($server.Name)") -ForegroundColor Red
# }
# }
# # Output the list of online servers
# $onlineServers | Select-Object Name, OperatingSystem, IPv4Address
# # Define the list of remote servers
# $remoteServers = $onlineServers.DNSHostName
# $mycomputersOnline = $mycomputers | ForEach-Object -Parallel {
# [pscustomobject]@{Name=$_;Online=Test-Connection -ComputerName $_ -Count 1 -Quiet -TimeoutSeconds 1 -ErrorAction SilentlyContinue}
# } #-ThrottleLimit 10
# # Get DNSHostNames from the AD
# $onlineServers = (($mycomputersOnline | Where-Object Online -eq $True).Name | Get-ADComputer)
$mycomputersOnline = $mycomputers | ForEach-Object -Parallel {
[pscustomobject]@{Name=$_;Online=Test-Connection -ComputerName $_.DNSHostName -Count 1 -Quiet -TimeoutSeconds 1}
} #-ThrottleLimit 10
# Get DNSHostNames from the AD
$onlineServers = (($mycomputersOnline | Where-Object Online -eq $True).Name).DistinguishedName | Get-ADComputer
if ($PSVersionTable.PSVersion.Major -ne 7) {
Write-Error("Bitte Powershell Version 7 nutzen")
Exit(1)
} else {
# Script block to get top CPU-consuming processes
$scriptBlock = {
param($topN)
Try {
# Retrieve process information
$processes = Get-CimInstance -ClassName Win32_Process
} catch {
Write-Error ("Fehler bei Get-CimInstance -ClassName Win32_Process bei : " + $env:computername)
}
Try {
# Retrieve CPU usage information
$cpuUsage = Get-CimInstance -ClassName Win32_PerfFormattedData_PerfProc_Process
} catch {
Write-Error ("Fehler bei Get-CimInstance -ClassName Win32_PerfFormattedData_PerfProc_Process bei : " + $env:computername)
}
if ($processes -and $cpuUsage) {
# Combine the data
$results = $processes | ForEach-Object {
$process = $_
$cpu = $cpuUsage | Where-Object { $_.IDProcess -eq $process.ProcessId }
try {
$cpuwert=if($cpu){$cpu.PercentProcessorTime} else {0}
[PSCustomObject]@{
ProcessName = $process.Name
ProcessId = $process.ProcessId
CPUUsage = [int]$cpuwert
}
} catch {}
} # Ende ForEach-Object
# Output the results
$results | Where-Object CPUUsage -gt 0 |Sort-Object -Descending -Property CPUUsage,ProcessName,ProcessId -Unique | Select-Object -First $topN
} else {
[PSCustomObject]@{
ProcessName = "FEHLER"
ProcessId = 0
CPUUsage = 9999
}
}
} # Ende Scriptblock
# Run the script block on all servers in parallel
$results = Invoke-Command -ComputerName ($onlineServers.DNSHostName) -Credential $credential -ScriptBlock $scriptBlock -ArgumentList $topN
# Display the results
$results | Out-GridView
}