-
Notifications
You must be signed in to change notification settings - Fork 16
/
check_win_updates-v5.ps1
308 lines (252 loc) · 15.8 KB
/
check_win_updates-v5.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# Powershell script for Zabbix agents.
# Version 2.1 - for Zabbix agent 5x
## This script will check for pending Windows Updates, report them to Zabbix, and optionally install the updates.
### If you do not wish the script to install updates, look for the comment in the script that tells you how to disable that function.
#### Check https://github.com/SpookOz/zabbix-winupdates for the latest version of this script
# ------------------------------------------------------------------------- #
# Variables
# ------------------------------------------------------------------------- #
# Change $reportpath to wherever you want your update reports to go.
$reportpath = "C:\IT\WinUpdates"
# Change $ZabbixInstallPath to wherever your Zabbix Agent is installed
$ZabbixInstallPath = "$Env:Programfiles\Zabbix Agent"
$ZabbixConfFile = "$Env:Programdata\zabbix"
# Do not change the following variables unless you know what you are doing
$htReplace = New-Object hashtable
foreach ($letter in (Write-Output ä ae ö oe ü ue Ä Ae Ö Oe Ü Ue ß ss)) {
$foreach.MoveNext() | Out-Null
$htReplace.$letter = $foreach.Current
}
$pattern = "[$(-join $htReplace.Keys)]"
$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3
$returnStateOptionalUpdates = $returnStateWarning
$Sender = "$ZabbixInstallPath\zabbix_sender.exe"
$Senderarg1 = '-vv'
$Senderarg2 = '-c'
$Senderarg3 = "$ZabbixConfFile\zabbix_agentd.conf"
$Senderarg4 = '-i'
$SenderargUpdateReboot = '\updatereboot.txt'
$Senderarglastupdated = '\lastupdated.txt'
$Senderargcountcritical = '\countcritical.txt'
$SenderargcountOptional = '\countOptional.txt'
$SenderargcountHidden = '\countHidden.txt'
$Countcriticalnum = '\countcriticalnum.txt'
$Senderarg5 = '-k'
$Senderargupdating = 'Winupdates.Updating'
$Senderarg6 = '-o'
$Senderarg7 = '0'
$Senderarg8 = '1'
If(!(test-path $reportpath))
{
New-Item -ItemType Directory -Force -Path $reportpath
}
# ------------------------------------------------------------------------- #
# This part gets the date Windows Updates were last applied and writes it to temp file
# ------------------------------------------------------------------------- #
$windowsUpdateObject = New-Object -ComObject Microsoft.Update.AutoUpdate
Write-Output "- Winupdates.LastUpdated $($windowsUpdateObject.Results.LastInstallationSuccessDate)" | Out-File -Encoding "ASCII" -FilePath $env:temp$Senderarglastupdated
# ------------------------------------------------------------------------- #
# This part get the reboot status and writes to test file
# ------------------------------------------------------------------------- #
if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"){
Write-Output "- Winupdates.Reboot 1" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargUpdateReboot
Write-Host "`t There is a reboot pending" -ForeGroundColor "Red"
}else {
Write-Output "- Winupdates.Reboot 0" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargUpdateReboot
Write-Host "`t No reboot pending" -ForeGroundColor "Green"
}
# ------------------------------------------------------------------------- #
# This part checks available Windows updates
# ------------------------------------------------------------------------- #
$updateSession = new-object -com "Microsoft.Update.Session"
$updates=$updateSession.CreateupdateSearcher().Search(("IsInstalled=0 and Type='Software'")).Updates
$criticalTitles = "";
$countCritical = 0;
$countOptional = 0;
$countHidden = 0;
# ------------------------------------------------------------------------- #
# If no updates are required - it writes the info to a temp file, sends it to Zabbix server and exits
# ------------------------------------------------------------------------- #
if ($updates.Count -eq 0) {
$countCritical | Out-File -Encoding "ASCII" -FilePath $env:temp$Countcriticalnum
Write-Output "- Winupdates.Critical $($countCritical)" | Out-File -Encoding "ASCII" -FilePath $env:temp$Senderargcountcritical
Write-Output "- Winupdates.Optional $($countOptional)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountOptional
Write-Output "- Winupdates.Hidden $($countHidden)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountHidden
Write-Host "`t There are no pending updates" -ForeGroundColor "Green"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargUpdateReboot -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderarglastupdated -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderargcountcritical -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountOptional -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountHidden -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg5 $Senderargupdating $Senderarg6 $Senderarg7 -s "$env:computername"
exit $returnStateOK
}
# ------------------------------------------------------------------------- #
# This part counts the number of updates to be applied
# ------------------------------------------------------------------------- #
foreach ($update in $updates) {
if ($update.IsHidden) {
$countHidden++
}
elseif ($update.AutoSelectOnWebSites) {
$criticalTitles += $update.Title + " `n"
$countCritical++
} else {
$countOptional++
}
}
# ------------------------------------------------------------------------- #
# This part writes the number of each update required to a temp file and sends it to Zabbix
# ------------------------------------------------------------------------- #
if (($countCritical + $countOptional) -gt 0) {
$countCritical | Out-File -Encoding "ASCII" -FilePath $env:temp$Countcriticalnum
Write-Output "- Winupdates.Critical $($countCritical)" | Out-File -Encoding "ASCII" -FilePath $env:temp$Senderargcountcritical
Write-Output "- Winupdates.Optional $($countOptional)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountOptional
Write-Output "- Winupdates.Hidden $($countHidden)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountHidden
Write-Host "`t There are $($countCritical) critical updates available" -ForeGroundColor "Yellow"
Write-Host "`t There are $($countOptional) optional updates available" -ForeGroundColor "Yellow"
Write-Host "`t There are $($countHidden) hidden updates available" -ForeGroundColor "Yellow"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargUpdateReboot -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderarglastupdated -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderargcountcritical -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountOptional -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountHidden -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg5 $Senderargupdating $Senderarg6 $Senderarg7 -s "$env:computername"
}
# ------------------------------------------------------------------------- #
# The following section will automatically apply any pending updates if it finds any critical updates missing or more than 3 optional updates missing. If you do not want this to run, comment out or delete everything between here and the next comment.
if ($countCritical -gt 0 -Or $countOptional -gt 2) {
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg5 $Senderargupdating $Senderarg6 $Senderarg8
$ErrorActionPreference = "SilentlyContinue"
If ($Error) {
$Error.Clear()
}
$Today = Get-Date
$TodayFile = get-date -f yyyy-MM-dd
$UpdateCollection = New-Object -ComObject Microsoft.Update.UpdateColl
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
$Session = New-Object -ComObject Microsoft.Update.Session
Write-Host "`t Initialising and Checking for Applicable Updates. Please wait ..." -ForeGroundColor "Yellow"
$Result = $Searcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
$ReportFile = $reportpath + "\" + $Env:ComputerName + "_WinupdateReport_" + $TodayFile + ".txt"
If (Test-Path $ReportFile) {
Remove-Item $ReportFile
}
New-Item $ReportFile -Type File -Force -Value "Windows Update Report For Computer: $Env:ComputerName`r`n" | Out-Null
Add-Content $ReportFile "Report Created On: $Today`r"
If ($Result.Updates.Count -EQ 0) {
Write-Host "`t There are no applicable updates for this computer."
Add-Content $ReportFile "==============================================================================`r`n"
Add-Content $ReportFile "There are no applicable updates for this computer today.`r`n"
Add-Content $ReportFile "------------------------------------------------`r"
}
Else {
Add-Content $ReportFile "==============================================================================`r`n"
Write-Host "`t Preparing List of Applicable Updates For This Computer ..." -ForeGroundColor "Yellow"
Add-Content $ReportFile "List of Applicable Updates For This Computer`r"
Add-Content $ReportFile "------------------------------------------------`r"
For ($Counter = 0; $Counter -LT $Result.Updates.Count; $Counter++) {
$DisplayCount = $Counter + 1
$Update = $Result.Updates.Item($Counter)
$UpdateTitle = $Update.Title
Add-Content $ReportFile "`t $DisplayCount -- $UpdateTitle"
}
$Counter = 0
$DisplayCount = 0
Add-Content $ReportFile "`r`n"
Write-Host "`t Initialising Download of Applicable Updates ..." -ForegroundColor "Yellow"
Add-Content $ReportFile "Initialising Download of Applicable Updates"
Add-Content $ReportFile "------------------------------------------------`r"
$Downloader = $Session.CreateUpdateDownloader()
$UpdatesList = $Result.Updates
For ($Counter = 0; $Counter -LT $Result.Updates.Count; $Counter++) {
$UpdateCollection.Add($UpdatesList.Item($Counter)) | Out-Null
$ShowThis = $UpdatesList.Item($Counter).Title
$DisplayCount = $Counter + 1
Add-Content $ReportFile "`t $DisplayCount -- Downloading Update $ShowThis `r"
$Downloader.Updates = $UpdateCollection
$Track = $Downloader.Download()
If (($Track.HResult -EQ 0) -AND ($Track.ResultCode -EQ 2)) {
Add-Content $ReportFile "`t Download Status: SUCCESS"
}
Else {
Add-Content $ReportFile "`t Download Status: FAILED With Error -- $Error()"
$Error.Clear()
Add-content $ReportFile "`r"
}
}
$Counter = 0
$DisplayCount = 0
Write-Host "`t Starting Installation of Downloaded Updates ..." -ForegroundColor "Yellow"
Add-Content $ReportFile "`r`n"
Add-Content $ReportFile "Installation of Downloaded Updates"
Add-Content $ReportFile "------------------------------------------------`r"
$Installer = New-Object -ComObject Microsoft.Update.Installer
For ($Counter = 0; $Counter -LT $UpdateCollection.Count; $Counter++) {
$Track = $Null
$DisplayCount = $Counter + 1
$WriteThis = $UpdateCollection.Item($Counter).Title
Add-Content $ReportFile "`t $DisplayCount -- Installing Update: $WriteThis"
$Installer.Updates = $UpdateCollection
Try {
$Track = $Installer.Install()
Add-Content $ReportFile "`t Update Installation Status: SUCCESS"
}
Catch {
[System.Exception]
Add-Content $ReportFile "`t Update Installation Status: FAILED With Error -- $Error()"
$Error.Clear()
Add-content $ReportFile "`r"
}
}
}
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg5 $Senderargupdating $Senderarg6 $Senderarg7
if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"){
Write-Output "- Winupdates.Reboot 1" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargUpdateReboot
Write-Host "`t There is a reboot pending" -ForeGroundColor "Red"
}else {
Write-Output "- Winupdates.Reboot 0" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargUpdateReboot
Write-Host "`t No reboot pending" -ForeGroundColor "Green"
}
$updates=$updateSession.CreateupdateSearcher().Search(("IsInstalled=0 and Type='Software'")).Updates
Write-Output "- Winupdates.Critical $($countCritical)" | Out-File -Encoding "ASCII" -FilePath $env:temp$Senderargcountcritical
Write-Output "- Winupdates.Optional $($countOptional)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountOptional
Write-Output "- Winupdates.Hidden $($countHidden)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountHidden
Write-Host "`t There are now $($countCritical) critical updates available" -ForeGroundColor "Yellow"
Write-Host "`t There are now $($countOptional) optional updates available" -ForeGroundColor "Yellow"
Write-Host "`t There are now $($countHidden) hidden updates available" -ForeGroundColor "Yellow"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargUpdateReboot -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderarglastupdated -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderargcountcritical -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountOptional -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountHidden -s "$env:computername"
exit $returnStateCritical
}
# Comment out or delete everything above here to disable automatic updating
# ------------------------------------------------------------------------- #
if ($countOptional -gt 0) {
exit $returnStateOptionalUpdates
}
# ------------------------------------------------------------------------- #
# If Hidden Updates are found, this part will write the info to a temp file, send to Zabbix server and exit
# ------------------------------------------------------------------------- #
if ($countHidden -gt 0) {
$countCritical | Out-File -Encoding "ASCII" -FilePath $env:temp$Countcriticalnum
Write-Output "- Winupdates.Critical $($countCritical)" | Out-File -Encoding "ASCII" -FilePath $env:temp$Senderargcountcritical
Write-Output "- Winupdates.Optional $($countOptional)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountOptional
Write-Output "- Winupdates.Hidden $($countHidden)" | Out-File -Encoding "ASCII" -FilePath $env:temp$SenderargcountHidden
Write-Host "`t There are $($countCritical) critical updates available" -ForeGroundColor "Yellow"
Write-Host "`t There are $($countOptional) optional updates available" -ForeGroundColor "Yellow"
Write-Host "`t There are $($countHidden) hidden updates available" -ForeGroundColor "Yellow"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargUpdateReboot -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderarglastupdated -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$Senderargcountcritical -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountOptional -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg4 $env:temp$SenderargcountHidden -s "$env:computername"
& $Sender $Senderarg1 $Senderarg2 $Senderarg3 $Senderarg5 $Senderargupdating $Senderarg6 $Senderarg7 -s "$env:computername"
exit $returnStateOK
}
exit $returnStateUnknown