Introduction
Have you ever opened an Excel file and realized that some sheets are locked with a password you no longer remember? This situation is common, especially with shared templates (.xlsx, .xlsm, .xltm) used in teams.
In this guide, I’ll show you how to safely remove worksheet and workbook protection (not file-open encryption) using a simple PowerShell script. This is for your own files when the password is lost, not for bypassing encryption on someone else’s data.
Difference Between Sheet Protection and File Passwords
- Sheet/Workbook Protection
- Prevents editing, formatting, hiding/unhiding sheets.
- Can be removed by editing the internal XML structure of the Excel file.
- File-Open Passwords
- Prevents opening the file entirely.
- Uses AES-128/256 encryption in modern Excel.
- Cannot be removed with this method.
This tutorial only applies to sheet/workbook protection.
Step 1: Save the Script
Create a file named Unprotect-ExcelXml.ps1 and paste in the following code:
param(
[Parameter(Mandatory=$true)]
[ValidateScript({ Test-Path $_ -PathType Leaf })]
[string]$Path
)
# --- Prep & checks ---
$fullPath = (Resolve-Path $Path).Path
$ext = [System.IO.Path]::GetExtension($fullPath).ToLower()
if ($ext -notin @('.xlsx','.xlsm','.xltx','.xltm')) {
Write-Error "Unsupported extension '$ext'. Use on .xlsx/.xlsm/.xltx/.xltm files."
exit 1
}
# Backup
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$backupPath = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($fullPath),
([System.IO.Path]::GetFileNameWithoutExtension($fullPath) + ".backup-$timestamp$ext"))
Copy-Item -LiteralPath $fullPath -Destination $backupPath -ErrorAction Stop
Write-Host "Backup created:" -ForegroundColor Cyan
Write-Host " $backupPath`n"
# Temp workspace
$workRoot = Join-Path $env:TEMP ("excel-unprotect-" + [guid]::NewGuid().ToString())
$extractDir = Join-Path $workRoot "extracted"
$newZip = Join-Path $workRoot "new.zip"
[void](New-Item -ItemType Directory -Path $extractDir -Force)
# Load System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
# Extract (Excel files are ZIP containers)
[System.IO.Compression.ZipFile]::ExtractToDirectory($fullPath, $extractDir)
# Regex patterns to remove protection tags (handle self-closing and paired tags)
$rxSheet = '(?is)<sheetProtection\b[^>]*?/?>.*?(?:</sheetProtection>)?'
$rxBook = '(?is)<workbookProtection\b[^>]*?/?>.*?(?:</workbookProtection>)?'
# Helper to write UTF-8 *without* BOM (works on Windows PowerShell & PowerShell 7+)
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
# Track changes
$sheetHits = 0
$bookHits = 0
$changed = 0
# Target only relevant XMLs but we’ll scan all XMLs to be thorough
$xmlFiles = Get-ChildItem -Path $extractDir -Recurse -Filter *.xml
foreach ($xml in $xmlFiles) {
$content = [System.IO.File]::ReadAllText($xml.FullName, [System.Text.Encoding]::UTF8)
$before = $content
$content = [regex]::Replace($content, $rxSheet, { $script:sheetHits++ ; '' })
$content = [regex]::Replace($content, $rxBook, { $script:bookHits++ ; '' })
if ($content -ne $before) {
[System.IO.File]::WriteAllText($xml.FullName, $content, $utf8NoBom)
$changed++
}
}
Write-Host "Edits made:" -ForegroundColor Yellow
Write-Host (" Files modified: {0}" -f $changed)
Write-Host (" <sheetProtection> tags removed: {0}" -f $sheetHits)
Write-Host (" <workbookProtection> tags removed: {0}`n" -f $bookHits)
# Repack to ZIP (keeping correct root structure; CreateFromDirectory does not add a superfluous top folder)
[System.IO.Compression.ZipFile]::CreateFromDirectory($extractDir, $newZip, [System.IO.Compression.CompressionLevel]::Optimal, $false)
# Replace original with new package
# (We can just overwrite by copying the .zip bytes onto the original .xltm/.xlsx)
Copy-Item -LiteralPath $newZip -Destination $fullPath -Force
Write-Host "Done. Rewrote:" -ForegroundColor Green
Write-Host " $fullPath`n"
Write-Host "Tip: Open Excel > File > Info. It should no longer say 'Some sheets are protected' and 'Unprotect Sheet' should be inactive." -ForegroundColor DarkCyan
Step 2: Allow Script Execution
PowerShell blocks scripts by default. Run this once to allow local scripts:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Step 3: Run the Script
Navigate to the folder where your Excel file and script are saved. Then run:
.\Unprotect-ExcelXml.ps1 -Path ".\YourFile.xltm"
The script will:
- Create a backup copy.
- Remove
<sheetProtection>and<workbookProtection>tags from the file. - Save the updated file ready to open in Excel.
Step 4: Verify in Excel
- Open the updated file.
- Go to File → Info.
- You should no longer see “Some sheets are protected.”
- The Unprotect Sheet option will be greyed out. ✅
Conclusion
This method gives you back control over your own Excel files when sheet/workbook protection passwords are forgotten. Always keep a backup and use a password manager in the future to avoid losing critical access.