NTS.Tools.Application.psm1
function Install-M365Apps { # https://github.com/mallockey/Install-Office365Suite/blob/master/Install-Office365Suite.ps1 [CmdletBinding(DefaultParameterSetName = 'XMLFile')] param( [Parameter(Mandatory = $true, ParameterSetName = "XMLFile")] [string] $ConfigXMLPath, [Parameter(Mandatory = $false)] [string] $WorkingDir = "$($env:ProgramData)\NTS\Office", [Parameter(Mandatory = $false)] [switch] $CleanUpInstallFiles, [Parameter(Mandatory = $false, ParameterSetName = "DefaultXML")] [switch] $UseDefaultConfigXML, [Parameter(Mandatory = $false, ParameterSetName = "SilentDefaultXML")] [switch] $UseSilentDefaultConfigXML ) $ErrorActionPreference = "Stop" # check admin access $CurrentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) if (!($CurrentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { Write-Warning "$($env:COMPUTERNAME): Script is not running as Administrator" Write-Warning "$($env:COMPUTERNAME): Please rerun this script as Administrator" exit } if (!(Test-Path $WorkingDir)) { New-Item -Path $WorkingDir -ItemType Directory | Out-Null } if ($UseDefaultConfigXML) { New-M365AppsXML -ConfigXMLPath $WorkingDir -ConfigXMLFileName "config.xml" -IncludeApps "Outlook", "Word", "Excel", "Teams" $ConfigXMLPath = "$($WorkingDir)\config.xml" } elseif ($UseSilentDefaultConfigXML) { New-M365AppsXML -ConfigXMLPath $WorkingDir -ConfigXMLFileName "config.xml" -IncludeApps "Outlook", "Word", "Excel", "Teams" -DisplayLevel None $ConfigXMLPath = "$($WorkingDir)\config.xml" } # verify config xml Test-OfficeConfiguration -ConfigurationXMLFilePath $ConfigXMLPath # Get Setup.exe Get-M365AppsSetup -OutPath $WorkingDir -FileName "Setup.exe" # Run the O365 install Write-Output "$($env:COMPUTERNAME): Start Installation of Microsoft 365 Apps" $Process = Start-Process "$($WorkingDir)\Setup.exe" -ArgumentList "/configure `"$ConfigXMLPath`"" -Wait -PassThru -WindowStyle Hidden if ($Process.ExitCode -ne 0) { throw "there was an error installing office - $($PSItem.Exception.Message)" } #Check if Office 365 suite was installed correctly. $RegLocations = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" ) $OfficeInstalled = $False foreach ($Key in (Get-ChildItem $RegLocations) ) { if ($Key.GetValue('DisplayName') -like '*Microsoft 365*') { $OfficeVersionInstalled = $Key.GetValue('DisplayName') $OfficeInstalled = $True } } if ($OfficeInstalled) { Write-Output "$($env:COMPUTERNAME): $($OfficeVersionInstalled) installed successfully!" } else { Write-Warning "$($env:COMPUTERNAME): Microsoft 365 was not detected after the install ran" } if ($CleanUpInstallFiles) { Start-FolderCleanUp -FolderToRemove $WorkingDir } } function New-M365AppsXML { # https://github.com/mallockey/Install-Office365Suite/blob/master/InstallOffice.psm1 [CmdletBinding(DefaultParameterSetName = 'ExcludeApps')] param( [Parameter(Mandatory = $false)] [string] $ConfigXMLPath = "$($env:ProgramData)\NTS\Office\", [Parameter(Mandatory = $false)] [string] $ConfigXMLFileName = "config.xml", [Parameter(Mandatory = $false)] [ValidateSet('O365ProPlusRetail', 'O365BusinessRetail')] [string] $OfficeEdition = 'O365ProPlusRetail', [Parameter(Mandatory = $false, ParameterSetName = "ExcludeApps")] [ValidateSet( 'Groove', 'Outlook', 'OneNote', 'Access', 'OneDrive', 'Publisher', 'Word', 'Excel', 'PowerPoint', 'Teams', 'Lync' )] [Array] $ExcludeApps, [Parameter(Mandatory = $false, ParameterSetName = "IncludeApps")] [ValidateSet( 'Groove', 'Outlook', 'OneNote', 'Access', 'OneDrive', 'Publisher', 'Word', 'Excel', 'PowerPoint', 'Teams', 'Lync' )] [Array] $IncludeApps, [Parameter(Mandatory = $false)] [Array] $LanguageIDs, [Parameter(Mandatory = $false)] [ValidateSet("None", "Full")] [string] $DisplayLevel = "Full", [Parameter(Mandatory = $false)] [ValidateSet('64', '32')] [string] $OfficeArch = '64', [Parameter(Mandatory = $false)] [ValidateSet("TRUE", "FALSE")] [string] $AcceptEULA = "TRUE", [Parameter(Mandatory = $false)] [ValidateSet("TRUE", "FALSE")] [string] $EnableUpdates = "TRUE", [Parameter(Mandatory = $false)] [ValidateSet('SemiAnnualPreview', 'SemiAnnual', 'MonthlyEnterprise', 'CurrentPreview', 'Current')] [string] $Channel = 'Current', [Parameter(Mandatory = $false)] [Switch] $IncludeProject, [Parameter(Mandatory = $false)] [Switch] $IncludeVisio, [Parameter(Mandatory = $false)] [ValidateSet(0, 1)] [string] $SharedComputerLicensing = '0', [Parameter(Mandatory = $false)] [bool] $RemoveMSI = $true, [Parameter(Mandatory = $false)] [bool] $SetFileFormat = $true ) $ErrorActionPreference = 'Stop' $ValidApps = ( 'Groove', 'Outlook', 'OneNote', 'Access', 'OneDrive', 'Publisher', 'Word', 'Excel', 'PowerPoint', 'Teams', 'Lync' ) if ($ExcludeApps -and $IncludeApps) { throw "you can use 'ExcludeApps' or 'IncludeApps' not both" } elseif ($ExcludeApps) { $ExcludeApps | ForEach-Object { $ExcludeAppsString += "<ExcludeApp ID =`"$_`" />" } } elseif ($IncludeApps) { $ValidApps | Where-Object { $PSItem -notin $IncludeApps } | ForEach-Object { $ExcludeAppsString += "<ExcludeApp ID =`"$_`" />" } } if ($LanguageIDs) { $LanguageIDs | ForEach-Object { $LanguageString += "<Language ID =`"$_`" />" } } else { $LanguageString = "<Language ID=`"MatchOS`" />" } if ($OfficeArch) { $OfficeArchString = "`"$OfficeArch`"" } if ($RemoveMSI) { $RemoveMSIString = '<RemoveMSI />' } else { $RemoveMSIString = $Null } if ($SetFileFormat) { $AppSettingsString = '<AppSettings> <User Key="software\microsoft\office\16.0\excel\options" Name="defaultformat" Value="51" Type="REG_DWORD" App="excel16" Id="L_SaveExcelfilesas" /> <User Key="software\microsoft\office\16.0\powerpoint\options" Name="defaultformat" Value="27" Type="REG_DWORD" App="ppt16" Id="L_SavePowerPointfilesas" /> <User Key="software\microsoft\office\16.0\word\options" Name="defaultformat" Value="" Type="REG_SZ" App="word16" Id="L_SaveWordfilesas" /> </AppSettings>' } else { $AppSettingsString = $Null } if ($Channel) { $ChannelString = "Channel=`"$Channel`"" } else { $ChannelString = $Null } if ($IncludeProject) { $ProjectString = "<Product ID=`"ProjectProRetail`"`>$ExcludeAppsString $LanguageString</Product>" } else { $ProjectString = $Null } if ($IncludeVisio) { $VisioString = "<Product ID=`"VisioProRetail`"`>$ExcludeAppsString $LanguageString</Product>" } else { $VisioString = $Null } $OfficeXML = [XML]@" <Configuration> <Add OfficeClientEdition=$($OfficeArchString) $($ChannelString) $($SourcePathString) > <Product ID="$($OfficeEdition)"> $($LanguageString) $($ExcludeAppsString) </Product> $($ProjectString) $($VisioString) </Add> <Property Name="SharedComputerLicensing" Value="$($SharedComputerlicensing)" /> <Display Level="$($DisplayLevel)" AcceptEULA="$($AcceptEULA)" /> <Updates Enabled="$($EnableUpdates)" /> $($AppSettingsString) $($RemoveMSIString) </Configuration> "@ try { if (!(Test-Path $ConfigXMLPath)) { New-Item -Path $ConfigXMLPath -ItemType Directory | Out-Null } Write-Output "$($env:COMPUTERNAME): XML Config file will be saved to $($ConfigXMLPath)\$($ConfigXMLFileName)" $OfficeXML.Save("$($ConfigXMLPath)\$($ConfigXMLFileName)") } catch { throw "could not create config xml at $($ConfigXMLPath) - $($PSItem.Exception.Message)" } } function Get-M365AppsSetup { # https://github.com/mallockey/Install-Office365Suite/blob/master/Install-Office365Suite.ps1 [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string] $OutPath = "$($env:ProgramData)\NTS\Office\Setup", [Parameter(Mandatory = $false)] [string] $FileName = "setup.exe", [Parameter(Mandatory = $false)] [switch] $KeepODTFiles ) $ODTFolder = "$($OutPath)\ODT" $ODTSetupFilePath = "$($ODTFolder)\ODTSetup.exe" # get odt try { if (!(Test-Path $OutPath)) { New-Item -Path $OutPath -ItemType Directory | Out-Null } if (!(Test-Path $ODTFolder)) { New-Item -Path $ODTFolder -ItemType Directory | Out-Null } if (Test-Path -Path $ODTSetupFilePath) { throw "$($ODTSetupFilePath) already exits" } else { try { [String]$MSWebPage = Invoke-RestMethod "https://www.microsoft.com/en-us/download/confirmation.aspx?id=49117" $ODTDownloadURL = $MSWebPage | ForEach-Object { if ($PSItem -match 'url=(https://.*officedeploymenttool.*\.exe)') { $matches[1] } } } catch { throw "could not find odt download url - $($PSItem.Exception.Message)" } Invoke-WebRequest -Uri $ODTDownloadURL -OutFile $ODTSetupFilePath } } catch { throw "could not download ODTSetup - $($PSItem.Exception.Message)" } # get setup try { Write-Output "$($env:COMPUTERNAME): Running the Office Deployment Tool..." Start-Process -FilePath $ODTSetupFilePath -ArgumentList "/quiet /extract:`"$($ODTFolder)`"" -Wait Write-Output "$($env:COMPUTERNAME): Copy Setup.exe to $($OutPath)" Copy-Item -Path "$($ODTFolder)\setup.exe" -Destination "$($OutPath)\$($FileName)" -Force if (!($KeepODTFiles)) { Start-FolderCleanUp -FolderToRemove $ODTFolder } } catch { Write-Warning "$($env:COMPUTERNAME): Error running the Office Deployment Tool - $($PSItem.Exception.Message)" } } function Test-OfficeConfiguration { param( [Parameter(Mandatory = $true)] [String] $ConfigurationXMLFilePath ) $ErrorActionPreference = 'Stop' try { $OfficeXML = Get-Content -Path $ConfigurationXMLFilePath } catch { throw "There was an error generating the XML config file" } try { Write-Output "$($env:COMPUTERNAME): Uploading XML config file to clients.config.office.net to verify syntax" Invoke-RestMethod -Uri 'https://clients.config.office.net/intents/v1.0/DeploymentSettings/ImportConfiguration' ` -Method Post ` -Body $OfficeXML ` -ContentType 'text/xml' | Out-Null Write-Output "$($env:COMPUTERNAME): XML config file was successfully verified" } catch { throw "The XML is not formatted correctly" } } |