Jump to content


wmmayms

Guide: Upgrading software dynamically with a task sequence

Recommended Posts

Hi guys

 

In this guide I will show you how you can dynamically upgrade applications no matter who installed it or from what source MSI package.

I will start of by introducing you to MSI UpgradeCode which is similar to the ProductCode but not the same. Normally this code is used by the MSI package to determine if there is an earlier application of the same type installed and in that case upgrade.

 

The ProductCode is the unique key for a specific MSI package.

The upgradeCode is the unique key for the specific software (at least if its a serious company who created the MSI installer)

 

Okay!

So would it not be great to be able to run this command:

msiexec /x <ProductCode> /qn

And uninstall any version of the software that you no longer need?

 

If that worked it would be great, but unfortunately you cannot do this. To uninstall a MSI package you need to specify the ProductCode after you /x switch.

 

So what to do?

Create a script of course! cool.gif

 

I created this script: MSIUninstallFromUpgradeCode.vbs

 

'Written by wmmayms @ WindowsNoob 2010-23/2

On Error Resume Next
'==================================== 
' Define Logpath
'==================================== 
strLogPath = "c:\MSIUninstallFromUpgradeCode.log"

'==================================== 
' Check arguments 
'==================================== 
Set objArguments = Wscript.Arguments
If WScript.Arguments.Count = 1 Then 
 strUpgradeCode = objArguments.Named.Item("Upgradecode")
Else 
  Wscript.Echo "Usage: MSIUninstallFromUpgradeCode.vbs /Upgradecode:[upgradecode]" 
  Wscript.Quit 
End If

'==================================== 
' Setup Logging
'==================================== 
Set objFSO = CreateObject("Scripting.FileSystemObject")

If not objFSO.FileExists(strLogPath) Then
 Set objOutputFile = objFSO.CreateTextFile(strLogPath)
Else
 Set objOutputFile = objFSO.OpenTextFile(strLogPath, 8)
End if

objOutputFile.WriteLine "--Script triggerd with the following UpgradeCode: " & strUpgradeCode 

'==================================== 
' Main Script
'==================================== 
Set installer = CreateObject("WindowsInstaller.Installer")
For Each prod In installer.ProductsEx("", "", 7)
  sLocalPkg = prod.InstallProperty("LocalPackage")
  set oDB = installer.OpenDataBase(sLocalPkg, 0)
  sQuery = "SELECT `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"
  Set oView = oDB.OpenView(sQuery)
  oView.Execute
  Set oRecord = oView.Fetch
  If Not (oRecord is Nothing) Then
   sUpgradeCode = oRecord.StringData(1)


	If strUpgradeCode = sUpgradeCode Then
	set WshShell = CreateObject("wscript.shell")
	objOutputFile.WriteLine "About to run: msiexec.exe /x" & prod.ProductCode & " /qn"
	Return = WshShell.Run("msiexec.exe /x" & prod.ProductCode & " /qn", 1, true)

  	If Return <> 0 Then
		objOutputFile.WriteLine "Uninstall failed. Error Code " & Return
	objOutputFile.Close
		Wscript.Quit()
  	Else
		objOutputFile.WriteLine "Uninstall succeeded"
  	End If  
	End If

  End If
Next

'==================================== 
' Close Logging
'==================================== 
objOutputFile.WriteLine "--Script has finished, if there is no information between Script Triggerd and Script finished then no package was found."   
objOutputFile.Close

 

 

The script works like this:

cscript.exe MSIUninstallFromUpgradeCode.vbs /UpgradeCode:<UpgradeCode>

 

Example:

cscript.exe MSIUninstallFromUpgradeCode.vbs /UpgradeCode:{529316F8-601C-48AB-BAF6-D9E09938D8D3}

 

The script will log it´s activities to a logfile located here:

c:\MSIUninstallFromUpgradeCode.log

 

What it does is that it basically creates a query for the ProductCode based on what UpgradeCode you use as an argument when triggering the script.

This makes it possible for us to create a uninstall command based on the UpgradeCode which in my opinion is great!

 

 

So how do we use this in the best way possible? Upgrade scenarios of course!

Here is how:

 

1. Start by creating a new SCCM package with nothing else but the script i supplied above. Don´t forget to add it to your distribution point.

 

2. Create another package containing the MSI installers of the software you want to upgrade to. Again, don´t forget the distribution point.

 

3. Okay, now lets create a new custom task sequence. Give it a good name and then right click on it and choose edit.

 

4. Let the fun begin! Create two default groups and name them "Uninstall" and "Install"

post-2500-0-20982400-1298554841_thumb.jpg

 

 

5. Under Uninstall create a "Run Command Line" Step.

Input this command line: XCOPY ".\*.*" %temp% /D /E /C /I /Q /H /R /Y /S

And make it run from the package containing your "MSIUninstallFromUpgradeCode.vbs" script

post-2500-0-10295500-1298555018_thumb.jpg

 

 

6. Create a new "Run Command Line" Step under uninstall group.

Click on the option tab and click "Add Condition". Choose "installed software".

 

Now browse for the MSI software that you want to uninstall. This can be either a new MSI Installer or the original (remember we are doing this based on the UpgradeCode NOT the ProductCode)

Don´t forget to mark "Match any version of this product (UpgradeCode only)"

