Deploying Office 2016 with PowerShell Application Deployment Toolkit
This was a post that was very popular on my old wordpress site, and it’s helped many people. I figured it was worth of reposting.
Basically wrap the required offscrub.vbs (details found here) and the office installer you’d like in the PowerShell Application Deployment toolkit and you have a pretty functional script. At the time the organization I worked at had an older Skype for Business (or Lync) server, so I needed to install SfB Updates at the end of the install to make sure we could connect.
Feel free to reach out to me on Twitter or LinkedIn if you need any assistance.
Best,
Jose R. Esposito
<#
.SYNOPSIS
This script performs the installation or uninstallation of an application(s).
.DESCRIPTION
The script is provided as a template to perform an install or uninstall of an application(s).
The script either performs an "Install" deployment type or an "Uninstall" deployment type.
The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install.
The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application.
.PARAMETER DeploymentType
The type of deployment to perform. Default is: Install.
.PARAMETER DeployMode
Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive.
.PARAMETER AllowRebootPassThru
Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered.
.PARAMETER TerminalServerMode
Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers.
.PARAMETER DisableLogging
Disables logging to file for the script. Default is: $false.
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }"
.EXAMPLE
Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent"
.NOTES
Toolkit Exit Code Ranges:
60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1
69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1
70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$false)]
[ValidateSet('Install','Uninstall')]
[string]$DeploymentType = 'Install',
[Parameter(Mandatory=$false)]
[ValidateSet('Interactive','Silent','NonInteractive')]
[string]$DeployMode = 'Interactive',
[Parameter(Mandatory=$false)]
[switch]$AllowRebootPassThru = $false,
[Parameter(Mandatory=$false)]
[switch]$TerminalServerMode = $false,
[Parameter(Mandatory=$false)]
[switch]$DisableLogging = $false
)
Try {
## Set the script execution policy for this process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' } Catch {}
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
## Variables: Application
[string]$appVendor = 'Microsoft'
[string]$appName = 'Office'
[string]$appVersion = '2016'
[string]$appArch = 'x86'
[string]$appLang = 'EN'
[string]$appRevision = '15.0.4551.1011'
[string]$appScriptVersion = '2.0.1'
[string]$appScriptDate = '01/13/2016'
[string]$appScriptAuthor = 'JRE'
##*===============================================
## Variables: Install Titles (Only set here to override defaults set by the toolkit)
[string]$installName = ''
[string]$installTitle = ''
##* Do not modify section below
#region DoNotModify
## Variables: Exit Code
[int32]$mainExitCode = 0
## Variables: Script
[string]$deployAppScriptFriendlyName = 'Deploy Application'
[version]$deployAppScriptVersion = [version]'3.6.8'
[string]$deployAppScriptDate = '02/06/2016'
[hashtable]$deployAppScriptParameters = $psBoundParameters
## Variables: Environment
If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation } Else { $InvocationInfo = $MyInvocation }
[string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent
## Dot source the required App Deploy Toolkit Functions
Try {
[string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1"
If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." }
If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging } Else { . $moduleAppDeployToolkitMain }
}
Catch {
If ($mainExitCode -eq 0){ [int32]$mainExitCode = 60008 }
Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue'
## Exit the script, returning the exit code to SCCM
If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit } Else { Exit $mainExitCode }
}
#endregion
##* Do not modify section above
#*===============================================
# Variables Powershell specific
# Office Directory
$dirOffice = Join-Path "$envProgramFilesX86" "Microsoft Office"
$appdatauser = $LoggedOnUserSessions | select -ExpandProperty UserName
#*====================================================
##*===============================================
##* END VARIABLE DECLARATION
##*===============================================
If ($deploymentType -ine 'Uninstall') {
##*===============================================
##* PRE-INSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Installation'
## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
Show-InstallationWelcome -CloseApps "iexplore,PWConsole,excel,groove,infopath,onenote,outlook,mspub,powerpnt,winword,communicator,skype,lync" -BlockExecution -CheckDiskSpace -PersistPrompt -CloseAppsCountdown 1
# Display Pre-Install cleanup status
Show-InstallationProgress "Installing Office 2016.Performing Pre-Install cleanup. This may take some time. Please wait..."
# Remove any previous version of Office (if required)
$officeExecutables = @("excel.exe", "groove.exe", "onenote.exe", "infopath.exe", "onenote.exe", "outlook.exe", "mspub.exe", "powerpnt.exe", "winword.exe", "winproj.exe")
ForEach ($officeExecutable in $officeExecutables) {
If (Test-Path (Join-Path $dirOffice "Office12\$officeExecutable")) {
Write-Log "Microsoft Office 2007 was detected. Will be uninstalled."
Execute-Process -FilePath "CScript.Exe" -Arguments "`"$dirSupportFiles\OffScrub07.vbs`" STANDARD,PROPLUS,PROOFKIT /S /Q /NoCancel" -WindowStyle Hidden -IgnoreExitCodes "1,2,3"
Break
}
}
ForEach ($officeExecutable in $officeExecutables) {
If (Test-Path (Join-Path $dirOffice "Office14\$officeExecutable")) {
Write-Log "Microsoft Office 2010 was detected. Will be uninstalled."
Execute-Process -FilePath "CScript.Exe" -Arguments "`"$dirSupportFiles\OffScrub10.vbs`" STANDARD,PROPLUS,PROOFKIT /S /Q /NoCancel" -WindowStyle Hidden -IgnoreExitCodes "1,2,3"
Break
}
}
ForEach ($officeExecutable in $officeExecutables) {
If (Test-Path (Join-Path $dirOffice "Office15\$officeExecutable")) {
Write-Log "Microsoft Office 2013 was detected. Will be uninstalled."
Execute-Process -FilePath "CScript.Exe" -Arguments "`"$dirSupportFiles\OffScrub13.vbs`" STANDARD,PROPLUS,PROOFKIT /S /Q /NoCancel" -WindowStyle Hidden -IgnoreExitCodes "1,2,3"
Break
}
}
#taskkill communicator, in case it's running
Write-Log -Message "Running.. taskkill /f /im communicator.exe /t"
taskkill /f /im communicator.exe /t
#taskkill communicator, in case it's running
Write-Log -Message "Running.. taskkill /f /im ucmapi.exe /t"
taskkill /f /im ucmapi.exe /t
#taskkill MSIEXEC, in case it's running
Write-Log -Message "Running.. taskkill /f /im MSIEXEC.exe /t"
taskkill /f /im MSIExec.exe /t
# Remove Microsoft Microsoft Save as PDF or XPS Add-in
Write-Log -Message "Remove-MSIApplications running uninstall of 2007 XPS and PDF addin"
Remove-MSIApplications "Microsoft Save as PDF or XPS Add-in"
# Remove Microsoft Office File Validation Add-In
Write-Log -Message "Remove-MSIApplications running uninstall of Microsoft Office File Validation Add-In"
Remove-MSIApplications "Microsoft Office File Validation Add-In"
# Remove Microsoft Guide to The Ribbion
Remove-MSIApplications -name 'Microsoft Guide to the Ribbon'
# Remove Microsoft Office 2007 Help Tab
Remove-MSIApplications -name 'Microsoft Office 2007 Help Tab'
# Remove Microsoft Conferencing Add-in for Microsoft Office Outlook
Remove-MSIApplications -name 'Microsoft Conferencing Add-in for Microsoft Office Outlook'
# Remove Microsoft Office Live Meeting 2007
Remove-MSIApplications -name 'Microsoft Office Live Meeting 2007'
# Remove Microsoft Office 2010 Interactive Guide
Remove-MSIApplications -name 'Microsoft Office 2010 Interactive Guide'
# Remove Microsoft Office 2010 User Resources
Remove-MSIApplications -name 'Office 2010 User Resources'
# Remove Microsoft Office Communicator 2007
Remove-MSIApplications -name 'Microsoft Office Communicator 2007'
# Remove Microsoft Lync
Write-Log -Message "Remove-MSIApplications running uninstall of SharePoint Designer"
Remove-MSIApplications -name 'Sharepoint Designer'
# Remove Microsoft Lync
Write-Log -Message "Remove-MSIApplications running uninstall of Office 32-bit compenets"
Remove-MSIApplications -name 'Office 32-bit'
# Remove Microsoft Lync
Write-Log -Message "Remove-MSIApplications running uninstall of Lync"
Remove-MSIApplications -name 'Lync'
#Remove old addressbook
Write-Log -Message "Remove Communicator Folder in app data"
Remove-Folder "C:\Users\$appdatauser\AppData\Local\Microsoft\Communicator"
#Remove Conversation History Lync 2010
Remove-File -Path "C:\Program Files\Microsoft Lync\ocoffice.dll"
Remove-file -Path "C:\Program Files (x86)\Microsoft Lync\ocoffice.dll"
Remove-File -path "C:\Users\$appdatauser\AppData\Local\Microsoft\outlook\extend.dat"
##*===============================================
##* INSTALLATION
##*===============================================
[string]$installPhase = 'Installation'
## Handle Zero-Config MSI Installations
If ($useDefaultMsi) {
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
}
## <Perform Installation tasks here>
# Installing Office 2016 Pro Plus
Show-InstallationProgress "Installing Microsoft Office 2016. This may take some time. Please wait..."
Execute-Process -FilePath "$dirFiles\Office2016\setup.exe" -Arguments " /adminfile `"$dirFiles\Office2016\1.MSP`"" -WindowStyle Hidden -IgnoreExitCodes "3010,1073807364" -ContinueOnError $true -WaitForMsiExec
##*===============================================
##* POST-INSTALLATION
##*===============================================
[string]$installPhase = 'Post-Installation'
#Install Office 2013 Proofing Tools with all languages
#Show-InstallationProgress "Installing Office Proofing Tools. This may take some time. Please wait..."
#Execute-Process -FilePath "$dirFiles\ProofingTools\setup.exe" -Arguments " /config `"$dirFiles\ProofingTools\W7_MSOffice2013_ProfingTools_config.xml`"" -WindowStyle Hidden -IgnoreExitCodes "3010"
#Create Startup Shortcut for Skype for Business
New-Shortcut -Path "$envProgramData\Microsoft\Windows\Start Menu\Programs\Startup\Skype For Business.lnk" -TargetPath "$envProgramFilesX86\Microsoft Office\Office16\Lync.exe" -IconLocation "$envProgramFilesX86\Microsoft Office\Office16\Lync.exe" -Description 'Skype For Business' -WorkingDirectory "$envHomeDrive\$envHomePath"
#Upgrade Symantec Vault Plugin
Write-Log -Message "Installing Symantec Vault 11.0.1.3683"
Execute-MSI -Action 'Install' -Path "$dirFiles\1.msi" -Parameters "REBOOT=ReallySurpress /QN"
#Intall SFB Updates - Dec,Jan,Feb
Write-Log -Message "Install SFB updates"
Write-Log -Message "Install SFB update-Dec"
Write-Log -Message "NOV"
Execute-Process -Path 'C:\office2016\files\MSUpdates\NOV-lync2016-kb3085634-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "DEC"
Execute-Process -Path 'C:\office2016\files\MSUpdates\DEC-lync2016-kb3114372-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "JAN"
Execute-Process -Path 'C:\office2016\files\MSUpdates\JAN-lync2016-kb3114516-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "FEB"
Execute-Process -Path 'C:\office2016\files\MSUpdates\FEB-lync2016-kb3114696-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "MAR"
Execute-Process -Path 'C:\office2016\files\MSUpdates\MAR-lync2016-kb3114846-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "APR"
Execute-Process -Path 'C:\office2016\files\MSUpdates\APR-lync2016-kb3114960-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "JUN"
Execute-Process -Path 'C:\office2016\files\MSUpdates\JUN-lync2016-kb3115087-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Write-Log -Message "JULY"
Execute-Process -Path 'C:\office2016\files\MSUpdates\JUL-lync2016-kb3115268-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
#Installing Office Updates
Write-Log -Message "Install Office Updates"
Execute-Process -Path 'C:\office2016\files\MSUpdates\access2016-kb3114379-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\excel2016-kb3114374-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\chart2016-kb3114385-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\msodll40ui2016-kb3114391-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\msodll202016-kb3114390-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\oart2016-kb3114370-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\ospp2016-kb2920724-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\msodll302016-kb3114971-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\csi2016-kb3114968-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\osfclient2016-kb3114965-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\oart2016-kb3114958-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\excel2016-kb3114964-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\chart2016-kb3114859-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\fonts2016-kb3114903-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\msodll99l2016-kb3114854-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\msodll40ui2016-kb3114712-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\policytips2016-kb3114694-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\mso2016-kb3114970-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\msodll202016-kb3114535-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\exppdf2016-kb2920720-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\powerpoint2016-kb3114961-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\word2016-kb3114969-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Execute-Process -Path 'C:\office2016\files\MSUpdates\outlook2016-kb3114972-fullfile-x86-glb.exe' -Parameters '/quiet /norestart /log "C:\windows\logs\software' -IgnoreExitCodes "3010,1073741205,17025"
Show-InstallationRestartPrompt -Countdownseconds 1
If ($deploymentType -ieq 'Uninstall')
{
##*===============================================
##* PRE-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Uninstallation'
## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing
Show-InstallationWelcome -CloseApps 'iexplore' -CloseAppsCountdown 60
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Uninstallation tasks here>
##*===============================================
##* UNINSTALLATION
##*===============================================
[string]$installPhase = 'Uninstallation'
## Handle Zero-Config MSI Uninstallations
If ($useDefaultMsi) {
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Uninstallation tasks here>
##*===============================================
##* POST-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Post-Uninstallation'
## <Perform Post-Uninstallation tasks here>
}
#*===============================================
#* END SCRIPT BODY
} } Catch {$exceptionMessage = "$($_.Exception.Message) `($($_.ScriptStackTrace)`)"; Write-Log "$exceptionMessage"; Show-DialogBox -Text $exceptionMessage -Icon "Stop"; Exit-Script -ExitCode 1} # Catch any errors in this script
Exit-Script -ExitCode 0 # Otherwise call the Exit-Script function to perform final cleanup operations
#*===============================================