You have a folder — maybe a shared drive, maybe a file server — with hundreds or thousands of .xls files that need to become .xlsx. Doing it one at a time through File > Save As is not realistic. You need a bulk conversion process that handles macro detection, preserves data integrity, and doesn't require you to babysit every file. This guide walks through every approach, from free PowerShell scripts to automated tools, so you can pick the one that fits your situation.
Microsoft has been nudging organizations away from .xls for nearly two decades, but the urgency has increased. Modern Excel versions still open .xls files, but they do so in Compatibility Mode — a reduced-functionality state that prevents you from using features like dynamic arrays, Power Query improvements, and the expanded row limits of .xlsx. More critically, many cloud-based tools and APIs either don't support .xls at all or handle it poorly.
If your organization is migrating to Microsoft 365, moving files to SharePoint, or integrating Excel data with Power BI or Python-based workflows, .xls files become a bottleneck. The binary BIFF format is harder for third-party tools to parse, and every .xls file sitting on your file server is a small liability — one that gets harder to deal with the longer you wait.
The good news: bulk conversion is a solved problem. The bad news: doing it wrong can silently strip VBA macros from files that depend on them. The rest of this guide ensures you avoid that outcome.
Before you convert a single file, run through this checklist. Skipping it is how organizations end up with broken spreadsheets and angry users.
dir /s *.xls on Windows or find . -name "*.xls" on Mac/Linux gives you a count and location list.='C:\Reports\[budget.xls]Sheet1'!A1) will break if you convert the referenced file but not the referencing one, or vice versa. Map your dependencies first.LegacyLeaps scans your entire folder and tells you exactly which files have macros, which have formula issues, and which will convert cleanly — free.
Try the Free ScanThis is the most common DIY approach. It uses Excel's COM automation interface to open each .xls file and save it as .xlsx. You need Excel installed on the machine running the script.
$sourcePath = "C:\LegacyFiles"
$destPath = "C:\ConvertedFiles"
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false
Get-ChildItem -Path $sourcePath -Filter "*.xls" -Recurse | ForEach-Object {
$workbook = $excel.Workbooks.Open($_.FullName)
# Check for VBA macros
$hasMacros = $false
try {
$hasMacros = $workbook.VBProject.VBComponents.Count -gt 0
} catch {
# VBA project access may be restricted
}
$relativePath = $_.DirectoryName.Replace($sourcePath, "")
$outputDir = Join-Path $destPath $relativePath
if (!(Test-Path $outputDir)) { New-Item -ItemType Directory -Path $outputDir -Force }
if ($hasMacros) {
$outputFile = Join-Path $outputDir ($_.BaseName + ".xlsm")
$workbook.SaveAs($outputFile, 52) # 52 = xlOpenXMLWorkbookMacroEnabled
} else {
$outputFile = Join-Path $outputDir ($_.BaseName + ".xlsx")
$workbook.SaveAs($outputFile, 51) # 51 = xlOpenXMLWorkbook
}
$workbook.Close($false)
Write-Host "Converted: $($_.Name) -> $(Split-Path $outputFile -Leaf)"
}
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
If you're more comfortable in VBA than PowerShell, you can write a macro that does essentially the same thing from inside Excel. The logic is identical — loop through files, detect macros, save as the appropriate format. The advantage is that you don't need to deal with COM object lifecycle management. The disadvantage is that you're running the conversion inside an Excel instance, which is even slower and more prone to crashes with large batches.
For most teams, the PowerShell approach is more practical. The VBA approach makes sense if you're converting a small batch (under 50 files) and don't want to open a terminal.
When you're dealing with hundreds or thousands of files — especially across an organization with multiple file servers and shared drives — scripting your own solution starts to cost more in engineer time than it saves. This is where purpose-built tools earn their keep.
A good bulk conversion tool should handle these things that scripts typically don't:
LegacyLeaps handles all of this. The free scan phase analyzes every file in your batch without modifying anything, then gives you a detailed report of what will happen during conversion. You review the report, approve the conversion, and the tool processes everything — routing macro files to .xlsm, flagging formula issues, and generating a conversion log you can audit.
This deserves its own section because it's the single most common cause of data loss during bulk .xls conversion.
The .xlsx format, by design, cannot contain VBA macros. When you save an .xls file as .xlsx, Excel strips all VBA code — modules, class modules, UserForms, event handlers, everything. It does warn you during manual Save As, but in a bulk script, there's no interactive prompt. The code just disappears.
The solution is straightforward: detect macros before converting, and route those files to .xlsm. The PowerShell script above includes basic detection, but it requires enabling VBA project trust settings and doesn't catch every case (like workbooks with empty VBA projects that still need the .xlsm container).
Converting the file format is only half the job. You need to verify that the converted files actually work. Here's a practical validation checklist:
| Error | Cause | Fix |
|---|---|---|
| "Cannot access the file" | File is open by another user or process | Close the file, or run conversion outside business hours |
| "The file format differs from the extension" | .xls file is actually a different format (CSV, HTML) saved with .xls extension | Inspect the file manually; rename to correct extension |
| Macros missing after conversion | File was saved as .xlsx instead of .xlsm | Re-convert from the original .xls, saving as .xlsm |
| "VBA project is locked" | The workbook has a password-protected VBA project | You can still convert; the locked VBA project transfers to .xlsm intact |
| External links broken | Referenced files were also converted, changing their extension | Update link paths from .xls to .xlsx/.xlsm using Edit Links dialog |
| Script hangs on a file | Corrupt file or Excel waiting for user input | Add a timeout wrapper; set DisplayAlerts = $false |
Download LegacyLeaps and scan your files for free. See exactly what needs to be converted — macros, formula issues, external links — before you spend a penny.
Download Free ScannerYes. You can use a PowerShell script that automates Excel's COM interface, or a dedicated tool like LegacyLeaps that processes entire folders without manual intervention. Both approaches convert files without requiring you to open each one individually.
If you blindly convert all files to .xlsx, yes — any VBA macros will be silently stripped. Files containing macros must be saved as .xlsm instead. A proper bulk conversion process detects macros first and routes those files to .xlsm automatically.
Using a PowerShell script with Excel COM automation, expect roughly 5-15 seconds per file depending on complexity, so 1,000 files takes 1-4 hours. LegacyLeaps processes files faster because it doesn't require a running Excel instance for the initial scan phase.
Practical fixes for legacy Excel and Access problems. No spam.