#
.SYNOPSIS
Interactive Microsoft Office 365 installation script with auto-elevation
.DESCRIPTION
This script provides an interactive menu to configure and install Microsoft Office 365
by automatically downloading the Office Deployment Tool and creating a configuration XML file.
It will automatically request elevation to administrator privileges if needed.
.NOTES
Author: Script User
Date: March 17, 2025
#>
# Initialize script variables with defaults at the beginning
$script:Architecture = "64"
$script:Language = "en-us"
$script:Channel = "Current"
$script:ExcludedApps = @("Groove", "OneDrive", "Access", "Lync", "OneNote", "Publisher")
$script:TempDir = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "Office365_Install_$(Get-Random)")
$script:ConfigFilePath = [System.IO.Path]::Combine($script:TempDir, "config.xml")
$script:InstallerPath = [System.IO.Path]::Combine($script:TempDir, "setup.exe")
$script:ODTUrl = "https://ms365.ved.yt/ODTsetup.exe" # Office Deployment Tool
# Check if running as administrator and self-elevate if needed
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
if (-not (Test-Admin)) {
Write-Host "This script requires administrator privileges. Attempting to elevate..." -ForegroundColor Yellow
Start-Sleep -Seconds 1
# Get the path of the currently running script
$scriptPath = $MyInvocation.MyCommand.Definition
# Prepare to relaunch the script with elevated privileges
$proc = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" -Verb RunAs -PassThru
# Exit the non-elevated script
exit
}
Write-Host "Running with administrator privileges!" -ForegroundColor Green
# Create temp directory
if (-not (Test-Path -Path $script:TempDir)) {
New-Item -ItemType Directory -Path $script:TempDir -Force | Out-Null
Write-Host "Created temporary directory: $script:TempDir"
}
# Function to download Office Deployment Tool
function Get-OfficeTool {
try {
Write-Host "Downloading Office Deployment Tool from: $script:ODTUrl" -ForegroundColor Cyan
$odtSetupPath = [System.IO.Path]::Combine($script:TempDir, "setup.exe")
Invoke-WebRequest -Uri $script:ODTUrl -OutFile $odtSetupPath
if (Test-Path $odtSetupPath) {
Write-Host "Office Deployment Tool downloaded successfully." -ForegroundColor Green
return $true
} else {
Write-Host "Failed to download Office Deployment Tool" -ForegroundColor Red
return $false
}
} catch {
Write-Host "Error downloading Office Deployment Tool: $_" -ForegroundColor Red
return $false
}
}
function Show-Menu {
param (
[string]$Title = 'Office 365 Installation Configuration'
)
Clear-Host
Write-Host "================ $Title ================"
Write-Host
Write-Host "Current Configuration:"
Write-Host " 1. Architecture: $script:Architecture-bit"
Write-Host " 2. Language: $script:Language"
Write-Host " 3. Update Channel: $script:Channel"
Write-Host " 4. Excluded Apps: $($script:ExcludedApps -join ', ')"
Write-Host
Write-Host "Options:"
Write-Host " 5. Proceed with Installation"
Write-Host " 6. Exit"
Write-Host
}
function Select-Architecture {
Clear-Host
Write-Host "=== Select Office Architecture ==="
Write-Host " 1. 32-bit"
Write-Host " 2. 64-bit"
$selection = Read-Host "Enter your choice (1-2)"
switch ($selection) {
"1" { $script:Architecture = "32" }
"2" { $script:Architecture = "64" }
default { Write-Host "Invalid selection, keeping current setting." -ForegroundColor Yellow }
}
}
function Select-Language {
Clear-Host
Write-Host "=== Select Office Language ==="
Write-Host " 1. English (US) - en-us"
Write-Host " 2. English (UK) - en-gb"
Write-Host " 3. French - fr-fr"
Write-Host " 4. German - de-de"
Write-Host " 5. Spanish - es-es"
Write-Host " 6. Custom"
$selection = Read-Host "Enter your choice (1-6)"
switch ($selection) {
"1" { $script:Language = "en-us" }
"2" { $script:Language = "en-gb" }
"3" { $script:Language = "fr-fr" }
"4" { $script:Language = "de-de" }
"5" { $script:Language = "es-es" }
"6" {
$customLang = Read-Host "Enter language code (e.g., ja-jp)"
if ($customLang -match "^[a-z]{2}-[a-z]{2}$") {
$script:Language = $customLang
}
else {
Write-Host "Invalid language code format, keeping current setting." -ForegroundColor Yellow
}
}
default { Write-Host "Invalid selection, keeping current setting." -ForegroundColor Yellow }
}
}
function Select-Channel {
Clear-Host
Write-Host "=== Select Office Update Channel ==="
Write-Host " 1. Current (Monthly updates with latest features)"
Write-Host " 2. MonthlyEnterprise (Monthly updates with security fixes only)"
Write-Host " 3. SemiAnnual (Updates every six months)"
Write-Host " 4. SemiAnnualPreview (Preview of semi-annual features)"
$selection = Read-Host "Enter your choice (1-4)"
switch ($selection) {
"1" { $script:Channel = "Current" }
"2" { $script:Channel = "MonthlyEnterprise" }
"3" { $script:Channel = "SemiAnnual" }
"4" { $script:Channel = "SemiAnnualPreview" }
default { Write-Host "Invalid selection, keeping current setting." -ForegroundColor Yellow }
}
}
function Manage-ExcludedApps {
$appOptions = @{
"1" = "Access"
"2" = "Excel"
"3" = "Groove"
"4" = "Lync"
"5" = "OneDrive"
"6" = "OneNote"
"7" = "Outlook"
"8" = "PowerPoint"
"9" = "Publisher"
"10" = "Teams"
"11" = "Word"
}
$done = $false
while (-not $done) {
Clear-Host
Write-Host "=== Manage Excluded Apps ==="
Write-Host "Current exclusions: $($script:ExcludedApps -join ', ')"
Write-Host
foreach ($key in $appOptions.Keys | Sort-Object) {
$app = $appOptions[$key]
$status = if ($script:ExcludedApps -contains $app) { "[Excluded]" } else { "[Included]" }
Write-Host " $key. $app $status"
}
Write-Host
Write-Host " 0. Done"
$selection = Read-Host "Enter number to toggle app inclusion/exclusion (0 to finish)"
if ($selection -eq "0") {
$done = $true
}
elseif ($appOptions.ContainsKey($selection)) {
$app = $appOptions[$selection]
if ($script:ExcludedApps -contains $app) {
$script:ExcludedApps = $script:ExcludedApps | Where-Object { $_ -ne $app }
Write-Host "$app will be included" -ForegroundColor Green
}
else {
$script:ExcludedApps += $app
Write-Host "$app will be excluded" -ForegroundColor Yellow
}
Start-Sleep -Seconds 1
}
else {
Write-Host "Invalid selection" -ForegroundColor Red
Start-Sleep -Seconds 1
}
}
}
function Create-ConfigXML {
$excludeXml = ""
foreach ($app in $script:ExcludedApps) {
$excludeXml += " `r`n"
}
$configXml = @"
$excludeXml
"@
$configXml | Out-File -FilePath $script:ConfigFilePath -Encoding utf8
Write-Host "Configuration file created at: $script:ConfigFilePath" -ForegroundColor Green
}
# Download Office Deployment Tool
Write-Host "`nChecking for Office Deployment Tool..." -ForegroundColor Cyan
$toolResult = Get-OfficeTool
if (-not $toolResult) {
Write-Host "Failed to download Office Deployment Tool. Please check your internet connection and try again." -ForegroundColor Red
Write-Host "Alternatively, you can manually download it from: https://www.microsoft.com/en-us/download/details.aspx?id=49117" -ForegroundColor Yellow
Read-Host "Press Enter to exit"
exit 1
}
# Main menu loop
$exit = $false
while (-not $exit) {
Show-Menu
$selection = Read-Host "Please make a selection (1-6)"
switch ($selection) {
"1" { Select-Architecture }
"2" { Select-Language }
"3" { Select-Channel }
"4" { Manage-ExcludedApps }
"5" {
Create-ConfigXML
Write-Host "`nPreparing to install Office 365 with these settings:" -ForegroundColor Cyan
Write-Host " Architecture: $script:Architecture-bit"
Write-Host " Language: $script:Language"
Write-Host " Update Channel: $script:Channel"
Write-Host " Excluded Apps: $($script:ExcludedApps -join ', ')"
$confirm = Read-Host "`nProceed with installation? (Y/N)"
if ($confirm -eq "Y" -or $confirm -eq "y") {
Write-Host "`nStarting Office 365 installation. This may take several minutes..." -ForegroundColor Cyan
try {
Start-Process -FilePath $script:InstallerPath -ArgumentList "/configure `"$script:ConfigFilePath`"" -Wait
Write-Host "Microsoft Office 365 installation completed." -ForegroundColor Green
# Verify installation
$officeInstalled = $false
$regPaths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
foreach ($path in $regPaths) {
foreach ($key in (Get-ChildItem -Path $path -ErrorAction SilentlyContinue)) {
if ($key.GetValue('DisplayName') -like '*Microsoft 365*') {
$officeVersion = $key.GetValue('DisplayName')
$officeInstalled = $true
break
}
}
if ($officeInstalled) { break }
}
if ($officeInstalled) {
Write-Host "Verification successful: $officeVersion installed." -ForegroundColor Green
}
else {
Write-Host "Verification notice: Microsoft 365 installation not detected in registry. This may be normal if you selected specific components." -ForegroundColor Yellow
}
}
catch {
Write-Host "Error during installation: $_" -ForegroundColor Red
}
# Clean up temporary files
Write-Host "`nCleaning up temporary files..." -ForegroundColor Cyan
try {
Remove-Item -Path $script:TempDir -Recurse -Force
Write-Host "Temporary files removed successfully." -ForegroundColor Green
}
catch {
Write-Host "Warning: Unable to remove all temporary files: $_" -ForegroundColor Yellow
}
$exit = $true
}
}
"6" {
$exit = $true
Write-Host "Installation cancelled." -ForegroundColor Yellow
# Clean up temporary files if cancelling
if (Test-Path -Path $script:TempDir) {
Write-Host "Cleaning up temporary files..." -ForegroundColor Cyan
Remove-Item -Path $script:TempDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
default { Write-Host "Invalid selection, please try again." -ForegroundColor Red }
}
}