Could use some help here please. We have to maintain a bunch of laptops which will NEVER connect to the internet (security reasons). There is a single laptop of the same type and disk image which does connect to the internet for patch management.
They run Windows 10 and on the internet laptop I use a script which uses the wsus2 cab file to find missing updates.
Now I want to take that script's output from the command line and have it download the missing updates for me.
In my script, I import the findings, find the KB number, append that KB number to the end of "https://www.catalog.update.microsoft.com/Search.aspx?q=", get the webpage in a variable, parse the variable for the patch name, and then try to get the download button which corresponds to the patch name.
For example, the output says "2017-07 Security Update for Adobe Flash Player for Windows 10 Version 1703 for x64-based Systems (KB4025376)" is missing.
So I get the URL, and download the source... which looks like this:
<td class="resultsbottomBorder resultspadding" id="9ebe5d13-4966-4cdb-a612-9780df621411_C1_R0">
<a id='9ebe5d13-4966-4cdb-a612-9780df621411_link' href="javascript:void(0);" onclick='goToDetails("9ebe5d13-4966-4cdb-a612-9780df621411");'>
2017-07 Security Update for Adobe Flash Player for Windows 10 Version 1703 for x64-based Systems (KB4025376)
</a>
</td>
<td class="resultsbottomBorder resultspadding" id="9ebe5d13-4966-4cdb-a612-9780df621411_C2_R0">
Windows 10
</td>
<td class="resultsbottomBorder resultspadding" id="9ebe5d13-4966-4cdb-a612-9780df621411_C3_R0">
Security Updates
</td>
<td class="resultsbottomBorder resultspadding " id="9ebe5d13-4966-4cdb-a612-9780df621411_C4_R0">
7/11/2017
</td>
<td class="resultsbottomBorder resultspadding" id="9ebe5d13-4966-4cdb-a612-9780df621411_C5_R0">
n/a
</td>
<td class="resultsbottomBorder resultspadding resultsSizeWidth" id="9ebe5d13-4966-4cdb-a612-9780df621411_C6_R0">
<span id="9ebe5d13-4966-4cdb-a612-9780df621411_size">20.7 MB</span>
<span class="noDisplay" id="9ebe5d13-4966-4cdb-a612-9780df621411_originalSize">21711921</span>
</td>
<td class="resultsbottomBorder resultsButtonWidth" id="9ebe5d13-4966-4cdb-a612-9780df621411_C7_R0">
<input id="9ebe5d13-4966-4cdb-a612-9780df621411" class="flatLightBlueButton" type="button" value='Download' />
</td>
I say "try" because that is where the script doesn't work.
Before posting, I looked at Click Button on Webpage via VBScript?. No help. I'm posting this so you all don't think I didn't RTFM beforehand.
The script fails on (yeah, I'm hardcoding the ID for now just to get it working... will be a variable later):
IE.Document.getElementsByID("9ebe5d13-4966-4cdb-a612-9780df621411").Item(0).Click
I also tried just using a http provider, rather than an IE object, and that failed too:
http.Document.getElementByID("9ebe5d13-4966-4cdb-a612-9780df621411").Item(0).Click
Here's my script:
' Test data -- not going to be in the production script. The output from the wsus scan
' will be imported here.
Dim findings(1)
findings(0) = "2017-07 Cumulative Update for Windows 10 Version 1703 for x64-based Systems (KB4025342_Fail)"
findings(1) = "2017-07 Security Update for Adobe Flash Player for Windows 10 Version 1703 for x64-based Systems (KB4025376)"
' *****
' Production script follows
' *****
' An array to hold all the findings from the wsus output.
' This array will change in size and is not declared as fixed.
Dim patches()
' Just a counter.
Dim i : i = 0
' Ints from parsing the strings created fromn the findings.
Dim firstParen, lastParen, length
Dim kb
Dim kbAndNameHash : Set kbAndNameHash = CreateObject("Scripting.Dictionary")
' Iterate through the results and populate the array... putting this stuff into
' an array because the original MS script just redirected the findings to
' output -- you couldn't do anything automatically with it afterwards.
For Each item In findings
ReDim Preserve patches(i)
patches(i) = item
i = i + 1
Next
For Each thingy In patches
' Need to parse the string to find just the KB number. The "(KB...)" appears to be
' unique.
firstParen = InStr(thingy, "(KB")
lastParen = InStr(thingy, ")")
' The -1 in this line is to exclude the closing paren in (KB...) -- we just want digits
' no special characters.
length = ((lastParen - 1) - firstParen)
' Just some debug
' WScript.Echo "firstParen: " & firstParen & vbCR & _
' "lastParen: " & lastParen & vbCR & _
' "length: " & length & vbCR
' Get the KB number by reading the string from the next spot after the first paren to
' the length of the number (because it's not always a fixed length).
kb = Mid(thingy, firstParen + 1, length)
' Create a hash for the kb and name. A hash is easier to work with
' than a 2 dimensional array. kb is needed for the patch URL. The name
' is needed for what to download once the page is loaded.
kbAndNameHash.Add kb, thingy
Next
' Provides access to the scripting dictionary
Dim k : k = kbAndNameHash.Keys
Dim n : n = kbAndNameHash.Items
' Get the patches
Dim http : Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
Dim partialURL : partialURL = "https://www.catalog.update.microsoft.com/Search.aspx?q="
Dim webpage, j
' #####
' Tried from: https://stackoverflow.com/questions/5292860/click-button-on-webpage-via-vbscript
Dim objWshShell,IE,searchStr
Set objWshShell = Wscript.CreateObject("Wscript.Shell")
Set IE = CreateObject("InternetExplorer.Application")
' #####
For Each key In k
With http
.Open "GET", partialURL & key, True
.Send
.WaitForResponse
End With
' Load the webpage source into memory.
webpage = http.ResponseText
' Find the postion of the name of the finding.
j = InStr(webpage, kbAndNameHash.Item(key))
If http.Status = 200 Then
If j > 0 Then
' This is where the script no longer works.
' I also tried this:
' http.Document.getElementByID("9ebe5d13-4966-4cdb-a612-9780df621411").Item(0).Click
' #####
' Tried from: https://stackoverflow.com/questions/5292860/click-button-on-webpage-via-vbscript
With IE
.Visible = True
.Navigate partialURL & key
Do While .Busy
WScript.Sleep 100
Loop
.Document.getElementsByID("9ebe5d13-4966-4cdb-a612-9780df621411").Item(0).Click
End With
' #####
Else
MsgBox "Did not find a download link for: " & vbCR & vbCR &_
kbAndNameHash.Item(key) & vbCR & vbCR &_
"Please manually check for " & key, 48, "Patch not found"
End If
Else
' TODO: handle the <>200 status
End If
Next
Set http = NOTHING
Set kbAndNameHash = NOTHING
WScript.Quit
Any assistance on how I can get the Download button which corresponds to the name of the patch specified would be greatly appreciated!!!
Thanks!