Enterprise · Endpoint Management

Remove All OST Files
Multi-User Outlook Cache Cleanup

When Outlook starts behaving strangely (slow sync, duplicate items, calendar glitches), a corrupted OST file is usually the culprit. This guide walks you through Remove-All-OST.ps1, a script that clears Outlook's cache for every user on a machine in one shot.

⚠ Requires Local Admin 🔄 Triggers Email Re-Sync 💻 PowerShell 5.1+
📦

What is an OST file, anyway?

Think of the OST (Offline Storage Table) file as Outlook's personal scratch pad. Every time you open Outlook, it copies your emails, calendar, and contacts from the Exchange server down to a local .ost file sitting in AppData\Local\Microsoft\Outlook\. This is what makes Outlook work even when you're offline: it's all cached right on the machine.

The problem is that this file can get large, fragmented, or outright corrupted over time. When that happens you get symptoms like: emails not syncing, calendar events disappearing, Outlook hanging on "Updating Inbox…", or the profile failing to load altogether.

The fix is straightforward: delete the OST file and let Outlook rebuild it from the server. No data is lost because everything lives in Exchange. The cache is just a local copy. This script does exactly that, but for every user profile on the machine at once instead of one at a time.

🚨

Before You Run It: Read This

This is a multi-user operation

The script targets every user profile on the machine, not just the current logged-in user. If three users share this PC, all three will need to re-download their email when they next open Outlook.

🌐
Plan for the network hit

When multiple users log back in and Outlook kicks off a full re-sync at the same time, you can get a mini "network storm." On a large shared workstation or kiosk, stagger user logins if you can, or run this during a maintenance window.

🔒
Outlook must be closed

OST files that are actively in use by Outlook cannot be deleted because Windows locks them. The script will report those as [FAILED - FILE LOCKED]. Make sure users close Outlook before you run this, or coordinate the timing so the machine is idle.

Your email is safe

The OST file is only a local cache. All your real email, calendar, and contacts live on the Exchange/Microsoft 365 server. Deleting the OST just forces Outlook to re-download a fresh copy, so nothing is permanently lost.

📄

The Script: Remove-All-OST.ps1

Here's the full script. Each block is annotated with comments so you can see exactly what it's doing at every stage, from the admin check at the top to the summary report at the bottom.

Remove-All-OST.ps1
# ==============================================================================
# SCRIPT: Remove-All-OST.ps1
# PURPOSE: Delete Outlook OST cache files for ALL user profiles on the machine.
# REQUIRES: Local Administrator Privileges
# ==============================================================================

# 1. Check for Administrator Privileges
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Warning "ERROR: This script must be run as Administrator."
    Break
}

# 2. Safety Confirmation
Write-Host "========================================================================" -ForegroundColor Cyan
Write-Host " WARNING: MULTI-USER OPERATION " -ForegroundColor Red
Write-Host "========================================================================" -ForegroundColor Cyan
Write-Host "This will delete Outlook OST cache files for ALL users on this PC."
Write-Host "- Users will need to re-download emails upon next login."
Write-Host "- Files currently in use (Outlook open) cannot be deleted."
Write-Host ""
$confirm = Read-Host "Do you want to proceed? (Y/N)"
if ($confirm -ne 'Y' -and $confirm -ne 'y') {
    Write-Host "Operation cancelled." -ForegroundColor Yellow
    Break
}

# 3. Stop Outlook for the CURRENT Admin Session
Write-Host "`nStopping Outlook for current session..." -ForegroundColor Cyan
Stop-Process -Name "OUTLOOK" -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2

# 4. Get All User Profiles from Registry
Write-Host "Scanning for user profiles..." -ForegroundColor Cyan
$ProfileListPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
$Profiles = Get-ItemProperty -Path "$ProfileListPath\*" |
    Where-Object {
        $_.ProfileImagePath -notmatch 'System|Default|Service|All Users'
    }

$TotalCount   = 0
$SuccessCount = 0
$FailCount    = 0
$SkippedCount = 0

