Skip to content

Commit

Permalink
Update to version 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
JankeSkanke committed Nov 24, 2022
1 parent 233afbb commit 9c3f2ee
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 127 deletions.
43 changes: 32 additions & 11 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
# Changelog
***
## 1.0 Initial release - 23.10.2022
No additional information - see Readme
# Changelog

## 1.2 - 23.11.2023

* Changed to Evergreen Url for setup.exe to avoid any issues with "scraping" the ODT download site and simplification. (Requested by [@aaronparker](https://github.com/aaronparker))
* Added cleanup action to remove temporary setup files after installation
* Added Languagepacks as an separated option. Install with parameters same way as Proofing tools. The XML files in the folder is only templates used by script to configure given language.

Example

```PowerShell
powershell.exe -executionpolicy bypass -file InstallLanguagePacks.ps1 -LanguageID nb-no -Action Install
powershell.exe -executionpolicy bypass -file InstallLanguagePacks.ps1 -LanguageID nb-no -Action Uninstall
```

***

## 1.1 - 28.10.2023
* Added support for external XML configuration.xml for M365 Apps main package, Visio and Project as an option

* Added support for external XML configuration.xml for M365 Apps main package, Visio and Project as an option
* No change for Proofing Tools

Example

Without external XML (Requires configuration.xml in the package) - Same as Version 1.0
```
Without external XML (Requires configuration.xml in the package) - Same as Version 1.0

```PowerShell
powershell.exe -executionpolicy bypass -file <installfile>.ps1
```

With external XML (Requires XML to be provided by URL) - New option in the scripts
```
With external XML (Requires XML to be provided by URL) - New option in the scripts

```PowerShell
powershell.exe -executionpolicy bypass -file <installfile>.ps1 -XMLURL "https://mydomain.com/xmlfile.xml"
```
***

***

## 1.0 Initial release - 23.10.2022

No additional information - see Readme

***
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Welcome to our contribution guide!
# Welcome to our contribution guide

Thank you for investing your time in contributing to our community project! Any contribution you make will be reflected on in here.

Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.

If you are having issues with this solution, please remember that this is a community solution free of charge. We are always looking for good proposals and ideas on how to bring this to the next level.
If you are having issues with this solution, please remember that this is a community solution free of charge. We are always looking for good proposals and ideas on how to bring this to the next level.
211 changes: 211 additions & 0 deletions LanguagePacks/InstallLanguagePacks.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
<#
.SYNOPSIS
Script to install additional languagepacks as a Win32 App
.DESCRIPTION
Script to install additional languagepacks as a Win32 App by downloading the latest office setup.exe from evergreen url
Running Setup.exe from downloaded files with provided config.xml file.
.PARAMETER LanguageID
Set the language ID in the correct formatting (like nb-no or en-us)
.PARAMETER Action
Supported actions are Install or Uninstall
.EXAMPLE
InstallLanguagePacks.ps1 -LanguageID "nb-no" -Action Install
InstallLanguagePacks.ps1 -LanguageID "nb-no" -Action Uninstall
.NOTES
Version: 1.2
Author: Jan Ketil Skanke
Creation Date: 23.11.2022
Purpose/Change: Initial script development
Author: Jan Ketil Skanke
Contributor Sandy Zeng
Contact: @JankeSkanke @sandytsang
Updated: 2022-23-11
Version history:
1.2 - (2022-23-11) Script created - Matching M365 Apps solution version
#>

#region parameters
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$LanguageID,

[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[ValidateSet("Install", "Uninstall")]
[string]$Action
)
#endregion parameters

#Region Functions
function Write-LogEntry {
param (
[parameter(Mandatory = $true, HelpMessage = "Value added to the log file.")]
[ValidateNotNullOrEmpty()]
[string]$Value,
[parameter(Mandatory = $true, HelpMessage = "Severity for the log entry. 1 for Informational, 2 for Warning and 3 for Error.")]
[ValidateNotNullOrEmpty()]
[ValidateSet("1", "2", "3")]
[string]$Severity,
[parameter(Mandatory = $false, HelpMessage = "Name of the log file that the entry will written to.")]
[ValidateNotNullOrEmpty()]
[string]$FileName = $LogFileName
)
# Determine log file location
$LogFilePath = Join-Path -Path $env:SystemRoot -ChildPath $("Temp\$FileName")

# Construct time stamp for log entry
$Time = -join @((Get-Date -Format "HH:mm:ss.fff"), " ", (Get-WmiObject -Class Win32_TimeZone | Select-Object -ExpandProperty Bias))

# Construct date for log entry
$Date = (Get-Date -Format "MM-dd-yyyy")

# Construct context for log entry
$Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)

# Construct final log entry
$LogText = "<![LOG[$($Value)]LOG]!><time=""$($Time)"" date=""$($Date)"" component=""$($LogFileName)"" context=""$($Context)"" type=""$($Severity)"" thread=""$($PID)"" file="""">"

# Add value to log file
try {
Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop
if ($Severity -eq 1) {
Write-Verbose -Message $Value
} elseif ($Severity -eq 3) {
Write-Warning -Message $Value
}
} catch [System.Exception] {
Write-Warning -Message "Unable to append log entry to $LogFileName.log file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
}
}
function Start-DownloadFile {
param(
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$URL,

[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Path,

[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Name
)
Begin {
# Construct WebClient object
$WebClient = New-Object -TypeName System.Net.WebClient
}
Process {
# Create path if it doesn't exist
if (-not(Test-Path -Path $Path)) {
New-Item -Path $Path -ItemType Directory -Force | Out-Null
}

# Start download of file
$WebClient.DownloadFile($URL, (Join-Path -Path $Path -ChildPath $Name))
}
End {
# Dispose of the WebClient object
$WebClient.Dispose()
}
}
function Invoke-XMLUpdate {
param(
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$LanguageID,

[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Filename,

[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[ValidateSet("Install", "Uninstall")]
[string]$Action
)
if ($Action -eq "Install"){
$xmlDoc = [System.Xml.XmlDocument](Get-Content $FileName)
$xmlDoc.Configuration.Add.Product.Language.ID = $LanguageID
$xmlDoc.Save($FileName);
}
else {
$xmlDoc = [System.Xml.XmlDocument](Get-Content $FileName)
$xmlDoc.Configuration.Remove.Product.Language.ID = $LanguageID
$xmlDoc.Save($FileName);
}
}
#Endregion Functions

#Region Initialisations
$LogFileName = "M365AppsSetup.log"
#Endregion Initialisations
switch -Wildcard ($Action) {
{($PSItem -match "Install")}{
$FileName = "install.xml"
}
{($PSItem -match "Uninstall")}{
$FileName = "uninstall.xml"
}
}

#Initate Install
Write-LogEntry -Value "Initiating LanguagePack $($LanguageID) $($Action) process" -Severity 1
#Attempt Cleanup of SetupFolder
if (Test-Path "$($env:SystemRoot)\Temp\OfficeSetup"){
Remove-Item -Path "$($env:SystemRoot)\Temp\OfficeSetup" -Recurse -Force -ErrorAction SilentlyContinue
}

$SetupFolder = (New-Item -ItemType "directory" -Path "$($env:SystemRoot)\Temp" -Name OfficeSetup -Force).FullName

try{
#Download latest Office Deployment Toolkit
$SetupEverGreenURL = "https://officecdn.microsoft.com/pr/wsus/setup.exe"
Write-LogEntry -Value "Attempting to download latest Office setup executable" -Severity 1
Start-DownloadFile -URL $SetupEverGreenURL -Path $SetupFolder -Name "setup.exe"

try{
#Start install preparations
$SetupFilePath = Join-Path -Path $SetupFolder -ChildPath "setup.exe"
if (-Not (Test-Path $SetupFilePath)) {
Throw "Error: Setup file not found"
}
Write-LogEntry -Value "Setup file ready at $($SetupFilePath)" -Severity 1
try{
#Prepare language pack installation or removal
$OfficeCR2Version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($SetupFilePath).FileVersion
Write-LogEntry -Value "Office C2R Setup is running version $OfficeCR2Version" -Severity 1
Invoke-XMLUpdate -LanguageID $LanguageID -Filename "$($PSScriptRoot)\$($Filename)" -Action $Action
Copy-Item "$($PSScriptRoot)\$($Filename)" $SetupFolder -Force -ErrorAction Stop
Write-LogEntry -Value "LanguagePack $($LanguageID) configuration file copied" -Severity 1
Try{
#Running office installer
Write-LogEntry -Value "Starting LanguagePack $($LanguageID) $($Action) with Win32App method" -Severity 1
$OfficeInstall = Start-Process $SetupFilePath -ArgumentList "/configure $($SetupFolder)\$($Filename)" -NoNewWindow -Wait -PassThru -ErrorAction Stop
}
catch [System.Exception]{
Write-LogEntry -Value "Error running the LanguagePack $($LanguageID) $($Action). Errormessage: $($_.Exception.Message)" -Severity 3
}
}
catch [System.Exception]{
Write-LogEntry -Value "Error preparing LanguagePack $($LanguageID) $($Action). Errormessage: $($_.Exception.Message)" -Severity 3
}
}
catch [System.Exception]{
Write-LogEntry -Value "Error finding setup.exe Possible download error. Errormessage: $($_.Exception.Message)" -Severity 3
}

}
catch [System.Exception]{
Write-LogEntry -Value "Error downloading setup.exe from evergreen url. Errormessage: $($_.Exception.Message)" -Severity 3
}
#Cleanup
if (Test-Path "$($env:SystemRoot)\Temp\OfficeSetup"){
Remove-Item -Path "$($env:SystemRoot)\Temp\OfficeSetup" -Recurse -Force -ErrorAction SilentlyContinue
}
Write-LogEntry -Value "LanguagePack $($LanguageID) $($Action) completed" -Severity 1
10 changes: 10 additions & 0 deletions LanguagePacks/install.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Configuration>
<Add OfficeClientEdition="64" Version="MatchInstalled">
<Product ID="LanguagePack">
<Language ID="" />
</Product>
</Add>
<Property Name="FORCEAPPSHUTDOWN" Value="TRUE" />
<Updates Enabled="TRUE" />
<Display Level="None" AcceptEULA="TRUE" />
</Configuration>
9 changes: 9 additions & 0 deletions LanguagePacks/uninstall.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Configuration>
<Remove>
<Product ID="LanguagePack">
<Language ID="" />
</Product>
</Remove>
<Display Level="None" AcceptEULA="TRUE" />
<Property Name="FORCEAPPSHUTDOWN" Value="TRUE" />
</Configuration>
43 changes: 21 additions & 22 deletions M365AppsWin32App/InstallM365Apps.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Script to install M365 Apps as a Win32 App
.DESCRIPTION
Script to install Office as a Win32 App during Autopilot by downloading the latest Office Deployment Toolkit
Script to install Office as a Win32 App during Autopilot by downloading the latest Office setup exe from evergreen url
Running Setup.exe from downloaded files with provided config.xml file.
.EXAMPLE
Expand All @@ -13,14 +13,15 @@
powershell.exe -executionpolicy bypass -file InstallM365Apps.ps1 -XMLURL "https://mydomain.com/xmlfile.xml"
.NOTES
Version: 1.1
Version: 1.2
Author: Jan Ketil Skanke
Contact: @JankeSkanke
Contact: @JankeSkanke
Creation Date: 01.07.2021
Updated: (2022-25-10)
Updated: (2022-23-11)
Version history:
1.0.0 - (2022-23-10) Script released
1.1.0 - (2022-25-10) Added support for External URL as parameter
1.0.0 - (2022-23-10) Script released
1.1.0 - (2022-25-10) Added support for External URL as parameter
1.2.0 - (2022-23-11) Moved from ODT download to Evergreen url for setup.exe
#>
#region parameters
[CmdletBinding()]
Expand Down Expand Up @@ -120,26 +121,20 @@ if (Test-Path "$($env:SystemRoot)\Temp\OfficeSetup") {
$SetupFolder = (New-Item -ItemType "directory" -Path "$($env:SystemRoot)\Temp" -Name OfficeSetup -Force).FullName

try {
#Download latest Office Deployment Toolkit
$ODTDownloadURL = "https://www.microsoft.com/en-us/download/confirmation.aspx?id=49117"
$WebResponseURL = ((Invoke-WebRequest -Uri $ODTDownloadURL -UseBasicParsing -ErrorAction Stop -Verbose:$false).links | Where-Object { $_.outerHTML -like "*click here to download manually*" }).href
$ODTFileName = Split-Path -Path $WebResponseURL -Leaf
$ODTFilePath = $SetupFolder
Write-LogEntry -Value "Attempting to download latest Office Deployment Toolkit executable" -Severity 1
Start-DownloadFile -URL $WebResponseURL -Path $ODTFilePath -Name $ODTFileName
#Download latest Office setup.exe
$SetupEverGreenURL = "https://officecdn.microsoft.com/pr/wsus/setup.exe"
Write-LogEntry -Value "Attempting to download latest Office setup executable" -Severity 1
Start-DownloadFile -URL $SetupEverGreenURL -Path $SetupFolder -Name "setup.exe"

try {
#Extract setup.exe from ODT Package
$ODTExecutable = (Join-Path -Path $ODTFilePath -ChildPath $ODTFileName)
$ODTExtractionPath = (Join-Path -Path $ODTFilePath -ChildPath (Get-ChildItem -Path $ODTExecutable).VersionInfo.ProductVersion)
$ODTExtractionArguments = "/quiet /extract:$($ODTExtractionPath)"
Write-LogEntry -Value "Attempting to extract the setup.exe executable from Office Deployment Toolkit" -Severity 1
Start-Process -FilePath $ODTExecutable -ArgumentList $ODTExtractionArguments -NoNewWindow -Wait -ErrorAction Stop
$SetupFilePath = ($ODTExtractionPath | Get-ChildItem | Where-Object { $_.Name -eq "setup.exe" }).FullName
#Start install preparations
$SetupFilePath = Join-Path -Path $SetupFolder -ChildPath "setup.exe"
if (-Not (Test-Path $SetupFilePath)) {
Throw "Error: Setup file not found"
}
Write-LogEntry -Value "Setup file ready at $($SetupFilePath)" -Severity 1
try {
#Prepare Office Installation
Copy-Item -Path $SetupFilePath -Destination $SetupFolder -Force -ErrorAction Stop
$OfficeCR2Version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$($SetupFolder)\setup.exe").FileVersion
Write-LogEntry -Value "Office C2R Setup is running version $OfficeCR2Version" -Severity 1

Expand Down Expand Up @@ -167,7 +162,7 @@ try {
Try {
#Running office installer
Write-LogEntry -Value "Starting M365 Apps Install with Win32App method" -Severity 1
$OfficeInstall = Start-Process "$($SetupFolder)\setup.exe" -ArgumentList "/configure $($SetupFolder)\configuration.xml" -Wait -PassThru -ErrorAction Stop
$OfficeInstall = Start-Process $SetupFilePath -ArgumentList "/configure $($SetupFolder)\configuration.xml" -Wait -PassThru -ErrorAction Stop
}
catch [System.Exception] {
Write-LogEntry -Value "Error running the M365 Apps install. Errormessage: $($_.Exception.Message)" -Severity 3
Expand All @@ -185,4 +180,8 @@ try {
catch [System.Exception] {
Write-LogEntry -Value "Error downloading Office Deployment Toolkit. Errormessage: $($_.Exception.Message)" -Severity 3
}
#Cleanup
if (Test-Path "$($env:SystemRoot)\Temp\OfficeSetup"){
Remove-Item -Path "$($env:SystemRoot)\Temp\OfficeSetup" -Recurse -Force -ErrorAction SilentlyContinue
}
Write-LogEntry -Value "M365 Apps setup completed" -Severity 1
Loading

0 comments on commit 9c3f2ee

Please sign in to comment.