Skip to content
English
  • There are no suggestions because the search field is empty.

Clean Microsoft Office Installation

A script to remove Office and all the language packs and then reinstall with just the GB language option.

You will need to download and extract the setup.exe file from the Office Deployment Tool and keep it on the path specified within the script.

Download the Office Deployment Tool

<#
    Reset-Office-EnGb.ps1
    ----------------------
    - Removes preinstalled Office / Office stub apps (Store / provisioned).
    - Uses Office Deployment Tool (ODT) to:
        * Uninstall ALL Click-to-Run Office products (all languages).
        * Install Microsoft 365 Apps (including OneNote) with en-gb only.

    REQUIREMENTS
    ------------
    - Run as Administrator.
    - Office Deployment Tool setup.exe must be in the SAME folder as this script.
      Example: C:\ODT\setup.exe and C:\ODT\Reset-Office-EnGb.ps1

    RESULT
    ------
    - No old Office / OneNote.
    - Fresh Microsoft 365 Apps (O365ProPlusRetail) with only en-gb language.
    - User signs into Office with their Microsoft 365 account to activate.
#>

# -----------------------------
# Helper functions
# -----------------------------
function Write-Info($msg)  { Write-Host "[INFO]  $msg" -ForegroundColor Cyan }
function Write-Warn($msg)  { Write-Host "[WARN]  $msg" -ForegroundColor Yellow }
function Write-Err($msg)   { Write-Host "[ERROR] $msg" -ForegroundColor Red }

function Test-IsAdmin {
    $identity  = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)
    return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

# -----------------------------
# Check admin
# -----------------------------
Write-Host ""
Write-Host "=== Reset Office to Microsoft 365 Apps (en-gb only) ===" -ForegroundColor Green
Write-Host ""

if (-not (Test-IsAdmin)) {
    Write-Err "This script must be run as Administrator. Right-click PowerShell and choose 'Run as administrator'."
    exit 1
}

# -----------------------------
# Locate ODT setup.exe
# -----------------------------
$ScriptDir    = Split-Path -Parent $MyInvocation.MyCommand.Path
$OdtSetupPath = Join-Path $ScriptDir "setup.exe"

if (-not (Test-Path $OdtSetupPath)) {
    Write-Err "Office Deployment Tool setup.exe not found in script folder: $ScriptDir"
    Write-Host "Download the Office Deployment Tool from Microsoft and extract it so that 'setup.exe' is in the same folder as this script." -ForegroundColor White
    exit 1
}

Write-Info "Using ODT setup.exe at: $OdtSetupPath"

# Temp XML folders/files
$WorkDir     = Join-Path $ScriptDir "ODT-Temp"
$RemoveXml   = Join-Path $WorkDir "RemoveAll.xml"
$InstallXml  = Join-Path $WorkDir "Install-EnGb.xml"

if (-not (Test-Path $WorkDir)) {
    New-Item -ItemType Directory -Path $WorkDir | Out-Null
}

# -----------------------------
# Remove Microsoft Store Office / OneNote stub
# -----------------------------
Write-Host ""
Write-Host "Step 1/3: Removing preinstalled Office / OneNote Store apps (if present)..." -ForegroundColor Green

try {
    # Remove provisioned packages so NEW profiles don't get Office stub
    $provPkgs = Get-AppxProvisionedPackage -Online | Where-Object {
        $_.DisplayName -like "*Microsoft.Office.Desktop*" -or
        $_.DisplayName -like "*Microsoft.Office.OneNote*" -or
        $_.DisplayName -like "*OfficeHub*" -or
        $_.DisplayName -like "*Microsoft.MicrosoftOfficeHub*"
    }

    foreach ($pkg in $provPkgs) {
        Write-Info "Removing provisioned package: $($pkg.DisplayName)"
        Remove-AppxProvisionedPackage -Online -PackageName $pkg.PackageName | Out-Null
    }

    # Remove installed appx packages for all users
    $appxPkgs = Get-AppxPackage -AllUsers | Where-Object {
        $_.Name -like "Microsoft.Office.Desktop*" -or
        $_.Name -like "Microsoft.Office.OneNote*" -or
        $_.Name -like "Microsoft.MicrosoftOfficeHub*"
    }

    foreach ($pkg in $appxPkgs) {
        Write-Info "Removing installed appx: $($pkg.Name) for all users"
        Remove-AppxPackage -Package $pkg.PackageFullName -AllUsers -ErrorAction SilentlyContinue
    }

    Write-Info "Store-based Office / OneNote stubs removed (if any were present)."
}
catch {
    Write-Warn "Error while removing Store-based Office/OneNote: $($_.Exception.Message)"
}

