You've got 400 .xls files — or 4,000. Your IT manager wants them migrated to .xlsx before the next Windows upgrade. Someone on the team suggests PowerShell. It's free, it's built-in, and there are scripts on Stack Overflow. What could go wrong?
Quite a bit, actually. PowerShell can convert .xls files to .xlsx — but it does so by automating Excel's COM interface, and that process silently strips VBA macros from any workbook that contains them. For a folder of simple spreadsheets with no automation, it works fine. For a folder of production workbooks with macros, it's a disaster that won't announce itself until someone tries to run a report and nothing happens.
This guide compares the two main approaches for bulk .xls to .xlsx conversion: PowerShell automation and LegacyLeaps. We'll walk through the PowerShell approach, explain exactly where it breaks down, and show what to do instead when macros are involved.
The .xls format dates to Excel 97 and uses the BIFF8 binary structure Microsoft officially discontinued. Starting with Windows 11 24H2, Microsoft tightened security policies around legacy binary formats — some organizations have already seen Excel refuse to open .xls files from network drives under Protected View without active user intervention on every file. Our complete guide to legacy Excel migration covers the full picture of what's changing and why.
Beyond compatibility, .xlsx files are typically 25-40% smaller, open faster, and work cleanly with Power Query, Power BI, and SharePoint. If your organization runs Excel 365, the pressure to migrate off .xls is real and increasing.
PowerShell can automate Excel's COM interface to open and save files in bulk. Here's the standard script you'll find on most IT forums:
# Batch convert .xls to .xlsx using PowerShell + Excel COM
$sourceDir = "C:\LegacyFiles"
$destDir = "C:\ConvertedFiles"
$xlXml = 51 # xlOpenXMLWorkbook format constant
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false
Get-ChildItem -Path $sourceDir -Filter "*.xls" | ForEach-Object {
$destPath = Join-Path $destDir ($_.BaseName + ".xlsx")
$wb = $excel.Workbooks.Open($_.FullName)
$wb.SaveAs($destPath, $xlXml)
$wb.Close($false)
Write-Host "Converted: $($_.Name)"
}
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
xlOpenXMLWorkbook) saves as .xlsx. The .xlsx format does not support VBA macros. Any macros in the source .xls file are silently dropped during the save. Excel will not warn you. The script reports "Converted: filename.xls" as if everything worked fine.
To preserve macros you'd need format constant 52 (xlOpenXMLWorkbookMacroEnabled), which saves as .xlsm. But .xlsm is not .xlsx — and if your goal is format compliance or SharePoint upload compatibility, .xlsm files often fail those requirements anyway.
Beyond macros, PowerShell/Excel COM has several other failure modes at scale:
Before converting anything — PowerShell or otherwise — you need to know what's actually in your files:
If you run PowerShell blind on 400 .xls files and 80 of them contain macros, you've silently broken 80 production workbooks. You may not discover the damage until a month-end report fails or a coworker notices their automation stopped running.
LegacyLeaps scans your entire folder and shows you exactly which files have macros, ActiveX controls, external links, and compatibility issues — before you touch a single file.
Try the Free ScanLegacyLeaps was built for this exact scenario: large folders of mixed legacy Office files, some simple, some with years of embedded automation, all needing to reach modern format without losing anything.
| File count | PowerShell + Excel | LegacyLeaps |
|---|---|---|
| 100 files | 5–15 min | <1 min |
| 500 files | 25–75 min | 3–5 min |
| 1,000 files | 45–90 min | 5–10 min |
| 5,000 files | 4–8 hours | 25–40 min |
| Feature | PowerShell + Excel | LegacyLeaps |
|---|---|---|
| VBA macro preservation | No (.xlsx) or saves .xlsm | Yes — preserved in .xlsm, flagged in report |
| ActiveX control handling | Silently dropped or broken | Audited; modern equivalents suggested |
| External link detection | No | Yes — listed in scan report |
| Requires Excel installed | Yes | No |
| Parallel processing | No | Yes |
| Pre-conversion audit | No | Yes |
| Post-conversion report | Basic log only | Full per-file summary |
| Files leave your machine | No | No (desktop app) |
| Cost | Free (+ your time) | Token-based (pay per file converted) |
PowerShell batch conversion is genuinely useful when:
A common hybrid workflow: use LegacyLeaps to scan everything and handle the macro-bearing files, then use PowerShell for the simple remainder. This gives you the best of both — automation for the clean files, safe handling for the complex ones.
LegacyLeaps is the right tool when:
Here's the approach we recommend for any bulk .xls migration:
Yes — using Excel's COM interface, PowerShell can open each .xls file and save it as .xlsx. It requires Excel to be installed and processes files sequentially. VBA macros are silently stripped during conversion.
Yes, if you save to .xlsx (format 51). Macros require .xlsm format (format 52) to survive — but .xlsm files won't satisfy requirements where .xlsx is specifically needed. LegacyLeaps gives you per-file control and full macro preservation, clearly flagged in the audit report.
PowerShell with Excel automation typically takes 45-90 minutes for 1,000 files. LegacyLeaps processes the same batch in 5-10 minutes using parallel native conversion without requiring Excel.
LegacyLeaps is the only purpose-built tool that handles bulk legacy Office file conversion with full VBA macro preservation, per-file audit reporting, and local processing — files never leave your machine.
Download LegacyLeaps and run the free scan against your .xls folder. See exactly which files have macros, which are safe to convert, and what the migration will look like — before you touch a single file.
Download Free ScannerPractical fixes for legacy Excel and Access problems. No spam.