Now Featuring the Latest Version!: Basic Patch Management for Basic Software

34
BASIC PATCH MANAGEMENT FOR BASIC SOFTWARE NOW FEATURING THE LATEST VERSION Francis Beaumier IT Specialist Brown County Library 515 Pine Street Green Bay, WI 54301 Phone: 920-448-5863 [email protected] .us

Transcript of Now Featuring the Latest Version!: Basic Patch Management for Basic Software

Page 1: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

B A S I C PATC H M A N A G E M E N T F O R B A S I C S O F T WA R E

NOW FEATURING THE LATEST VERSION

Francis BeaumierIT SpecialistBrown County Library515 Pine StreetGreen Bay, WI 54301Phone: [email protected]

Page 2: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

ORGANIZATIONAL BACKGROUND

• Part of Brown County• Use of county’s Technology Services department• Getting new software is a process

• Public computers • Windows machines on a physically separate and all

wireless network• No central management• Freezing software• …. No updates besides Microsoft ones

Page 3: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

STARTING POINTS

• Computers already left on weekly for Windows updates• Windows Task Scheduler• Public computers can talk to other public

computers• MSIs can be installed silently• Compare-Object cmdlet • Windows 7 computers all come with a version of

Powershell• Web server available

Page 4: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

CLIENTS.PS1

$URL = "http://www.example.org/updates/Updater.ps1"$Output = "C:\Updater\Updater.ps1"

#Download the Updater.ps1 file (New-Object System.Net.WebClient).DownloadFile($URL,$Output);

#Call the downloaded scriptPowershell.exe -File $Output

Page 5: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

$sourceFolder = "\\172.17.101.210\updates$"$targetFolder = "c:\updates"$sourceItem = Get-ChildItem -Path $sourceFolder $targetItem = Get-ChildItem -Path $targetFolder#if *Item is empty, provide empty array to make Compare-Object work.If (-not $sourceItem) {$sourceItem = @()}if (-not $targetItem) {$targetItem = @()}$differentitems = Compare-Object $sourceItem $targetItem -Property Name, LastWriteTime, Length | where { $_.SideIndicator -eq "<=" }

#Copy the items that are different to the client PCSet-Location $sourceFolder$differentitems | foreach {Copy-Item -Destination $targetFolder -Path $_.Name}

#Start the installation Pocess of each Update\Package that was copiedSet-Location $targetFolder$differentitems | foreach { Start-Process -FilePath $_.Name -ArgumentList "/q" -Wait }

#Reboot the computer after the installs are completeRestart-Computer

ORIGINAL UPDATER.PS1

Page 6: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

UPDATER.PS1$source="http://www.example.org/updates/" #web server address $targetFolder="c:\updates\" #local file destination $webClient = New-Object System.Net.WebClient$updates = $webClient.DownloadString($source).Split("`n") # Web server listing -> object -> array$sourceItem= @()foreach ($update in $updates) { $file,$mod = $update.Split(","); $sourceItem += New-Object –TypeName PSObject –Prop @{'Name'=$file; 'LastWriteTime'= Get-Date $mod };}$targetItem = Get-ChildItem -Path $targetFolder#if targetItem is empty, provide empty array to make Compare-Object work.if (-not $targetItem) {$targetItem = @()}$differentitems = Compare-Object $sourceItem $targetItem -Property Name, LastWriteTime | where { $_.SideIndicator -eq "<=" }

Page 7: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

UPDATER.PS1 (CONTINUED)