# -----------------------------
# Helper: run ODT with generated XML
# -----------------------------
function Invoke-ODTConfig {
    param(
        [Parameter(Mandatory = $true)][string] $XmlPath,
        [Parameter(Mandatory = $true)][string] $Description
    )

    Write-Host ""
    Write-Host ">>> Running ODT for: $Description" -ForegroundColor Green
    Write-Info "Config file: $XmlPath"
    Write-Host ""

    $arguments = "/configure `"$XmlPath`""

    try {
        $proc = Start-Process -FilePath $OdtSetupPath -ArgumentList $arguments -Wait -PassThru -WindowStyle Normal
        $code = $proc.ExitCode
        Write-Info "ODT finished '$Description' with exit code: $code"

        if ($code -ne 0) {
            Write-Warn "ODT reported a non-zero exit code for '$Description'. Check Office logs if something looks wrong."
        }
    }
    catch {
        Write-Err "Failed to start ODT for '$Description': $($_.Exception.Message)"
    }
}

# -----------------------------
# Build RemoveAll.xml
# -----------------------------
Write-Host ""
Write-Host "Step 2/3: Removing ALL existing Click-to-Run Office products..." -ForegroundColor Green

$removeXmlContent = @"
<Configuration>
  <Remove All="TRUE" />
  <Display Level="None" AcceptEULA="TRUE" />
</Configuration>
"@

try {
    $removeXmlContent | Out-File -FilePath $RemoveXml -Encoding UTF8 -Force
    Write-Info "Created removal config: $RemoveXml"
}
catch {
    Write-Err "Failed to create removal XML: $($_.Exception.Message)"
    exit 1
}

Invoke-ODTConfig -XmlPath $RemoveXml -Description "Remove ALL Office Click-to-Run products"

# -----------------------------
# Build Install-EnGb.xml
# -----------------------------
Write-Host ""
Write-Host "Step 3/3: Installing Microsoft 365 Apps (incl. OneNote) with en-gb only..." -ForegroundColor Green
Write-Host "(Defaulting to 64-bit and Current channel; adjust in XML if you need different settings.)" -ForegroundColor Yellow

$installXmlContent = @"
<Configuration>
  <Add OfficeClientEdition="64" Channel="Current">
    <Product ID="O365ProPlusRetail">
      <Language ID="en-gb" />
    </Product>
  </Add>
  <Display Level="None" AcceptEULA="TRUE" />
</Configuration>
"@

# NOTE:
# - 'O365ProPlusRetail' is Microsoft 365 Apps for enterprise.
#   If you specifically use Business plans only, you could change this to 'O365BusinessRetail'.

try {
    $installXmlContent | Out-File -FilePath $InstallXml -Encoding UTF8 -Force
    Write-Info "Created install config: $InstallXml"
}
catch {
    Write-Err "Failed to create install XML: $($_.Exception.Message)"
    exit 1
}

Invoke-ODTConfig -XmlPath $InstallXml -Description "Install Microsoft 365 Apps (O365ProPlusRetail) en-gb only"

# -----------------------------
# Cleanup
# -----------------------------
Write-Host ""
Write-Host "Cleaning up temporary files..." -ForegroundColor Green
try {
    if (Test-Path $RemoveXml)  { Remove-Item $RemoveXml  -Force }
    if (Test-Path $InstallXml) { Remove-Item $InstallXml -Force }
    # Leave $WorkDir in place in case you want to inspect logs later
}
catch {
    Write-Warn "Could not delete some temporary files: $($_.Exception.Message)"
}

Write-Host ""
Write-Host "============================================================" -ForegroundColor Green
Write-Host " Completed." -ForegroundColor Green
Write-Host ""
Write-Host " Office / OneNote should now be a clean Microsoft 365 Apps" -ForegroundColor Green
Write-Host " installation with ONLY the en-gb language installed." -ForegroundColor Green
Write-Host ""
Write-Host " When you first open an Office app, sign in with the user's" -ForegroundColor Green
Write-Host " Microsoft 365 account to activate the license." -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Green
Write-Host ""