-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStart-PowercfgRequestsLog.ps1
More file actions
135 lines (123 loc) · 5.33 KB
/
Copy pathStart-PowercfgRequestsLog.ps1
File metadata and controls
135 lines (123 loc) · 5.33 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
<#
.SYNOPSIS
Wrapper for powercfg to monitor requests for a set period of time and at a set interval
Must be RunAsAdministrator
.DESCRIPTION
Wrapper for powercfg to monitor requests for a set period of time and at a set interval
Converts the results of "powercfg /requests" into an object to return to the output stream
.EXAMPLE
PS C:\> .\Start-PowercfgRequestsLog.ps1 -Delay 500 -Runtime 600
DATETIME : 17/10/2018 00:11:15
DISPLAY : {[PROCESS] \Device\HarddiskVolume7\Users\username\AppData\Local\Google\Chrome\Application\Chrome.exe,
Requested By SomeApp, }
SYSTEM : {[DRIVER] Legacy Kernel Caller, }
AWAYMODE :
EXECUTION :
PERFBOOST :
ACTIVELOCKSCREEN :
Description
-----------
Runs for 600 seconds (10 minutes) at an interval of every 500 milliseconds directly to console
.EXAMPLE
PS C:\> $Results = .\Start-PowercfgRequestsLog.ps1 -Delay 1 -Runtime 10
Description
-----------
Runs for 10 seconds at an interval of every 1 millisecond
Once completed, you can get a quick idea of the processes recorded with the below:
# Foreach property that is not DateTime, print title and sort results, filtered to exclude blank entries
$Results[0].psobject.Properties.name.where{$_ -ne 'DateTime'} | % {Write-Host $_ -f Cyan; $Results.$_ | where {$_ -ne ''} | Sort-Object -Unique}
.NOTES
https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/powercfg-command-line-options
#>
[CmdletBinding()]
#Requires -RunAsAdministrator
param (
# Millisecond delay to wait between running powercfg
# Defaults to 100 milliseconds
# Parameter help description
[Parameter(
Position=0)]
[int] $Delay = 100,
# Runtime until function will finish. Set to 0 to never end, instead requiring you to manually cancel it
# Defaults to 300 seconds (5 minutes)
[Parameter(
Position=1)]
[int] $Runtime = 300
)
begin {
$Stopwatch = [system.diagnostics.stopwatch]::StartNew()
if ($Runtime -eq 0) {
# Reset $Stopwatch to ensure While check always returns true. "0 -le 0"
$Stopwatch.stop()
$Stopwatch.reset()
} else {
# Due to using "$Stopwatch.Elapsed.Seconds -le $Runtime" for the While check, a 5min timer will technically run up to the 6min mark
# Remove 1 minute from $runtime to bring the end run to last up the expected completion time
$Runtime--
}
}
process {
while ($Stopwatch.Elapsed.Seconds -le $Runtime) {
$ToReturn = '' | Select-Object -Property DATETIME, DISPLAY, SYSTEM, AWAYMODE, EXECUTION, PERFBOOST, ACTIVELOCKSCREEN
$Index = ''| Select-Object -Property DISPLAY, SYSTEM, AWAYMODE, EXECUTION, PERFBOOST, ACTIVELOCKSCREEN
Start-Sleep -Milliseconds $Delay
$PowerCFG = powercfg /requests
# Due to how powercfg outputs the results, there's no consistent index position for each section
# Re-indexing the index IDs for each section is necessary to allow accurate selection of the results for each section
$Index.DISPLAY = $PowerCFG.IndexOf('DISPLAY:')
$Index.SYSTEM = $PowerCFG.IndexOf('SYSTEM:')
$Index.AWAYMODE = $PowerCFG.IndexOf('AWAYMODE:')
$Index.EXECUTION = $PowerCFG.IndexOf('EXECUTION:')
$Index.PERFBOOST = $PowerCFG.IndexOf('PERFBOOST:')
$Index.ACTIVELOCKSCREEN = $PowerCFG.IndexOf('ACTIVELOCKSCREEN:')
switch ($true) {
($PowerCFG[$Index.DISPLAY + 1] -ne 'None.') {
[int] $a = $Index.DISPLAY + 1
[int] $b = $Index.SYSTEM - 1
$ToReturn.DISPLAY = $PowerCFG[$a..$b]
}
($PowerCFG[$Index.SYSTEM + 1] -ne 'None.') {
[int] $a = $Index.SYSTEM + 1
[int] $b = $Index.AWAYMODE - 1
$ToReturn.SYSTEM = $PowerCFG[$a..$b]
}
($PowerCFG[$Index.AWAYMODE + 1] -ne 'None.') {
[int] $a = $Index.AWAYMODE + 1
[int] $b = $Index.EXECUTION - 1
$ToReturn.AWAYMODE = $PowerCFG[$a..$b]
}
($PowerCFG[$Index.EXECUTION + 1] -ne 'None.') {
[int] $a = $Index.EXECUTION + 1
[int] $b = $Index.PERFBOOST - 1
$ToReturn.EXECUTION= $PowerCFG[$a..$b]
}
($PowerCFG[$Index.PERFBOOST + 1] -ne 'None.') {
[int] $a = $Index.PERFBOOST + 1
[int] $b = $Index.ACTIVELOCKSCREEN - 1
$ToReturn.PERFBOOST = $PowerCFG[$a..$b]
}
($PowerCFG[$Index.ACTIVELOCKSCREEN + 1] -ne 'None.') {
[int] $a = $Index.ACTIVELOCKSCREEN + 1
[int] $b = $PowerCFG.count - 1
$ToReturn.ACTIVELOCKSCREEN = $PowerCFG[$a..$b]
}
}
if (
# No need to output results for every loop, only those with any result
$null -ne $ToReturn.DISPLAY -or
$null -ne $ToReturn.SYSTEM -or
$null -ne $ToReturn.AWAYMODE -or
$null -ne $ToReturn.EXECUTION -or
$null -ne $ToReturn.PERFBOOST -or
$null -ne $ToReturn.ACTIVELOCKSCREEN
) {
$ToReturn.DATETIME = $(Get-Date)
Write-Output -InputObject $ToReturn
}
}
}
end {
if ($Stopwatch.IsRunning) {
$Stopwatch.Stop()
}
}