Tomas
Tomas

Reputation: 75

Copy files in a folder structure to their respective sub-folder with Powershell

I want to move the file "file_to_move.txt"in each folder to their respective "done"-folder.

so the file_to_move.txt in C:\Temp\test\folder1 is moved to C:\Temp\test\folder1\done and file_to_move.txt in C:\Temp\test\folder2 is moved to C:\Temp\test\folder2\done

...and so on, preferably with a %date%_%time% added to the file-name.

if a folder (like folder4 in the example below) does not have a file_to_move.txt, the script should just ignore it and move on.

folder structure example:

I have experimented with a Powershell script even if I'm not very good at it and I dont know it can be done in a standard batch-script. I have tried this so far:

In a batch-script:

SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%bin\movescript.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'"

in the movescript.ps1:

Move-Item C:\Temp\test\*\file_to_move.txt C:\Temp\test\*\done\file_to_move_$(get-date -f yyyyMMdd_HHmmss).txt

But this is not working. I guess it's not precise enough to work.

As a bonus, can the whole thing be done within the basic script or must we use the external .PS1-file?

Upvotes: 0

Views: 449

Answers (1)

Martin Brandl
Martin Brandl

Reputation: 58931

You can use the Get-ChildItem cmdlet with a filter to retrieve all file_to_move.txt files recursively from a path. Use the Foreach-Object (alias foreach) to iterate over them and combine the new path using the Join-Path cmdlet. To Copy the Item, you can use the Copy-Item cmdlet:

$itemsToCopy = Get-ChildItem -Path c:\Temp\Test -Filter file_to_move.txt -Recurse 
$itemsToCopy | foreach {
    $newPath = Join-Path $_.DirectoryName 'done'
    New-Item -Path $newPath -ItemType directory -Force | out-null
        $_ | Copy-Item -Destination $newPath
}

If you want to add a Timestamp, you could use the Get-Date cmdlet and invoke the ToString method with your desired format on it, example:

(Get-Date).ToString("yyyy-dd-M_HH-mm-ss")

Output:

2016-05-4_15-06-02

You can now concat the filenames using a format string and the $_.Basename and $_.Extension property within your foreach loop. I will leave this as an exercise to you.

Upvotes: 3

Related Questions