Installing Adobe Reader DC including the latest patch, with Powershell

Just a code example today, where Powershell downloads the Adobe MSI, runs it, then downloads the latest patch and applies it. Finally, it will disable the auto updater of Adobe Reader DC.

Code:


$tempFolder=$Env:TEMP

function runProcess ($cmd, $params) {
$p = new-object System.Diagnostics.Process
$p.StartInfo = new-object System.Diagnostics.ProcessStartInfo
$exitcode = $false
$p.StartInfo.FileName = $cmd
$p.StartInfo.Arguments = $params
$p.StartInfo.UseShellExecute = $False
$p.StartInfo.RedirectStandardError = $True
$p.StartInfo.RedirectStandardOutput = $True
$p.StartInfo.WindowStyle = 1;
$null = $p.Start()
$p.WaitForExit()
$output = $p.StandardOutput.ReadToEnd()
$exitcode = $p.ExitCode
$p.Dispose()
$exitcode
$output
}

#download installer
invoke-webrequest "ftp://ftp.adobe.com/pub/adobe/reader/win/AcrobatDC/1500720033/AcroRdrDC1500720033_nl_NL.msi" -OutFile "$tempFolder\AcroRdrDC1500720033_nl_NL.msi" -ErrorAction Stop

#run installer
$res = runProcess msiexec "/i $tempFolder\AcroRdrDC1500720033_nl_NL.msi /qb"

#check if return code is 0
if(0 -ne $res[0]){
return "Failed to install Adobe Reader: $($res[0]) $($res[1])"
}

#download the patch
invoke-webrequest "ftp://ftp.adobe.com/pub/adobe/reader/win/AcrobatDC/1500920079/AcroRdrDCUpd1500920079.msp" -OutFile "$tempFolder\AcroRdrDCUpd1500920079.msp" -ErrorAction Stop

#install it
$res = runProcess msiexec "/p $tempFolder\AcroRdrDCUpd1500920077.msp /qb"

#check if return code is 0
if(0 -ne $res[0]){
return "Failed to install Adobe Reader DC Patch: $($res[0]) $($res[1])"
}else{
#Attempt to silently disable the auto updater if set in this script
new-itemproperty "HKLM:\Software\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown" -name bUpdater -value 0 -ErrorAction SilentlyContinue
}

RunProcess from Powershell

Sometimes I want to run older programs / tools like MSIEXEC or such to run from within my Powershell scripts or modules. I wanted to make it easy for myself to format the exact command line, and capturing non-standard output that is written to the screen .

I wrote this simple function to start any  .exe or other w32 process, wait for it to complete, and capturing both the exit code and the full output in an array while the window remains hidden.

Example call to this function:


$res = runProcess msiexec "/i AcroRdrDC1500720033_nl_NL.msi /quiet"
write-host "Result code of msiexec: $($res[0])"
write-host "All output of msiexec: $($res[1])"

And here is the function:


function runProcess ($cmd, $params, $windowStyle=1) {
$p = new-object System.Diagnostics.Process
$p.StartInfo = new-object System.Diagnostics.ProcessStartInfo
$exitcode = $false
$p.StartInfo.FileName = $cmd
$p.StartInfo.Arguments = $params
$p.StartInfo.UseShellExecute = $False
$p.StartInfo.RedirectStandardError = $True
$p.StartInfo.RedirectStandardOutput = $True
$p.StartInfo.WindowStyle = $windowStyle; #1 = hidden, 2 =maximized, 3=minimized, 4=normal
$null = $p.Start()
$output = $p.StandardOutput.ReadToEnd()
$exitcode = $p.ExitCode
$p.Dispose()
$exitcode
$output
}