forked from ruudmens/LazyAdmin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Auto-Shutdown.ps1
160 lines (123 loc) · 5.11 KB
/
Auto-Shutdown.ps1
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<#
.SYNOPSIS
Monitors Steam downloads and initiates a system shutdown when downloads have completed.
.DESCRIPTION
This script will check for active Steam downloads and monitor their progress. Other scripts rely on
network / disk activity however they are somewhat flawed as they don't accommodate for user intervention
or drop in network connectivity.
Providing Steam doesn't change how the registry settings work, this script should correctly identify when
downloads are active, when they have completed and when there has been user intervention.
.PARAMETER loopSleepSeconds
This is the interval timer for the loop that monitors the active download.
.PARAMETER shutdownDelaySeconds
This is the delay for system shutdown, AFTER the threshold for no download activity has been exceeded.
.PARAMETER noDownloadActivityThreshold
This is used to specify how many loop iterations of an inactive download are completed before the script is to
initiate the shutdown call.
#>
param (
[int] $loopSleepSeconds = 60,
[int] $shutdownDelaySeconds = 900, # 15 minutes
[int] $noDownloadActivityThreshold = 5
)
$STEAM_REG_PATHS = @(
'HKLM:\SOFTWARE\WOW6432Node\Valve\Steam',
'HKLM:\SOFTWARE\Valve\Steam'
)
$STEAM_APPS_REG_PATH = "HKCU:\Software\Valve\Steam\Apps\*"
$STEAM_PROCESS_NAME = "steam"
$ACF_FILE_PATTERN = "appmanifest_{0}.acf"
function Get-SteamPath {
# There should only be one return here but just in case...
foreach ($path in $STEAM_REG_PATHS | Where-Object {Test-Path $_}) {
$installPath = (Get-ItemProperty -Path $path -Name "InstallPath" -ErrorAction SilentlyContinue).InstallPath
if (Test-Path -Path $installPath) {
return $installPath
} else {
throw "No Steam path was detected."
}
}
}
function Get-ActiveDownload {
return Get-ItemProperty -Path $STEAM_APPS_REG_PATH -Name "Updating" -ErrorAction SilentlyContinue | Where-Object {$_.Updating -eq 1}
}
function Confirm-DownloadComplete {
param (
[Parameter(Mandatory=$true)]
[string] $acfPath
)
# User has cancelled the download and uninstalled.
if (!(Test-Path -Path $acfPath)) {
return $false
}
$acfContent = Get-Content -Path $acfPath
$isDownloadCompleted = $false
if ($acfContent) {
$bytesToDownloadMatch = $acfContent | Select-String -Pattern "`"BytesToDownload`"\s+`"(\d+)`""
$bytesDownloadedMatch = $acfContent | Select-String -Pattern "`"BytesDownloaded`"\s+`"(\d+)\`""
if($bytesToDownloadMatch -and $bytesDownloadedMatch) {
$bytesToDownload = [int] $bytesToDownloadMatch.Matches[0].Groups[1].Value
$bytesDownloaded = [int] $bytesDownloadedMatch.Matches[0].Groups[1].Value
if ($bytesToDownload -eq $bytesDownloaded) {
$isDownloadCompleted = $true
}
}
}
return $isDownloadCompleted
}
$steamPath = Get-SteamPath
$downloadAppID = $null
$loopState = "WaitingForSteam"
$i = 0
while ($true) {
Clear-Host
switch ($loopState) {
"WaitingForSteam" {
Write-Output "Looking for Steam process..."
if (Get-Process $STEAM_PROCESS_NAME -ErrorAction SilentlyContinue) {
Write-Output "Steam process detected!"
$loopState = "WaitingForDownloads"
} else {
Start-Sleep -Seconds 3
}
}
"WaitingForDownloads" {
$activeDownload = Get-ActiveDownload
if ($activeDownload) {
$downloadAppID = $activeDownload.PSChildName
$loopState = "MonitoringDownloads"
$i = 0
} else {
Write-Output "Waiting for downloads to begin..."
Start-Sleep -Seconds 3
}
}
"MonitoringDownloads" {
$activeDownload = Get-ActiveDownload
if ($activeDownload) {
Write-Output "Steam client is downloading."
$downloadAppID = $activeDownload.PSChildName
$i = 0
} else {
if(Confirm-DownloadComplete -acfPath ("${steamPath}\steamapps\$ACF_FILE_PATTERN" -f $downloadAppID)) {
Write-Warning "There is no active download."
Write-Warning "$($noDownloadActivityThreshold - $i) checks remain until shutdown."
if ($i -ge $noDownloadActivityThreshold) {
Write-Output "Sending shutdown signal..."
shutdown /s /f /t $shutdownDelaySeconds
Write-Output "To cancel the shutdown, run `"shutdown /a`"."
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
exit
}
$i++
} else {
Write-Output "User intervention has been detected."
$loopState = "WaitingForDownloads"
continue
}
}
Write-Output "Next check: ~$((Get-Date).AddSeconds($loopSleepSeconds).ToString('HH:mm:ss'))"
Start-Sleep -Seconds $loopSleepSeconds
}
}
}