Bulk & Automation

Rename Multiple Files With PowerShell

PowerShell is the most capable way to rename files in bulk on Windows, once you know the three commands that actually matter: Rename-Item to change a name, Get-ChildItem to select the files, and -replace to transform names with a regular expression. This guide is the complete reference: pattern renames, regex substitution, sequential numbering, bulk extension changes, and the -WhatIf dry-run that stops a bad rename before it happens. It sticks to PowerShell; for the graphical way or the old ren command, see the linked guides at the end.

The PowerShell Renaming Commands at a Glance

Almost every bulk rename is one of these four patterns. Pick by what the new name depends on.

TaskCommandWhen to use it
Rename one fileRename-Item -Path old.txt -NewName new.txtA single, known rename
Rename a batch by ruleGet-ChildItem | Rename-Item -NewName { ... }Apply one transformation across many files
Pattern / find-and-replaceRename-Item -NewName { $_.Name -replace 'old','new' }Swap text or match a regex pattern
Preview before running... -WhatIfAlways, on any batch, before committing

Method 1: Rename-Item for One File or a Simple Batch

Rename-Item is the core cmdlet. For a single file it's a one-liner: Rename-Item -Path 'report.txt' -NewName 'report-final.txt'. The power comes when you feed it many files through the pipeline and compute each new name with a script block, the {} after -NewName, where $_ is the current file.

For example, to add a prefix to every .txt file in a folder: Get-ChildItem -Filter *.txt | Rename-Item -NewName { '2025_' + $_.Name }. Get-ChildItem lists the files, the pipe hands each one to Rename-Item, and the script block builds the new name from the old one. Use $_.BaseName for the name without its extension and $_.Extension for the extension, so you can rebuild a name precisely, for instance { $_.BaseName + '_draft' + $_.Extension }.

Two switches on Get-ChildItem make the selection sharper. Add -File so folders are never caught up in a batch meant for files, and add -Recurse to walk every subfolder, for example Get-ChildItem -Filter *.txt -File -Recurse. When you only want part of a folder, insert a Where-Object filter before the pipe to Rename-Item, so you can match on name, size, or date. Get-ChildItem | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } | Rename-Item -NewName { 'recent_' + $_.Name } touches only files changed in the last week.

Method 2: -replace for Pattern and Regex Renames

The -replace operator is what turns PowerShell into a real bulk renamer. It takes a regular expression and a replacement, so you can do far more than a literal swap. To replace spaces with underscores across a folder: Get-ChildItem | Rename-Item -NewName { $_.Name -replace ' ','_' }. To strip a common prefix: { $_.Name -replace '^IMG_','' }. To change every .jpeg extension to .jpg: Get-ChildItem -Filter *.jpeg | Rename-Item -NewName { $_.Name -replace '\.jpeg$','.jpg' }.

Because -replace is regex, you can capture and reorder parts of a name. { $_.Name -replace '(\d{4})-(\d{2})-(\d{2})','$3-$2-$1' } flips a date from YYYY-MM-DD to DD-MM-YYYY across every matching file. That's the kind of transformation the graphical tools and the old ren command simply can't do.

Method 3: Sequential Numbering With a Counter

When you want files numbered in order, keep a counter variable and increment it in the loop. A ForEach-Object gives you room to do that:

  1. Set a starting number: $i = 1
  2. Pipe the files and rename each with the padded counter: Get-ChildItem -Filter *.jpg | ForEach-Object { Rename-Item $_ -NewName ('Vacation_{0:D3}.jpg' -f $i); $i++ }
  3. The {0:D3} format pads the number to three digits (001, 002, ...), so the files sort correctly.
  4. Run it with -WhatIf first (add -WhatIf to the Rename-Item) to confirm the numbering before it's applied.

Rename Safely: -WhatIf and -PassThru

A rename script applies to every matching file at once, so a mistake scales instantly. Two switches make it safe. -WhatIf performs a dry run: PowerShell prints exactly what each file would be renamed to without touching anything, so you can read the plan before committing. Add it to any Rename-Item and remove it once the output looks right.

