So, it used to be that we would install Office using a batch script that would invoke a setup.exe, assign a specific /configure flag and manually assign a specific XML file that contained the product that we wanted to install. This was bulky. It got too bulky when we needed to install 32-bit and 64-bit versions.
TIME FOR A CHANGE!
This is when I started thinking: “wow I really hate batch. I’m really glad I’m not the one that had to write this old script. Lets PowerShell this shit!”
First I needed a template XML file to modify, So this is what that looks like:
<Configuration>
<Add OfficeClientEdition="64" Channel="Current">
<Product ID="O365BusinessRetail">
<Language ID="MatchOS" />
</Product>
</Add>
</Configuration>
This is the file that we will edit to say which product we want installing also if we want 64-bit or 32-bit.
Next, I needed to create a PowerShell script that would take a user’s input, edit the XML file accordingly and start the setup.exe with this flag. I also needed the bit-version that they wanted.
I started by defining the variables I would need for the script:
#Variables used for the installation
$bitVersion = ""
$officeProduct = ""
$pathToOffice = "\\path\to\office\folder"
$xmlFile = "OfficeXML.xml"
$pathToXMLFile = Join-Path -Path $pathToOffice -ChildPath $xmlFile
Then I created a function I would use to update the XML file. I needed two parameters, the product that they wanted installing and the bit version they wanted:
#Updates the XML file based on the input
function Update-XMLFile([string]$product, [string]$bit){
try{
#Loading the XML document
$xmlDoc = Get-Content -Path $pathToXMLFile
#Edit the document
$xmlDoc.Configuration.Add.OfficeClientEdition = $bit
$xmlDoc.Configuration.Add.Product.ID = $product
#Save the document
$xmlDoc.Save($pathToXMLFile)
}catch{
$errorMessage = $_.Exception.Message
Write-Host $errorMessage -ForegroundColor Red
Read-Host "The script encountered the above error - will now exit"
}
}
I then created another function to start the installation. This also required two parameters, the bit version and the XML file name
#Function to start the installation
function Start-Installation([string]$bit, [string]$xmlName){
try{
.\setup.exe /configure $bit\$xmlName
}catch{
$errorMessage = $_.Exception.Message
Write-Host $errorMessage
Read-Host "The script encountered the above error - will now exit"
}
}
My final function was a verification test. Since we want to only use 64-bit for future installations, I had to make sure that whoever was using the script knew this and would be competent enough to do a little bit of math:
#Function to check the user wants 32 bit
function Get-Verification(){
$output = $false
Write-Host "Are you sure you want to install 32-bit?" -ForegroundColor Red
Write-Host "All new installs should use 64-bit instead"
Write-Host "If you want to install 32-bit, complete the test below, otherwise enter the wrong answer"
$firstNumber = Get-Random -Minimum 1 -Maximum 11
$secondNumber = Get-Random -Minimum 1 -Maximum 11
$sumToCheck = $firstNumber + $secondNumber
$verificationInput = Read-Host "$($firstNumber) + $($secondNumber) = ?"
if ($verificationInput -eq $sumToCheck){
Write-Host "Fine! 32-bit will be installed..."
$output = $true
}else{
Write-Host "Finally! 64-bit will be installed"
$output = $false
}
return $output
}
Now that all my functions were defined, I could start with the actual meat of the script. This included cleaning the screen, asking the user some questions, launching the 32-bit verification is needed, updating the XML file using a switch statement and finally kicking off the installation. Heres what that looked like:
#Clear the screen
Clear-Host
#region Checking if the user wants 64 bit or 32 bit
do{
Write-Host "Do you want" -NoNewline
Write-Host " 64-bit " -NoNewline -ForegroundColor Yellow
Write-Host "or" -NoNewline
Write-Host " 32-bit " -NoNewline -ForegroundColor Green
Write-Host "? (64 or 32): " -NoNewline
$bitVersionInput = (Read-Host).ToUpper()
}while((64 ,32) -notcontains $bitVersionInput)
#endregion
#Check the user definitely wants 32 bit
if ($bitVersionInput -eq "32"){
if (Get-Verification){
$bitVersion = $bitVersionInput
}else{
$bitVersionInput = "64"
}
}
#Update the bitVersion variable
$bitVersion = $bitVersionInput
#region Asking what product to install
#Ask the user what product they want to install
Write-Host @"
Please select one product from the below list
"@
Write-Host @"
1) Business Retail
2) ProPlus Retail
"@ -ForegroundColor Cyan
Write-Host @"
3) Visio Std Volume
4) Visio Pro Volume
5) Visio Pro Retail
"@ -ForegroundColor Green
Write-Host @"
6) Project Std Volume
7) Project Pro Volume
8) Project Pro Retail
"@ -ForegroundColor Gray
Write-Host @"
C) Cancel
"@ -ForegroundColor Red
do{
$officeProductInput = (Read-Host "Enter a number").ToUpper()
}while((1,2,3,4,5,6,7,8, "C") -notcontains $officeProductInput)
#endregion
#Update the product variable
$officeProduct = $officeProductInput
#region Switch the input to see what it is and perform the required operation
switch($officeProduct){
#Business Retail
1 { Update-XMLFile -product "O365BusinessRetail" -bit $bitVersion}
#ProPlus
2 { Update-XMLFile -product "O365ProPlusRetail" -bit $bitVersion}
#Visio Std Volume
3 { Update-XMLFile -product "VisioStd2019Volume" -bit $bitVersion}
#Visio Pro Volume
4 { Update-XMLFile -product "VisioPro2019Volume" -bit $bitVersion}
#Visio Pro Retail
5 { Update-XMLFile -product "VisioPro2019Retail" -bit $bitVersion}
#Project Std Volume
6 { Update-XMLFile -product "ProjectStd2019Volume" -bit $bitVersion}
#Project Pro Volume
7 { Update-XMLFile -product "ProjectPro2019Volume" -bit $bitVersion}
#Project Pro Retail
8 { Update-XMLFile -product "ProjectPro2019Retail" -bit $bitVersion}
#Cancel
"C" {Exit}
default {Exit}
}
#endregion
#Start the installation
Write-Host "Installing..." -ForegroundColor Green
Start-Installation -bit $bitVersion -xmlName $xmlFile
Write-Host "This window can be closed"
Read-Host
Done!
If you’re wondering what the script looks like as a whole, wonder no longer:
#Variables used for the installation
$bitVersion = ""
$officeProduct = ""
$pathToOffice = "\\sandpdc\software\Office"
$xmlFile = "OfficeXML.xml"
$pathToXMLFile = Join-Path -Path $pathToOffice -ChildPath $xmlFile
#Updates the XML file based on the input
function Update-XMLFile([string]$product, [string]$bit){
try{
#Loading the XML document
$xmlDoc = Get-Content -Path $pathToXMLFile
#Edit the document
$xmlDoc.Configuration.Add.OfficeClientEdition = $bit
$xmlDoc.Configuration.Add.Product.ID = $product
#Save the document
$xmlDoc.Save($pathToXMLFile)
}catch{
$errorMessage = $_.Exception.Message
Write-Host $errorMessage -ForegroundColor Red
Read-Host "The script encountered the above error - will now exit"
}
}
#Function to start the installation
function Start-Installation([string]$bit, [string]$xmlName){
try{
.\setup.exe /configure $bit\$xmlName
}catch{
$errorMessage = $_.Exception.Message
Write-Host $errorMessage
Read-Host "The script encountered the above error - will now exit"
}
}
#Function to check the user wants 32 bit
function Get-Verification(){
$output = $false
Write-Host "Are you sure you want to install 32-bit?" -ForegroundColor Red
Write-Host "All new installs should use 64-bit instead"
Write-Host "If you want to install 32-bit, complete the test below, otherwise enter the wrong answer"
$firstNumber = Get-Random -Minimum 1 -Maximum 11
$secondNumber = Get-Random -Minimum 1 -Maximum 11
$sumToCheck = $firstNumber + $secondNumber
$verificationInput = Read-Host "$($firstNumber) + $($secondNumber) = ?"
if ($verificationInput -eq $sumToCheck){
Write-Host "Fine! 32-bit will be installed..."
$output = $true
}else{
Write-Host "Finally! 64-bit will be installed"
$output = $false
}
return $output
}
#Clear the screen
Clear-Host
#region Checking if the user wants 64 bit or 32 bit
do{
Write-Host "Do you want" -NoNewline
Write-Host " 64-bit " -NoNewline -ForegroundColor Yellow
Write-Host "or" -NoNewline
Write-Host " 32-bit " -NoNewline -ForegroundColor Green
Write-Host "? (64 or 32): " -NoNewline
$bitVersionInput = (Read-Host).ToUpper()
}while((64 ,32) -notcontains $bitVersionInput)
#endregion
#Check the user definitely wants 32 bit
if ($bitVersionInput -eq "32"){
if (Get-Verification){
$bitVersion = $bitVersionInput
}else{
$bitVersionInput = "64"
}
}
#Update the bitVersion variable
$bitVersion = $bitVersionInput
#region Asking what product to install
#Ask the user what product they want to install
Write-Host @"
Please select one product from the below list
"@
Write-Host @"
1) Business Retail
2) ProPlus Retail
"@ -ForegroundColor Cyan
Write-Host @"
3) Visio Std Volume
4) Visio Pro Volume
5) Visio Pro Retail
"@ -ForegroundColor Green
Write-Host @"
6) Project Std Volume
7) Project Pro Volume
8) Project Pro Retail
"@ -ForegroundColor Gray
Write-Host @"
C) Cancel
"@ -ForegroundColor Red
do{
$officeProductInput = (Read-Host "Enter a number").ToUpper()
}while((1,2,3,4,5,6,7,8, "C") -notcontains $officeProductInput)
#endregion
#Update the product variable
$officeProduct = $officeProductInput
#region Switch the input to see what it is and perform the required operation
switch($officeProduct){
#Business Retail
1 { Update-XMLFile -product "O365BusinessRetail" -bit $bitVersion}
#ProPlus
2 { Update-XMLFile -product "O365ProPlusRetail" -bit $bitVersion}
#Visio Std Volume
3 { Update-XMLFile -product "VisioStd2019Volume" -bit $bitVersion}
#Visio Pro Volume
4 { Update-XMLFile -product "VisioPro2019Volume" -bit $bitVersion}
#Visio Pro Retail
5 { Update-XMLFile -product "VisioPro2019Retail" -bit $bitVersion}
#Project Std Volume
6 { Update-XMLFile -product "ProjectStd2019Volume" -bit $bitVersion}
#Project Pro Volume
7 { Update-XMLFile -product "ProjectPro2019Volume" -bit $bitVersion}
#Project Pro Retail
8 { Update-XMLFile -product "ProjectPro2019Retail" -bit $bitVersion}
#Cancel
"C" {Exit}
default {Exit}
}
#endregion
#Start the installation
Write-Host "Installing..." -ForegroundColor Green
Start-Installation -bit $bitVersion -xmlName $xmlFile
Write-Host "This window can be closed"
Read-Host