Menu

Downloading the latest Adobe Flash Player MSIs automatically

I have finally figured out a way to download the latest Adobe Flash Player MSIs using PowerShell. This method involves loading the new Adobe distribution page in Internet Explorer and logging in to generate the appropriate download tokens. Once the tokens are generated the MSI can be downloaded with any tool you desire.

I use a file download function like the one found here. I slightly modified it to fit my needs and named the function Download-File. The function is posted on my blog here.

Once you have the downloaded MSI you can use it for deployment using SCCM, Group Policy, or your preferred deployment system.


# Set at least the distribution page URL. If you do not set the username and password it will prompt for them.
$adobeDistributionPage = ''
$myAdobeIdUsername = ''
$myAdobeIdPassword = ''

[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null

# This sets a registry entry to allow Internet Explorer to open json files to view
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT | Out-Null
(Get-Item HKCR:\).OpenSubKey("MIME\Database\Content Type", $true).CreateSubKey('application/json') | Out-Null
New-ItemProperty -Path "HKCR:\MIME\Database\Content Type\application/json" -Name "CLSID" -Value "{25336920-03F9-11cf-8FD0-00AA00686F13}" -PropertyType String -Force | Out-Null
New-ItemProperty -Path "HKCR:\MIME\Database\Content Type\application/json" -Name "Encoding" -Value 0x08,0x00,0x00,0x00 -PropertyType Binary -Force | Out-Null
Remove-PSDrive HKCR

# Load an IE object
$ie = New-Object -ComObject "InternetExplorer.Application"

# Set preferences to make page invisible
$ie.visible = $false
$ie.silent = $true

# Navigate to Adobe's distribution page
$ie.navigate($adobeDistributionPage)

# Wait for it to load. I add extra wait time, just to be safe.
Start-Sleep -Milliseconds 2000
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
Start-Sleep -Milliseconds 2000

# Check if the sign-in page is there, assume you're already logged in and skip login if it isn't
While ($ie.Document.getElementByID("adobeid_signin").id -eq "adobeid_signin") {
	# Get login credentials if they were not set above
	If (($myAdobeIdUsername -eq $null) -or ($myAdobeIdPassword -eq $null) -or ($myAdobeIdUsername -eq '') -or ($myAdobeIdPassword -eq '')) {
		$adobeCred = Get-Credential -Message "Enter your Adobe ID credentials." -ErrorAction SilentlyContinue
		$myAdobeIdUsername = $adobeCred.Username
		$myAdobeIdPassword = $adobeCred.GetNetworkCredential().Password
	}

	Write-Host Authenticating with Adobe...

  	$ie.Document.getElementByID("adobeid_username").value = $myAdobeIdUsername
	$ie.Document.getElementByID("adobeid_password").value = $myAdobeIdPassword
	$ie.Document.getElementByID("adobeid_signin").submit()

	Start-Sleep -Milliseconds 2000
	while($ie.Busy) { Start-Sleep -Milliseconds 100 }
	Start-Sleep -Milliseconds 2000
	
	If ($ie.Document.getElementByID("adobeid_signin").id -eq "adobeid_signin") {
		Write-Host Authentication Failed, please provide new credentials...
		$myAdobeIdUsername = $null
		$myAdobeIdPassword = $null
	}
}

# It's easy to scrape the download URLs, but they won't work without a download token
$FlashActiveXURL = ($ie.Document.getElementsByTagName("a") | Where-Object {($_.InnerHTML -eq "Download MSI Installer") -and ($_.href -like "*_active_x.msi")}).href
$FlashNPAPIURL = ($ie.Document.getElementsByTagName("a") | Where-Object {($_.InnerHTML -eq "Download MSI Installer") -and ($_.href -like "*_plugin.msi")}).href
$FlashPPAPIURL = ($ie.Document.getElementsByTagName("a") | Where-Object {($_.InnerHTML -eq "Download MSI Installer") -and ($_.href -like "*_ppapi.msi")}).href

# Load the JavaScript file into IE to find the token generator location, this can be hard-coded, but I don't trust Adobe not to change it's location
$ie.Navigate(($ie.Document.getElementsByTagName("script") | Where-Object {($_.type -eq "text/javascript") -and ($_.src -like "*adobe-distribution.min.fp*")}).src)

Start-Sleep -Milliseconds 2000
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
Start-Sleep -Milliseconds 2000

# Find the json URLs that will contain the token URLs
($ie.Document.body.innerText -match '\/(.*?)installerlink\.json') | Out-Null
$jsonURL = ("https://www.adobe.com" + $matches[0])

# Generate token for each download URL
$ie.Navigate($jsonURL + "?href=" + [System.Web.HttpUtility]::UrlEncode($FlashActiveXURL))
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
Start-Sleep -Milliseconds 2000
$FlashActiveXURL = (ConvertFrom-Json -InputObject ($ie.Document.body.innerText)).urlwithtoken
 
$ie.Navigate($jsonURL + "?href=" + [System.Web.HttpUtility]::UrlEncode($FlashNPAPIURL))
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
Start-Sleep -Milliseconds 2000
$FlashNPAPIURL = (ConvertFrom-Json -InputObject ($ie.Document.body.innerText)).urlwithtoken
 
$ie.Navigate($jsonURL + "?href=" + [System.Web.HttpUtility]::UrlEncode($FlashPPAPIURL))
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
Start-Sleep -Milliseconds 2000
$FlashPPAPIURL = (ConvertFrom-Json -InputObject ($ie.Document.body.innerText)).urlwithtoken
 
#Quit IE, now that we have the download tokens we no longer need it.
$ie.Quit()

# Here I used the download function mentioned above
Download-File -Source $FlashActiveXURL
Download-File -Source $FlashNPAPIURL
Download-File -Source $FlashPPAPIURL

Leave a Reply

Your email address will not be published. Required fields are marked *