-PassThru makes Rename-Item return the renamed objects, which is handy for confirming a large batch or piping the results onward. And if a rename could collide, two files resolving to the same new name, test with -WhatIf first, because PowerShell will error on the collision rather than overwrite silently. The usual fix for a collision is to add a distinguishing part to the new name, such as a sequential counter or a piece of the original name, so every result is unique. It is also worth running the command from inside the target folder, or passing an explicit -Path, so a stray match in another directory never gets swept into the batch. When the path itself changes, not just the name, reach for Move-Item instead of Rename-Item.

When the New Name Has to Come From Inside the File

There's a hard limit to what any PowerShell script can do: it works on the filename, the extension, and file metadata, but it cannot read what a document actually says. If you're renaming a folder of scanned invoices or contracts named Scan0043.pdf, no -replace pattern can turn that into the vendor and date, because those values are printed inside the PDF, not in the name. A script can renumber them; it can't identify them.

That's a different job called content-aware renaming, and it needs OCR and AI to read the page rather than the filename. A tool like renamer.ai reads each document, extracts the fields that matter, and builds a name from them, which is exactly the case a script can't reach. It runs on Windows and Mac, not from a terminal. If your bulk rename is really a pattern job, dates, prefixes, numbering, PowerShell is the right and free tool; if the name depends on the content, see the bulk rename software overview for the content-aware approach.

The honest split: use PowerShell when the information you need is already in the filename or a rule you can write, and reach for content-aware renaming only when the filename is meaningless and the document itself is the only source of the right name.

Other Ways to Rename Multiple Files on Windows

PowerShell is the most flexible option, but it isn't the only one, and it's overkill for a quick job. If you'd rather not script, File Explorer and PowerToys PowerRename handle multi-select and pattern renames from a graphical interface, covered in how to rename multiple files on Windows. If you prefer the classic command line without PowerShell's cmdlets, the cmd rename multiple files guide covers ren and batch-file loops, and explains where CMD's lack of regex means you'll want PowerShell after all.

For the full picture of bulk and automated renaming approaches, start at the bulk rename software hub.

Frequently Asked Questions

How do I rename multiple files at once in PowerShell?

Select them with Get-ChildItem and pipe to Rename-Item with a script block that builds each new name, for example: Get-ChildItem -Filter *.txt | Rename-Item -NewName { '2025_' + $_.Name }. Add -WhatIf first to preview the changes before applying.

How do I do a find-and-replace on filenames in PowerShell?

Use the -replace operator inside the -NewName script block: Get-ChildItem | Rename-Item -NewName { $_.Name -replace ' ','_' }. Because -replace takes a regular expression, you can also match patterns and reorder captured groups.

How can I preview a rename before it happens?

Add -WhatIf to the Rename-Item command. PowerShell prints exactly what each file would be renamed to without changing anything, so you can confirm the plan and only remove -WhatIf once it looks correct.

How do I number files sequentially with PowerShell?

Keep a counter and increment it in a ForEach-Object loop, using a format string to pad it: $i=1; Get-ChildItem -Filter *.jpg | ForEach-Object { Rename-Item $_ -NewName ('Photo_{0:D3}.jpg' -f $i); $i++ }.

How do I rename files in subfolders as well?

Add -Recurse to Get-ChildItem so it walks every subfolder, and pair it with -File so directories are left alone: Get-ChildItem -Filter *.txt -File -Recurse | Rename-Item -NewName { $_.Name -replace ' ','_' }. Preview it with -WhatIf first, because a recursive rename can touch far more files than you expect.

How do I rename only some of the files in a folder?

Insert a Where-Object filter into the pipeline before Rename-Item, so only the files you want reach it: Get-ChildItem | Where-Object { $_.Length -gt 1MB } | Rename-Item -NewName { 'big_' + $_.Name }. You can match on Name, Length, or LastWriteTime to target exactly the files that should change.

Can PowerShell rename files based on what's inside them?

No. PowerShell renames from the filename, extension, and metadata, not the document's content. To name a scanned invoice or contract by what's printed inside it, you need content-aware renaming with OCR, which is a separate kind of tool.