webdude2000
asked on
Move multiple windows files and folders to specific subfolder using powershell
Unfortunately I am short on time for this client change and so asking this forum:
Initially the request was to organise the clients many folders.
They are an accounting firm so have many client folders and under each, other folders such as 2010, 2011, 2013, marketing etc.
They wanted most of the subfolders folders moved for each client to a folder under each client call Historical.
They also wanted a set of new folders created under each client folder.
These requirements, I had mostly sorted out with PS script.
The problem now is they have additional folders under some clients created by staff that could be anything and files in the root of the client folder.
So the request is now to move everything in the client folder using a wildcard to the client sub folder called historical but exclude the folder called Permanent. I have not figured out how to do this.
So client looks like this on the server for example:
s:\client1\files.doc/xls/p df etc.
s:\client1\2010
s:\client1\2011
s:\client1\2012
s:\client1\2013
s:\client1\marketing
s:\client1\finplan
s:\client1\business
s:\client1\other-unknown-f olders
s:\client1\Permanent
All folders have files within them which have to move as well.
Now:
Will create folder under each client called Historical (Will create the other folders after the move)
So the client folders should be moved and look like:
s:\client1\historical\file s.doc/xls/ pdf etc.
s:\client1\historical\2010
s:\client1\historical\2011
s:\client1\historical\2012
s:\client1\historical\2013
s:\client1\historical\mark eting
s:\client1\historical\finp lan
s:\client1\historical\busi ness
s:\client1\historical\othe r-unknown- folders
s:\client1\Permanent
s:\client2 -- same as above and for all other client under the main drive
I wonder if my copy script could be easily modified to achieve the above?
$srcPath = "c:\test\folder\"
$dstPath = "c:\test\folder\NewLoc"
$clients = get-childitem -path $srcPath | ? { $_.PSIsContainer} | Select-Object Name
$log = "";
foreach ($client in $clients)
{
$srcCltPath = $srcPath + "\" + $client.name
$dstCltPath = $dstPath + "\" + $client.name
New-Item $dstCltPath -ItemType Directory -Force
$subFolders = get-childitem $srcCltPath | ? { $_.PSIsContainer} | Select-Object Name
$log += "New-Item " + $dstCltPath + " -ItemType Directory -Force `r`n"
foreach ($folder in $subFolders){
$copySrc = $srcCltPath + "\" + $folder.name
if ($folder.name -match "2010" -or $folder.name -match "2011"){
$copyDst = $dstPath + "\" + $client.name + "\historical\" + $folder.name
Copy-Item $copySrc -destination $copyDst -Recurse
$log += "Copy-Item " + $copySrc + " -destination" + $copyDst + " -recurse `r`n"
}
}
}
$log > c:\test\log10.csv
Initially the request was to organise the clients many folders.
They are an accounting firm so have many client folders and under each, other folders such as 2010, 2011, 2013, marketing etc.
They wanted most of the subfolders folders moved for each client to a folder under each client call Historical.
They also wanted a set of new folders created under each client folder.
These requirements, I had mostly sorted out with PS script.
The problem now is they have additional folders under some clients created by staff that could be anything and files in the root of the client folder.
So the request is now to move everything in the client folder using a wildcard to the client sub folder called historical but exclude the folder called Permanent. I have not figured out how to do this.
So client looks like this on the server for example:
s:\client1\files.doc/xls/p
s:\client1\2010
s:\client1\2011
s:\client1\2012
s:\client1\2013
s:\client1\marketing
s:\client1\finplan
s:\client1\business
s:\client1\other-unknown-f
s:\client1\Permanent
All folders have files within them which have to move as well.
Now:
Will create folder under each client called Historical (Will create the other folders after the move)
So the client folders should be moved and look like:
s:\client1\historical\file
s:\client1\historical\2010
s:\client1\historical\2011
s:\client1\historical\2012
s:\client1\historical\2013
s:\client1\historical\mark
s:\client1\historical\finp
s:\client1\historical\busi
s:\client1\historical\othe
s:\client1\Permanent
s:\client2 -- same as above and for all other client under the main drive
I wonder if my copy script could be easily modified to achieve the above?
$srcPath = "c:\test\folder\"
$dstPath = "c:\test\folder\NewLoc"
$clients = get-childitem -path $srcPath | ? { $_.PSIsContainer} | Select-Object Name
$log = "";
foreach ($client in $clients)
{
$srcCltPath = $srcPath + "\" + $client.name
$dstCltPath = $dstPath + "\" + $client.name
New-Item $dstCltPath -ItemType Directory -Force
$subFolders = get-childitem $srcCltPath | ? { $_.PSIsContainer} | Select-Object Name
$log += "New-Item " + $dstCltPath + " -ItemType Directory -Force `r`n"
foreach ($folder in $subFolders){
$copySrc = $srcCltPath + "\" + $folder.name
if ($folder.name -match "2010" -or $folder.name -match "2011"){
$copyDst = $dstPath + "\" + $client.name + "\historical\" + $folder.name
Copy-Item $copySrc -destination $copyDst -Recurse
$log += "Copy-Item " + $copySrc + " -destination" + $copyDst + " -recurse `r`n"
}
}
}
$log > c:\test\log10.csv
ASKER
This works:
$ClientLocation = 'C:\Test\folder'
$Clients = Get-ChildItem $ClientLocation
foreach ($Client in $Clients) {
$ClientName = $Client.Name
$FoldersToMove = Get-ChildItem "$ClientLocation\$ClientNa me" | Where-Object {$_.Name -notlike 'Historical' -and $_.Name -notlike 'Permanent'}
foreach ($FolderToMove in $FoldersToMove) {
$Destination1 = "$ClientLocation\$ClientNa me\Histori cal"
New-Item -Name $FolderToMove -Path $Destination1 -ItemType Directory
$Destination2 = "$ClientLocation\$ClientNa me\Histori cal\$Folde rToMove"
Get-ChildItem -Path "$ClientLocation\$ClientNa me\$Folder ToMove" -Recurse | Move-Item -Destination $Destination2
Remove-Item -Path "$ClientLocation\$ClientNa me\$Folder ToMove"
}
}
$ClientLocation = 'C:\Test\folder'
$Clients = Get-ChildItem $ClientLocation
foreach ($Client in $Clients) {
$ClientName = $Client.Name
$FoldersToMove = Get-ChildItem "$ClientLocation\$ClientNa
foreach ($FolderToMove in $FoldersToMove) {
$Destination1 = "$ClientLocation\$ClientNa
New-Item -Name $FolderToMove -Path $Destination1 -ItemType Directory
$Destination2 = "$ClientLocation\$ClientNa
Get-ChildItem -Path "$ClientLocation\$ClientNa
Remove-Item -Path "$ClientLocation\$ClientNa
}
}
ASKER
On further testing, it is having issues with deeper subdirectories
yes, i think the command should be
Move-Item -Path "$ClientLocation\$ClientNa me\$Folder ToMove" -Destination $Destination2
(no recursive as this will put everything into the flat structure)
p/s: i haven't do a code testing, but i guess that's your problem when i look at your code, (a wild guess)
can you tell me what is your issue? (without me go into a lab test)
Move-Item -Path "$ClientLocation\$ClientNa
(no recursive as this will put everything into the flat structure)
p/s: i haven't do a code testing, but i guess that's your problem when i look at your code, (a wild guess)
can you tell me what is your issue? (without me go into a lab test)
ASKER
As it stands without your change it moves the client subfolders and root files under each client as well as the next subfolder correctly yo the historical folder and leaves the permanant folder alone. However folders deeper than that are pulled up and placed in the 2nd subfolder level and files under those are pulled up and directories are created with the file names.
So I had documents called new document.txt and it created a folder called new document.txt
The copy command of my first script worked perfectly however I need to move the items using a wildcard excluding historical and permanent including all files and subdirectories and the directory structured under each main client folder needs to be retained.
So I had documents called new document.txt and it created a folder called new document.txt
The copy command of my first script worked perfectly however I need to move the items using a wildcard excluding historical and permanent including all files and subdirectories and the directory structured under each main client folder needs to be retained.
for the sack of testing, i have redeveloped this and the correct command should be ## TESTING at your own risk again##
Move-Item -Path "$ClientLocation\$ClientNa me\$Folder ToMove" -Destination "$ClientLocation\$ClientNa me\Histori cal"
you also don't require to remove the folder [ remove-Item -Path "$ClientLocation\$ClientNa me\$Folder ToMove"] as this is move command.
Move-Item -Path "$ClientLocation\$ClientNa
you also don't require to remove the folder [ remove-Item -Path "$ClientLocation\$ClientNa
ASKER
Thanks, I will change to your move command. We added the remove command because it was keeping the top level sub folder still in the source location even though we were doing a move.
Seeing this when running the script:
+ CategoryInfo : WriteError: (C:\Test\folder\...ocument 2010.txt:D irectoryIn fo) [Move-Item], IOException
+ FullyQualifiedErrorId : MoveDirectoryItemIOError,M icrosoft.P owerShell. Commands.M oveItemCom mand
Move-Item : Cannot create a file when that file already exists.
At C:\Users\ms\Documents\Clie nts\client \new-move- script.ps1 :13 char:84
+ ... ve" -Recurse | Move-Item -Destination $Destination2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Test\folder\...ocument 2010.txt:F ileInfo) [Move-Item], IOException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Mi crosoft.Po werShell.C ommands.Mo veItemComm and
Seeing this when running the script:
+ CategoryInfo : WriteError: (C:\Test\folder\...ocument
+ FullyQualifiedErrorId : MoveDirectoryItemIOError,M
Move-Item : Cannot create a file when that file already exists.
At C:\Users\ms\Documents\Clie
+ ... ve" -Recurse | Move-Item -Destination $Destination2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Test\folder\...ocument
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Mi
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Seems to work now:
It throws up errors because I did not define Directory anymore behind –Itemtype.
I had to leave –ItemType in otherwise the script does not work and if I state directory then it moves files from the client root folder but also creates directories of the same name, now it complains but moves both files and folders.
$ClientLocation = 'C:\Test\folder'
$Clients = Get-ChildItem $ClientLocation
foreach ($Client in $Clients) {
$ClientName = $Client.Name
$FoldersToMove = Get-ChildItem "$ClientLocation\$ClientNa me" | Where-Object {$_.Name -notlike 'Historical' -and $_.Name -notlike 'Permanent'}
foreach ($FolderToMove in $FoldersToMove) {
$Destination1 = "$ClientLocation\$ClientNa me\Histori cal"
New-Item -Name $FolderToMove -Path $Destination1 -ItemType
$Destination2 = "$ClientLocation\$ClientNa me\Histori cal\$Folde rToMove"
Get-ChildItem -Path "$ClientLocation\$ClientNa me\$Folder ToMove" -Recurse
Move-Item -Path "$ClientLocation\$ClientNa me\$Folder ToMove" -Destination "$ClientLocation\$ClientNa me\Histori cal" -force
$log += "Move-Item " + $FoldersToMove + " -destination" + $Destination2 + " -recurse `r`n"
}
}
$log > c:\test\log20.csv
It throws up errors because I did not define Directory anymore behind –Itemtype.
I had to leave –ItemType in otherwise the script does not work and if I state directory then it moves files from the client root folder but also creates directories of the same name, now it complains but moves both files and folders.
$ClientLocation = 'C:\Test\folder'
$Clients = Get-ChildItem $ClientLocation
foreach ($Client in $Clients) {
$ClientName = $Client.Name
$FoldersToMove = Get-ChildItem "$ClientLocation\$ClientNa
foreach ($FolderToMove in $FoldersToMove) {
$Destination1 = "$ClientLocation\$ClientNa
New-Item -Name $FolderToMove -Path $Destination1 -ItemType
$Destination2 = "$ClientLocation\$ClientNa
Get-ChildItem -Path "$ClientLocation\$ClientNa
Move-Item -Path "$ClientLocation\$ClientNa
$log += "Move-Item " + $FoldersToMove + " -destination" + $Destination2 + " -recurse `r`n"
}
}
$log > c:\test\log20.csv
ASKER
I've requested that this question be closed as follows:
Accepted answer: 0 points for webdude2000's comment #a40757613
for the following reason:
PS scripts that works.
Accepted answer: 0 points for webdude2000's comment #a40757613
for the following reason:
PS scripts that works.
I agree that is your answer, but i think I have help on your journey to your scripts that work.
ASKER
Core component of the script provided.
Thank you for the assistance.
Thank you for the assistance.
if ($folder.name -notmatch "Permanent")
then every folder will move except permanent