Move folders with certain folder name keeping directory tree

How do I move all “2010” folders (and its sub folders and data) from k:\Clients\ to k:\Archive\ keeping the same directory tree as there was under clients. The layout of Clients folder is:
\Clients*First Letter Client code**client code**year**sub folder**data or more subfolders*\

Examples

K:\Clients\A\Abc12\2010\Fin
K:\Clients\A\Abc12\2010\Emails
K:\Clients\A\Abc12\2010\Data
K:\Clients\A\Abc12\2011\Fin
K:\Clients\A\Abc12\2011\Emails
K:\Clients\A\Abc12\2011\Data
K:\Clients\A\Abc12\2012\Fin
K:\Clients\A\Abc12\2012\Emails
K:\Clients\A\Abc12\2012\Data
K:\Clients\A\Aefg34\2010\Fin
K:\Clients\A\Aefg34\2010\Emails
K:\Clients\A\Aefg34\2010\Data
K:\Clients\A\Aefg34\2011\Fin
K:\Clients\A\Aefg34\2011\Emails
K:\Clients\A\Aefg34\2011\Data
K:\Clients\A\Aefg34\2012\Fin
K:\Clients\A\Aefg34\2012\Emails
K:\Clients\A\Aefg34\2012\Data
K:\Clients\B\Bhgf76\2010\Data
K:\Clients\B\Bhgf76\2011\Fin
K:\Clients\B\Bhgf76\2011\Emails
K:\Clients\B\Bhgf76\2011\Data
K:\Clients\B\Bhgf76\2012\Fin
K:\Clients\B\Bhgf76\2012\Emails
K:\Clients\B\Bhgf76\2012\Data\

In above example result would be the following:

K:\Archive\A\Abc12\2010\Fin
K:\Archive\A\Abc12\2010\Emails
K:\Archive\A\Abc12\2010\Data
K:\Archive\A\Aefg34\2010\Fin
K:\Archive\A\Aefg34\2010\Emails
K:\Archive\A\Aefg34\2010\Data
K:\Archive\B\Bhgf76\2010\Data\

All other data stays in K:\clients\ only 2010 folders are moved. Reason for this is to archive and free up space but there are 1000’s of clients folders

Thanks for your help

Hey mate,

The two cmdlets you are going to want to work with are Get-ChildItem and Move-Item This could be achieved in a single line of code. Have a play around with Get-ChildItem and Move-Item.

Try something like this:

Get-ChildItem C:\Temp\Folder | Move-Item -Destination C:\newTemp 

You can also use wildcards when using Get-Childitem so you can do something like this.

Get-ChildItem C:\Temp\*\2010\  | Move-Item -Destination C:\newTemp 

Remember, if you’re in doubt. use the common parameter -WhatIf on the end of your code to see what ‘would’ happen if you executed your line.

Let us know how you go.

Thanks, I create a temp folder and the layout of clients to test script.
First I tried
Get-ChildItem C:\Temp\kdrive\clients*\2010 | Move-Item -Destination C:\Temp\kdrive\archive

But above didnt do anything
Then i tried:
Get-ChildItem C:\Temp\kdrive\clients**\2010 | Move-Item -Destination C:\Temp\kdrive\archive

This did move the first 2010 folder it found but it didnt create the directory structure so when it found second 2010 folder it gave error:

Move-Item : Cannot create a file when that file already exists.

How would i get the directory tree when moving folders ie so client code is used under archive folder. thanks

I found the following webpage http://blogs.msdn.com/b/powershell/archive/2007/04/27/fun-with-paths.aspx

It suggested the following code but I cant get it working
get-childitem | where {conditions} | move-item -destination {join-path ‘D:\Archive’ $_.FullName.SubString($pwd.path.length) }

I tried the following but comes up with error
Get-ChildItem C:\Temp\kdrive\clients**\2010 | move-Item -Destination {join-path C:\Temp\kdrive\archive $_.FullName.SubString($pwd.path.length) }

Error:
move-Item : Could not find a part of the path.

I sort of cheated and used robocopy in conjunction with the script above. Once you review the copy (making sure all the files are where you want them) - you can run a remove using the same get-item query.

get-item C:\temp\*\2010 | foreach ($_){$oldpath = $_.FullName; $newpath = "C:\archive\"+$_.Parent; robocopy $oldpath $newpath /COPYALL /E}

This may work for you. Just modify what Get-ChildItem is looking in
If the Name has a consistent naming convention you can add a where condition

The below moved the folders and all the contents after the root to a new folder location

I am not sure that the 2 wildcards would work

$Paths = Get-ChildItem C:\Users\user\Documents\test | select name | ForEach-Object {$_.name}
$Root = "C:\Users\user\Documents\test\"
foreach ($Path in $Paths)
{
    $FileLocation = Join-Path $root $Path
    Move-Item $Filelocation -Destination C:\fso\Firefox
}

The below worked with wildcards

$Paths = Get-ChildItem C:\Users\user\Documents\test\*\m* | select fullname | ForEach-Object {$_.fullname}

foreach ($Path in $Paths)
{
    Move-Item $Path -Destination C:\fso\Firefox
}

You can’t beat robocopy in this instance.

Robocopy “C:\source” “H:\Dest” /MIR /FFT /Z /XA:H /W:5

Something like this should work I think.

$Source = Get-ChildItem -Path "K:\Clients\*\*" | where {$_.psiscontainer -eq $true -and $_.FullName -like "K:\Clients\*\*\2010*"}
foreach ($S in $Source){
    $Destination = "K:\Archive\" + $S.FullName.TrimStart("K:\Clients\")
     Move-Item -Path $S.FullName -Destination $Destination
}

Thank for your help, the following seems to have worked in my test environment, I will be doing the live move over next few days and will post results. Note you need to run powershell using “Run as Administrator” or robocopy comes up with warning

get-item C:\temp\kdrive\clients\a\*\2011 | foreach ($_){$oldpath = $_.FullName; $newpath = "C:\temp\kdrive\archive\a\"+$_.Parent+"\2011"; robocopy $oldpath $newpath /MOVE /E}