Set-Location $targetFolder foreach ($item in $differentitems) { #Copy the items that are different to the client PC $webClient.DownloadFile($source+$item.Name, $targetFolder+$item.Name)

#Start the installation Pocess of the Update\Package that was copied Start-Process -FilePath $item.Name -ArgumentList "/q /norestart" -Wait #Change the date modified to match what the server says so that the #compare works on the next run (Get-Item ($targetFolder+$item.Name)).LastWriteTime= $item.LastWriteTime}

Page 8: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

INDEX.PHP

<? // set time zone so that date modified is accuratedate_default_timezone_set('America/Chicago');

$updateList = array_diff(scandir('.'), array('..', '.', 'index.php',

'error_log', 'Updater.ps1'));

foreach ($updateList as $file ) {$out .= rawurlencode($file) . ',' .

date('Y-m-d G:i:s',filemtime ($file)) . "\n"; }

print rtrim($out, "\n")

?>

Page 9: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

INDEX.PHP OUTPUT

Page 10: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

GOOD TO GO UPDATES

• Adobe Acrobat Reader patches• Flash• Shockwave

Page 11: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

SERVER INSTALLATION

1. Make a folder with Updater.ps1, index.php, and the updates that you want.

2. Make sure your server has PHP, is configured to serve that folder and use index.php as your directory index.

Page 12: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

CLIENT INSTALLATION

1. Set power settings2. Create Updater and Updates folders in C:\3. Allow PowerShell to run unsigned scripts:

set-executionpolicy bypass4. Copy Clients.ps1 to the Updater folder5. Create a scheduled task to run the Updater

during your maintenance window.

Page 13: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

SCHEDULING THE UPDATER

12

34

Page 14: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

SCHEDULING THE UPDATER II

Page 15: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

SCHEDULING THE UPDATER III

Page 16: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

MSI HACKING WITH ORCA: SKYPE

• Skype MSI: http://www.skype.com/go/getskype-msi• Orca: https://

www.microsoft.com/en-us/download/details.aspx?id=3138

• In the Property table, • change

ProductCode to something new.

• change InstallUpdatesEnabled to #0

Page 17: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

MSI HACKING WITH ORCA: ADOBE ACROBAT READER

• Change ECULA_ACCEPT to YES in the Property table.

Page 18: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

ADVANCED MSI HACKING WITH ORCA: JAVA (* THERE’S AN EASIER WAY)

• Get the .exe from the vendor. Run it but do not click through the wizard.• Retrieve the MSI from %userprofile%\appdata\

LocalLow\Oracle\Java\jre1.8.0_xx (where xx is the update number)• Make the following edits in Orca:• In the CustomAction table, change the Type of installexe

to 3090. This adjusts the permissions requested by the installer.

Page 19: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

ADVANCED MSI HACKING WITH ORCA: JAVA II

• The changes on the previous slide will get you going. The rest of these instructions take care of removing previous versions.• Make the

following edits in Orca:• In the InstallExecuteSequence table, change the condition for

FindRelatedProducts and RemoveExistingProducts to 1=1. This forces those two actions to run.

Page 20: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

ADVANCED MSI HACKING WITH ORCA: JAVA III

• Add an entry for each version of Java you wish to uninstall in the Upgrade table: • UpgadeCode: you’ll need the one for your Java version• VersionMin – 0.0.0.0 (any version ≥ 0 )• VersionMax – leave blank to use only VersionMin as criteria• Language – blank = any• Attributes – a set of flags. 256 seems to work for me• Remove – ALL means all • ActionProperty – a variable of your choice – must be unique

and must be added to the SecureCustomProperties variable in the Property table. I chose FRANCIS1

Page 21: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

HOW DO I TRACK DOWN A JAVA UPGRADE CODE?

• If you have the MSI, open it in Orca• Otherwise, if you have a machine with it installed:• Go to C:\Windows\Installer• Right click the column headings and add Authors• Find the .msi authored by Oracle• Open it in Orca

• Go to the Property table, and you’ll find the UpgradeCode property.

Page 22: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

ADVANCED MSI HACKING WITH ORCA: JAVA IV

• Go to the property table and add/change the following:• JAVAUPDATE=0• AUTOUPDATECHECK=0• JU=0• In SecureCustomProperties, add

your custom variables from part III

Page 23: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

SO YOU NEED SOME MSIs?

• Make them!• Be leery of packing software…

Page 24: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

Firef

ox.v

er

Firefox.mm

ROLL YOUR OWN MSI WITH MAKEMSI: FIREFOX .

• MAKEMSI: dennisbareis.com • Standard Firefox installer

; ProductName = Firefox; DESCRIPTION = Install Firefox; Installed = WINDOWS_ALL

VERSION : 47.0.1DATE : 19 Nov 2015CHANGES : nothing#define COMPANY_WANT_TO_INSTALL_DOCUMENTATION N ;; no

docs

#include "ME.MMH" ;; required files

; install firefox<$WrapInstall EXE="Firefox Setup 47.0.1.exe" Args='-ms' SeqI="<-InstallFinalize">

; dummy component - the MSI needs to have something to install<$Component "dummy" Create="Y" Directory_="<$AnyDir>"> <$/Component>

; filter validation errors<$MsiValFilter "ICE71">

Page 25: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

BROWN COUNTY LIBRARY FIREFOX#define COMPANY_AUTO_UNINSTALL_VIA_UPGRADE_TABLE N ;;nothing to uninst #define COMPANY_WANT_TO_INSTALL_DOCUMENTATION N ;; no docs#define COMPANY_REINSTALLMODE ;; leave blank to avoid validation issue#define UISAMPLE_DISABLE_COMPLETELY Y ;; disable MSI UI customizations#define DBG_ALL N#include "ME.MMH" ;; required files ; do not register this installer in Add/Remove Programs <$Table "InstallExecuteSequence">

<$RowsDelete WHERE="Action = 'PublishComponents'"><$RowsDelete WHERE="Action = 'PublishFeatures'"><$RowsDelete WHERE="Action = 'PublishProduct'"><$RowsDelete WHERE="Action = 'RegisterProduct'"><$RowsDelete WHERE="Action = 'RegisterUser'">

<$/Table>; fast install<$Table "Property">

<$Row Property="MSIFASTINSTALL" Value="3"><$/Table>

Page 26: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

BROWN COUNTY LIBRARY FIREFOX II ; install firefox<$WrapInstall EXE="Firefox Setup 47.0.1.exe" Args='-ms' SeqI="<-InstallFinalize">; install BCL settings#( <$DirectoryTree Key="INSTALLDIR" Dir="c:\program files\Mozilla Firefox" CHANGE="\" PrimaryFolder="Y">#)<$Files "files\moz*" DestDir="INSTALLDIR">#( <$DirectoryTree Dir="c:\program files\Mozilla Firefox\browser" Key="INSTALLDIR2" CHANGE="\" PrimaryFolder="Y">#)<$Files "files\override.ini" DestDir="INSTALLDIR2">#( <$DirectoryTree Dir="c:\program files\Mozilla Firefox\defaults\pref" Key="INSTALLDIR3" CHANGE="\" PrimaryFolder="Y">#)<$Files "files\local-settings.js" DestDir="INSTALLDIR3">

Page 27: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

<$VbsCa Binary="ADRC.vbs"> <$VbsCaEntry "ADRC"> DoIt() <$/VbsCaEntry><?NewLine><?NewLine> sub DoIt() Dim wshNetwork, fso Set wshNetwork = CaMkObject("WScript.Network") If InStr(wshNetwork.ComputerName,"ADRC") > 0 Then Set fso = CaMkObject("Scripting.FileSystemObject") If fso.FileExists("C:\Program Files (x86)\Mozilla Firefox\mozilla.cfg") Then fso.DeleteFile("C:\Program Files (x86)\Mozilla Firefox\mozilla.cfg") fso.MoveFile "mozilla-adrc.cfg","mozilla.cfg" ' will need full path Else fso.DeleteFile("C:\Program Files\Mozilla Firefox\mozilla.cfg") fso.MoveFile "mozilla-adrc.cfg","mozilla.cfg" ' will need full path End If set fso = Nothing End If set wshNetwork = Nothing end sub<$/VbsCa>

BCL

FIRE

FOX

III

Page 28: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

BROWN COUNTY LIBRARY FIREFOX IV

#( <$VbsCaSetup Binary="ADRC.vbs" Entry="ADRC" Seq="InstallFinalize-" CONDITION=^<$CONDITION_EXCEPT_UNINSTALL>^ Type="IMMEDIATE">#)

; ignore validation errors<$MsiValFilter "ICE82">

Page 29: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

AIR

• Problem: AdobeAirInstaller.exe uses an MSI internally, so wrapping it in an MSI won’t work• My solution: AutoIT: https://www.autoitscript.com

#RequireAdmin#NoTrayIcon#include <MsgBoxConstants.au3>

;MsgBox($MB_SYSTEMMODAL, "", "copying file")FileInstall ( ".\AdobeAirInstaller.exe", "c:\windows\temp\", 1)

;MsgBox($MB_SYSTEMMODAL, "", "installing air")RunWait('c:\windows\temp\AdobeAirInstaller.exe -silent' _ & ' –eulaAccepted', "", @SW_HIDE)

;MsgBox($MB_SYSTEMMODAL, "", "deleting air")FileDelete ( "c:\windows\temp\AdobeAirInstaller.exe" )

Page 30: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

BATCH FILE EXAMPLE: INSTALLING WIRELESS PROFILES

#include ..\francis.mmh; files to install#( <$DirectoryTree Dir="c:\users\libadmin\desktop\wifi-profiles" Key="INSTALLDIR" CHANGE="\" PrimaryFolder="Y">#)<$Files "wifi-profiles\*.*" DestDir="INSTALLDIR">; script to run after installation<$VbsCa Binary="Postflight.vbs"> <$VbsCaEntry "Postflight"> dim WshShell : Set WshShell = CaMkObject("WScript.Shell") WshShell.Run "C:\users\libadmin\desktop\wifi-profiles\import.bat", , TRUE set WshShell = Nothing <$/VbsCaEntry><$/VbsCa>#( <$VbsCaSetup Binary="Postflight.vbs" Entry="Postflight" Seq="InstallFinalize-" CONDITION="" Type="IMMEDIATE">#)

Page 31: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

#include "OpenMsi.MMH"<$Msi "out\Java.msi" template="Java.msi"> <$Table "CustomAction"> <$Row @Where="Action='installexe'" Type="3090"> <$/Table> <$Table "InstallExecuteSequence"> <$Row @Where="Action='FindRelatedProducts' or Action='RemoveExistingProducts'" Condition="1=1"> <$/Table> <$Table "Upgrade"> <$Row UpgradeCode="{57BDA5C6-443C-4D65-B233-282393218045}" VersionMin="0.0.0.0" Attributes="256" Remove="ALL" ActionProperty="FRANCIS1"> <$/Table> <$Table "Property"> <$Row @Where="Property='SecureCustomProperties'" @SelfRef="{*}" *Value=^"FRANCIS1;" & {*}̂ > <$Row Property="JAVAUPDATE" Value="0"> <$Row Property="AUTOUPDATECHECK" Value="0"> <$Row Property="JU" Value="0"> <$/Table><$/Msi><$MsiValFilter "ICE03|ICE61" Re="Y"> ; filter validation errors

JAVA THE MAKEMSI WAY

Page 32: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

MORE POSSIBILITIES

• Different update branches• Error checking / hashes• Reporting

Page 33: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

BROWN COUNTY LIBRARY’S SOFTWARE UPDATE LIBRARY

• Adobe Air• Adobe Flash (Active X)• Adobe Flash (Plug-in• Adobe Reader• Adobe Shockwave• Arduino• Google Earth• HP Universal Print Driver• Kyocera KX Print Driver• Mozilla Firefox• Oracle Java• Netloan (our PC reservation software)• Paint.NET• Skype• WebEx Player

Page 34: Now Featuring the Latest Version!: Basic Patch Management for Basic Software

DEMO/QUESTIONS