Wednesday, March 16, 2011

Script/SCCM Upgrade Office 2007 to Office 2010

There are a lot of ways to uninstall Office 2007 and install Office 2010, as well as many ways to combine them to effect an "upgrade".  Here's one I recently used that was clean, simple (ok, sort of simple) and reliable even when shoved through the entrails of SCCM advertisements onto XP and Windows 7 clients.  Note that the "custom.MSP" was created by using the Office Customization Toolkit.

Watch out for word-wrapping!

CMD Script
@echo off
rem ****************************************************************
rem  Filename..: setup.cmd
rem  Author....: David M. Stein
rem  Date......: 03/16/2011
rem  Purpose...: install microsoft office 2010 (remove 2007 if found)
rem ****************************************************************
CLS
title Installing Office 2010
echo Installing Microsoft Office 2010...
SETLOCAL
set APPNAME=Office2010_x86
set LOG=%TMP%\%APPNAME%_install.log
rem set MSI=/quiet /norestart
echo %DATE% %TIME% installing... %APPNAME%... >%LOG%
echo %DATE% %TIME% source....... %~dps0 >>%LOG%
echo %DATE% %TIME% target....... %COMPUTERNAME% >>%LOG%
echo %DATE% %TIME% windir....... %WINDIR% >>%LOG%
echo %DATE% %TIME% progfiles.... %PROGRAMFILES% >>%LOG%
echo %DATE% %TIME% temp......... %TMP% >>%LOG%
echo INSTALL LOG: %LOG%
echo ----------------------------------------------- >>%LOG%
echo *** REMOVE OFFICE 2007 *** >>%LOG%
rem ------------------------------------------------
echo %DATE% %TIME% info: checking if office 2007 is installed... >>%LOG%
if exist "%ProgramFiles%\Microsoft Office\Office12\winword.exe" (
  echo %DATE% %TIME% info: *** removing Office 2007... >>%LOG%
  cscript /nologo "%~dps0uninstall2007.vbs" >>%LOG%
) else (
  echo %DATE% %TIME% info: Office 2007 was not found on this compuer. >>%LOG%
)
echo ----------------------------------------------- >>%LOG%
echo *** INSTALL OFFICE 2010 *** >>%LOG%
echo %DATE% %TIME% info: app-log is %temp%\Microsoft Office Professional Plus Setup(*).txt >>%LOG%
echo %DATE% %TIME% command is "%~dps0setup.exe" /adminfile "%~dps0custom.MSP" /config "%~dps0ProPlus.WW\config.xml" >>%LOG%
rem --- intentional line break for blog post ---
"%~dps0setup.exe" /adminfile "%~dps0custom.MSP" /config "%~dps0ProPlus.WW\config.xml"
echo installation completed!
if %errorlevel%==0 (
  echo %DATE% %TIME% info: installation was successful >>%LOG%
) else (
  echo %DATE% %TIME% fail: exit code is %errorlevel% >>%LOG%
)
ENDLOCAL
exit %errorlevel%

VBScript File
Rather than using the setup.exe or direct msiexec /x options for doing the uninstall, I just crack my Indiana Jones whip on WMI and let it do the uninstall.  Only problem is that the "Uninstall()" method doesn't wait.  So I had to insert a process termination monitor (below) to watch for when "setup.exe" finishes before continuing on.

'**************************************************************** 
' Filename..: uninstall2007.vbs 
' Author....: David M. Stein 
' Date......: 03/16/2011 
' Purpose...: uninstall office professional 2007 
'**************************************************************** 
Dim query, objWMI, colSoftwareComponents, objSoftwareComponent  
Const strComputer = "."  


wscript.echo LogDate & " info: searching for office professional 2007..."  
query = "Select * from Win32_Product " & _
"Where Name = 'Microsoft Office Professional Plus 2007'"  

Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")  

Set colSoftwareComponents = objWMI.ExecQuery (query)  
For each objSoftwareComponent in colSoftwareComponents
found = True
wscript.echo LogDate & " info: removing office professional 2007..."
objSoftwareComponent.Uninstall()
Next

If found = True Then
' this is where we setup a watch to wait for setup.exe to finish...
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
query = "SELECT ProcessId FROM Win32_Process WHERE Name='setup.exe'"
Set colItems = objWMIService.ExecQuery(query,,48)
For Each objItem in colItems
intProcessID = objItem.ProcessId
Next
If intProcessID <> "" Then
Set colMonitoredProcesses = objWMIService.ExecNotificationQuery _
("Select * From __InstanceDeletionEvent Within 1 Where " & _
"TargetInstance ISA 'Win32_Process'")
Do Until bTerminated = True
Set objLatestProcess = colMonitoredProcesses.NextEvent
If objLatestProcess.TargetInstance.ProcessID = intProcessID Then
bTerminated = True
End If
Loop
If bTerminated = True Then
wscript.echo LogDate & " info: office professional 2007 uninstalled" wscript.echo LogDate & " info: exit code is " & err.Number
Else
' yes, I know this condition can never be true, oh well.
wscript.echo LogDate & " warn: setup.exe process failed to terminate." End If
Else
wscript.echo LogDate & " warn: unable to obtain processID handle"
End If
Else
wscript.echo LogDate & " info: office professional 2007 was not found"
End If


'---------------------------------------------------------------- 
' comment: 
'----------------------------------------------------------------
Function LogDate()
LogDate = FormatDateTime(Now, vbShortDate) & " " & _
FormatDateTime(Now, vbLongTime) 
End Function


So when you call the .CMD script, it launches the .VBS script and checks for Office 2007 and (if found) uninstalls it, then returns to the .CMD script process to finish installing Office 2010.  So far, so good.  I hope this helps someone else out there.

No comments: