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