# 5. Iterate Through Profiles
foreach ($Profile in $Profiles) {
    $UserPath = $Profile.ProfileImagePath
    $OstPath  = "$UserPath\AppData\Local\Microsoft\Outlook\*.ost"

    if (Test-Path $UserPath) {
        $Files = Get-Item -Path $OstPath -ErrorAction SilentlyContinue

        if ($Files) {
            foreach ($File in $Files) {
                $TotalCount++
                Write-Host "Processing: $($File.Name) (User: $(Split-Path $UserPath -Leaf))" -NoNewline

                try {
                    Remove-Item -Path $File.FullName -Force -ErrorAction Stop
                    Write-Host " [DELETED]" -ForegroundColor Green
                    $SuccessCount++
                }
                catch {
                    if ($_.Exception.Message -like "*used by another process*") {
                        Write-Host " [FAILED - FILE LOCKED]" -ForegroundColor Red
                    } else {
                        Write-Host " [FAILED - PERMISSION/ERROR]" -ForegroundColor Red
                    }
                    $FailCount++
                }
            }
        } else {
            $SkippedCount++
        }
    }
}

# 6. Summary Report
Write-Host "`n========================================================================" -ForegroundColor Cyan
Write-Host " OPERATION COMPLETE " -ForegroundColor Cyan
Write-Host "========================================================================" -ForegroundColor Cyan
Write-Host "Total OST Files Found   : $TotalCount"
Write-Host "Successfully Deleted    : $SuccessCount" -ForegroundColor Green
Write-Host "Failed (Locked/Error)   : $FailCount"    -ForegroundColor Red
Write-Host "Users Skipped (No OST)  : $SkippedCount"  -ForegroundColor Gray
Write-Host "========================================================================" -ForegroundColor Cyan

if ($FailCount -gt 0) {
    Write-Warning "Some files could not be deleted. Ensure Outlook is closed for those users."
}

Notice the safety confirmation prompt at the top: the script won't do anything until you type Y. This is intentional. It gives you one last chance to bail out if you ran it on the wrong machine.

How to Execute

Four steps. The only thing that can trip you up is forgetting to run PowerShell as Administrator, but the script will catch that and stop itself, so no harm done if you forget.

1
Save the script file

Copy the script above and save it as Remove-All-OST.ps1 anywhere convenient. Desktop or a tools folder works fine.

2
Open PowerShell as Administrator

Press Win + X → select Windows PowerShell (Admin) or Terminal (Admin). You must see the UAC prompt. If you don't, you're not running as admin.

3
Unblock the file (if needed)

If Windows flags it as downloaded from the internet, run this first to unblock it:

PowerShell
Unblock-File -Path "C:\Path\To\Remove-All-OST.ps1"
4
Run the script

Navigate to the folder containing the script, then execute it:

PowerShell
cd C:\Path\To\
.\Remove-All-OST.ps1

Type Y when prompted and press Enter. Watch the output: each file will show [DELETED] in green or [FAILED] in red.

🔧

Troubleshooting

🔒
FAILED: FILE LOCKED

This means Outlook is still running for that user profile. The OS won't let anything else touch the file while Outlook holds it open. You cannot force-delete a locked file without terminating the process that owns it.

What you see What it means Fix
[FAILED - FILE LOCKED] Outlook is open for that user Close Outlook for that account, then re-run the script, or use Task Manager to kill the OUTLOOK.EXE process under that user's session
[FAILED - PERMISSION/ERROR] Access denied or unexpected error Confirm you are running as a true local admin (not just a domain admin). Check if the profile folder has custom ACLs.
Users Skipped (No OST) > 0 Those profiles never had Outlook configured Not an issue. It just means those users don't use Outlook on this machine.
Script exits immediately without prompt Not running as Administrator Close and re-open PowerShell using Run as Administrator.
"Execution of scripts is disabled" PowerShell execution policy blocks the script Run: Set-ExecutionPolicy RemoteSigned -Scope Process. This only affects the current session.

One-Liner Alternative

If you just need to nuke OST files for the current user only and want to skip the full script, this one-liner does the job. Run it in an elevated PowerShell session with Outlook closed:

PowerShell (current user only)
Get-ChildItem -Path "$env:LOCALAPPDATA\Microsoft\Outlook\*.ost" -ErrorAction SilentlyContinue | Remove-Item -Force

Unlike the full script, this version has no confirmation prompt, no admin check, and no summary report. It silently deletes whatever it finds. Use the full script when you need visibility into what happened across all profiles. Use this one-liner when you're in a hurry and know exactly what you're targeting.