Search code examples
powershell

Powershell: How to move image folders from one folder to another based on name


I have a folder with thousands of images of various file types. The eaisest way for me to move the relevant files is by filename as I can't confirm all the file types in the folder without going through the list.

$source = ''   
$dest = ''
Get-ChildItem $source -filter *. -recurse | Select-String -List -Pattern "Image1","Image2","Image3" | ForEach-Object {
    Move-Item $PSItem.Path -Destination $dest
}

I am new to powershell and first tested it with a script I found on Stack to move text files from one folder to another based on name which worked fine but when I adjusted this to allow for multiple file names and for images of various file types I can't get it to work. I first tried with one image file and one image type and even that wasn't working. Help appreciated.


Solution

  • Use Get-ChildItem's -Include parameter, which - unlike the -Filter parameter - allows you to specify multiple wildcard patterns:

    Get-ChildItem $source -Include *Image1*, *Image2*, *Image3* -Recurse -File |
      Move-Item -Destination $dest -WhatIf
    

    Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf and re-execute once you're sure the operation will do what you want.

    Note:

    • It is generally preferable - both for simplicity and performance - to pipe directly to a target cmdlet (rather than via ForEach-Object), as shown above.

    • -File has been added to ensure that Get-ChildItem only processes files and not also directories.

    • As lit points out, -Include and -Exclude only work as expected when -Recurse is also specified, and suggests the following workaround for when -Recurse isn't called for.

      • Use -Depth 0, which implies -Recurse while on the one hand limiting traversal to the immediate child items (as omitting -Recurse or -Depth would) yet on the other hand also honoring -Include / -Exclude.

      • See this answer for background information.


    As for what you tried:

    Piping Get-ChildItem output to Select-String makes the latter search for the given patterns (regexes) in the content of the files being piped, not in their names.