i basically want to run:

C:\>xcopy [0-9]{13}\.(gif|jpg|png) s:\TargetFolder /s

i know xcopy doesn't support regular-expression filename searches.

i can't find out how to find out if PowerShell has a Cmdlet to copy files; and if it does, how to find out if it supports regular expression filename matching.

Can anyone think of a way to perform a recursive file copy/move with regex filename matching?

  • 1
    this should be moved to stackoverflow right?
    – user33788
    Jun 7, 2010 at 18:59
  • 1
    @smoknheap : It could be both, I find that Powershell scripting is becoming more and more a Power User tool. This is more of a xcopy replacement question then a scripting question. Jun 7, 2010 at 19:07

3 Answers 3


I like using all Powershell commands when I can. After a bit of testing, this is the best I can do.

$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter} 
foreach ($item in $bin) {Copy-Item -Path $item.FullName -Destination $destination}

The first three lines are just to make this easier to read, you can define the variables inside the actual commands if you want. The key to this code sample is the the "Where-Object" command which is a filter that accepts regular expression matching. It should be noted that regular expression support is a little weird. I found a PDF reference card here that has the supported characters on the left side.


As "@Johannes Rössel" mentioned, you can also reduce the last two lines down to a single line.

((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination

The main difference is that Johannes's way does object filtering and my way does text filtering. When working with Powershell, it's almost always better to use objects.


As @smoknheap mentioned, the above scripts will flatten out the folder structure and put all your files in one folder. I'm not sure if there is a switch that retains folder structure. I tried the -Recurse switch and it doesn't help. The only way I got this to work is to go back to string manipulation and add in folders to my filter.

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")

I'm sure that there is a more elegant way to do this, but from my tests it works. It gather s everything and then filters for both name matches and folder objects. I had to use the ToString() method to gain access to the string manipulation.


Now if you want to report the pathing to make sure you have everything correct. You can use the "Write-Host" Command. Here's the code that will give you some hints as to what's going on.

$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Write-Host "
Obj: $item
Path: "$item.fullname"
Destination: "$item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")

This should return the relevant strings. If you get nothing somewhere, you'll know what item is having problems with.

Hope this helps

  • Note that you don't need to use $item.FullName there – the appropriate property is taken automatically if you pass a FileInfo object (imho, you shouldn't, since PowerShell's power comes from passing structured objects, not string). Furthermore, you can put everything into a single pipeline: ((gci $source) -match $filter) | cp -dest $destination (slightly adapted for brevity – feel free to change; I'm just saying that the foreach is unnecessary there).
    – Joey
    Jun 7, 2010 at 22:25
  • When I was testing it, I couldn't get the objects to pipe correctly. That is turn forces me to use the foreach command. I'll give your code a try and see what happens. Thanks for pointing that out. Jun 8, 2010 at 16:31
  • does this have the same problem as mine where it flattens the destination directory out? xcopy would normally preserve the directory structure on the destination directory, right?
    – user33788
    Jun 8, 2010 at 16:52
  • Copy-Item : Cannot bind argument to parameter 'Path' because it is null
    – Ian Boyd
    Jun 13, 2010 at 16:33
  • Please note that Trim is not intended to remove a string from the end of another string, instead it removes all instances of the characters in the parameter string from the beginning and end of the string it is called on. In your case if $item.Name contains a capital C it will also remove the drive letter C from the beginning of the string.
    – Andris
    Jan 18, 2012 at 11:17

PowerShell is an excellent tool for that task. You can use Copy-Item cmdlet for the copying process. You can pipeline it with other cmdlets for complex copy commands, here is someone that did exactly that :)

Regular expressions use the .NET RegEx class from the System.Text.RegularExpressions namespace, there are quick how-to on these class

PowerShell also have the -match and -replace operators that can be used when pipelining with copy-item

There are also tools to help you create the RegEx itself, e.g. RegEx buddy

  • Imho, -match and -replace should be mentioned before going into System.Text.RegularExpressions.RegEx. At least for me, I rarely use [regex] directly; however I do frequently use the -match and -replace operators. As for creating the regular expressions I found PowerShell to be quite useful in testing and refining a regex you're writing, too.
    – Joey
    Jun 7, 2010 at 1:21
  • i've asked for the answer to your answer in this question: superuser.com/questions/149808/…
    – Ian Boyd
    Jun 7, 2010 at 14:23

as an idea but needs some work

dir -r | ?{$_ -match '[0-9]{13}\.(gif|jpg|png)'} | %{xcopy $_.fullname c:\temp}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.