post-2500-0-53743400-1298555387_thumb.jpg

 

 

7. Before going back to the properties tab make sure you copy the UpgradeCode.

 

8. On the properties tab enter the following commandline:

cscript.exe MSIUninstallFromUpgradeCode.vbs /UpgradeCode:<UpgradeCode>

 

Replace <UpgradeCode> with the code you just copied from the options tab.

Now make the command start running from %temp% by adding that value.

post-2500-0-56020400-1298555644_thumb.jpg

 

 

Okay this means that the uninstall group is complete in our task sequence!

If you followed my example above this will uninstall any version of iTunes on the computer where this task sequence is advertised. This is all good... But we want the newest version to get installed aswell!

 

1. Under the install groupl create a "Run Command Line" Step.

Input this command line: XCOPY ".\*.*" %temp% /D /E /C /I /Q /H /R /Y /S

And make it run from the package containing your new software MSI package/packages

post-2500-0-07324000-1298555868_thumb.jpg

 

 

2. Create a new "Run Command Line" Step under install group

Add the following command: msiexec /i i <MSI Installer> REBOOT="ReallySuppress" /qn

And make it run in this folder: %temp%

post-2500-0-08267200-1298555952_thumb.jpg

 

 

 

Okay that is it!

If you advertise this task sequence it will now uninstall any version and then install the newest version which is currently 10.1.2.17

Without the need of creating different collections based on what software they currently have and different programs for running different commands. This is all you need to do cool.gif

 

 

If your software requires many different parts you can do something like this:

post-2500-0-07855100-1298556134_thumb.jpg

 

 

 

I hope you guys can find some good use of the info provided here. Feel free to get back to me with thoughts and improvements.

Here is the task sequence if you want to import the finished thingcool.gif

example.xml

 

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

excellent post Marcus thanks for sharing :)

Share this post


Link to post
Share on other sites

Thanks. was thinking of a way to have a general uninstall program for specific software like all versions of Firefox/Chrome. Could use the Uninstall part and keep the next part for future reference. Great post :)

Share this post


Link to post
Share on other sites

Hi again. Do you know a way to find any version of a program without the localization. As you can see from my screenshot i am able to uninstall all Firefox en-US but it is failing for GB. Only way is to edit my msi with an msi editor? What is the reason of having a condition if we want to uninstall all versions? If i remove the condition it can not find the software on the client to uninstall it.

post-4980-0-11020600-1298625939_thumb.jpg

Share this post


Link to post
Share on other sites

Hi again. Do you know a way to find any version of a program without the localization. As you can see from my screenshot i am able to uninstall all Firefox en-US but it is failing for GB. Only way is to edit my msi with an msi editor? What is the reason of having a condition if we want to uninstall all versions? If i remove the condition it can not find the software on the client to uninstall it.

 

Hm good feedback! I have not had time to test it so much yet, and especially not in international enviroments cool.gif

But we must remember why we use the condition. This is to make it run only on computer which has the software targeted installed.

 

To work around this problem you can simply remove the condition and let the script run on all computers targeted by the advertisement. If the script does not find a productcode for the given upgradecode it will do nothing.

And the "c:\MSIUninstallFromUpgradeCode.log" (found locally on the client) will tell you that no productcode was found.

I will look into the condition section to see if it is possible to use another condition under these circumstances.

cheers! cool.gif

Share this post


Link to post
Share on other sites

Hi thanks for replying. I actually made a collection based on Add/Remove Programs having %Firefox% installed so i know they have the program. but with the condition removed as well it does not work for a majority. Will have a look again on Monday and let you know if i found anything else.

Share this post


Link to post
Share on other sites

Hi thanks for replying. I actually made a collection based on Add/Remove Programs having %Firefox% installed so i know they have the program. but with the condition removed as well it does not work for a majority. Will have a look again on Monday and let you know if i found anything else.

 

I would tick the "Continue on Error" box for the uninstall steps.

Then i would also think about how the uninstall process works if the program or any of its dependencies are loaded when you trigger your command. This might make the uninstall process fail. The eventlog is a good place to find this information.

 

If this is the case then maybe you need to run your upgrade while users are logged off.

Or you might need to add a step for killing started processes before trying to uninstall. If you decide to do this I strongly recommend an optional advertisement or at least a long countdown time to not upset your customers to much cool.gif

 

PS: Chrome > Firefox

Share this post


Link to post
Share on other sites

I would tick the "Continue on Error" box for the uninstall steps.

Then i would also think about how the uninstall process works if the program or any of its dependencies are loaded when you trigger your command. This might make the uninstall process fail. The eventlog is a good place to find this information.

 

If this is the case then maybe you need to run your upgrade while users are logged off.

Or you might need to add a step for killing started processes before trying to uninstall. If you decide to do this I strongly recommend an optional advertisement or at least a long countdown time to not upset your customers to much cool.gif

 

PS: Chrome > Firefox

 

 

The script says that package not found so i don't think that continue on error will work. is as if its different upgradecode. Will check again.

 

Well we use IE cause its manageable at work and ofcourse users can not use anything else since im blocking them from the proxy :P We are mean... :P

Share this post


Link to post
Share on other sites

Hi some more info: The upgrade ID is the same no matter the language, at least on Firefox Msi. But when i view the Resourse Explorer the product ID is Mozilla Firefox (Version) :P oh well

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...