PowerShell Genie
Learn Export to Excel

Exporting to Excel with PowerShell

Export-Csv gives you a plain text file Excel can open. The ImportExcel module gives you a real spreadsheet: formatted headers, frozen panes, multiple worksheets, tables and charts — all from the pipeline.

Intermediate 6 min read Works in Windows PowerShell 5.1 and PowerShell 7 · Requires the ImportExcel module

Documentation: ImportExcel module on the PowerShell Gallery

What Export-Excel does

PowerShell has two ways to get data into Excel. Export-Csv writes a comma-separated text file. Excel opens it, but it carries no formatting, no frozen panes, no multiple sheets — it is data wearing a spreadsheet costume.

The ImportExcel module, installable from the PowerShell Gallery, adds the real thing. Export-Excel writes a genuine .xlsx file: bold headers, auto-sized columns, frozen top rows, one worksheet per dataset, Excel tables with filter buttons, conditional formatting and even charts. The input is the same pipeline you already know — objects in, spreadsheet out.

ImportExcel works in Windows PowerShell 5.1 and PowerShell 7, needs no installed copy of Excel, and runs on the machine that produces the report. That last point matters for servers: you can generate a formatted report on a server that has never had Office installed.

See the objects move

Inspect this authored example with fictional data in the bounded browser model. The numbered stages show how its objects change.

Get-Process | Sort-Object CPU -Descending | Select-Object Name, CPU, Id -First 5 |
  1. Stage 1Get-Process | Sort-Object CPU -Descending | STry it: export processes

    Install it, then export

    Install once per machine, for the current user, from the Gallery:

    1PS> Install-Module ImportExcel -Scope CurrentUser

    Then pipe objects to Export-Excel. The cmdlet reads the objects' properties and turns each one into a column:

    1PS> Get-Service | Where-Object Status -eq 'Stopped' |
    2PS> Select-Object Name, DisplayName, Status |
    3PS> Export-Excel ./stopped-services.xlsx -WorksheetName Services -AutoSize -FreezeTopRow -BoldTopRow

    -WorksheetName names the sheet. -AutoSize widens columns to fit. -FreezeTopRow keeps headers visible while scrolling. -BoldTopRow bolds them. Add -Append to add rows to an existing file, and repeat Export-Excel with different -WorksheetName values to build a multi-sheet workbook.

    For a polished table, add -TableName and -TableStyle: -TableName Services -TableStyle Medium9 turns the range into a real Excel table with filter buttons. Conditional formatting comes from New-ConditionalText piped to -ConditionalText, and charts from New-ExcelChartDefinition piped to -ExcelChartDefinition.

    Try it: export processes

    Export the five most CPU-hungry processes to a spreadsheet, then verify the file exists:

    1PS> Get-Process | Sort-Object CPU -Descending | Select-Object Name, CPU, Id -First 5 |
    2PS> Export-Excel ./top-processes.xlsx -WorksheetName Processes -AutoSize -FreezeTopRow -BoldTopRow
    3PS> Get-Item ./top-processes.xlsx | Select-Object Name, Length

    Open top-processes.xlsx: the Processes sheet lists five rows under a bold, frozen header, columns sized to fit. The second command only confirms the file was written — Export-Excel itself prints nothing on success.

    Common mistakes

    • Skipping the install. Export-Excel is not built in. Without Install-Module ImportExcel first, you get 'command not found'.
    • Expecting formatting from Export-Csv. A CSV file has no bold, no frozen panes, no sheets. If the report must look formatted, it must be .xlsx.
    • The file is open in Excel. Export-Excel cannot overwrite a workbook Excel currently holds open. Close it first or the export fails.
    • -Append with mismatched columns. Appending rows whose properties differ from the sheet's columns produces ragged data. Keep the Select-Object list identical across appends.
    • Forgetting the module on a new machine. A script that exports to Excel fails on any machine where ImportExcel was never installed. Put the install check at the top of scheduled scripts.

    Your turn

    On your own machine, export all services to an .xlsx file with two worksheets: one for running services, one for stopped services. Use -AutoSize and -FreezeTopRow on both, and open the file to confirm each sheet holds the right rows.

    Prove it: write it alone

    Blank editor. No starter, no hints. Write a one-liner that exports the names and statuses of all services to services.xlsx with a bold frozen header — then check the file opens with one worksheet.

    Practise this

    Export stopped services to Excel

    Export the stopped services to an .xlsx file with a frozen header row and auto-sized columns.

    Review the lesson

    Recap

    Export-Csv writes text; Export-Excel writes a real spreadsheet. Install the ImportExcel module once, pipe objects to Export-Excel, and use -AutoSize, -FreezeTopRow and -BoldTopRow for a readable report. Add -TableName for a true Excel table, and never export to a workbook that Excel has open.

    Genie guideExport to Excel with PowerShell

    Export-Csv makes a text file Excel can open. ImportExcel makes a real spreadsheet — formatting, frozen panes, worksheets, tables and charts, all from the pipeline.

    Stuck? Re-read the section, then try the filter yourself.