Move items with folder structure

I have a file storage server with documents are stored in the different locations. See file listing below. I need to move all of the items in the folder called Archive to another backup server and keep the folder structure. I tried Get-ChildItem, Move-item, Split-path but I can’t get it to work. Can someone please help me? Thank you in advance.

C:\Documents\TestData\E0001\E0001_0001\report.xls
C:\Documents\TestData\E0001\E0001_0001\Archive\bank_statement.docx
C:\Documents\TestData\E0001\E0001_0003\Info_gov.docx
C:\Documents\TestData\E0001\E0001_0003\Archive\Monthly Billing Report.xlsx
C:\Documents\TestData\E0001\E0001_0003\Archive\HomeDrive\server_backup.txt
C:\Documents\TestData\E0002\E0002_0001\Archive\9047_Payment_History.pdf
C:\Documents\TestData\E0002\E0002_0002\employee_contactlist.doc
C:\Documents\TestData\E0002\E0002_0002\Archive\working_document.pdf
C:\Documents\TestData\E0002\E0002_0003\Archive\New folder\9570_Pay_History.pdf
C:\Documents\TestData\E0003\Archive\Agreement Terms.pdf
C:\Documents\TestData\E0003\Archive\Bank Statement eStmt_2023-10-07.pdf

Here is what I tried. I just can’t get array03(which is the source path) and array04(which is destination) in a table format like SQL to loop through each for the move-item cmdlet. If this doesn’t work, I need a batch file move or copy command.

$filepath = 'C:\Documents\TestData\'

# create array01 to get all the files, including subfolders and only file type.
$array01 =@() 
$array01 = Get-Childitem $filepath -Name -Recurse -File 

# create array02 to match filename with word Archive
$array02 = @()
$array02 = $array01 -match 'Archive' 

# create array03 to (1)get the matched items and (2)write out full path for all matched items.
$array03 = @()
#$array02 | ForEach-object {Write-Output "C:\Documents\TestData\\$_"} <--replace this hard path to variable $filepath
$array03 = $array02 | ForEach-object {Write-Output "$filepath\$_"}

# for parent path folder
$array04 = @()
$array04 = $array03 | ForEach-object {split-path $_ -parent}

# either create a batch copy file or use Move-Item
$array05 = @()
$array05 = $array03 | ForEach-object {Write-Output "Copy ""$array03"" $_" } |Format-Table
$array05 = ForEach-object {Move-Item -path $array03 -destination $array04 }

No,
Welcome to the forum. :wave:t4:

With a little string acrobatics it is not that hard … :wink: :grinning:

$SourceDir = 'C:\Documents\TestData'
$TargetDir = 'D:\Backup'

Get-ChildItem -Path $SourceDir -Directory -Recurse |
Where-Object -Property FullName -Match -Value '\\Archive(?!\\)' |
ForEach-Object {
    $SourceDirLength = $SourceDir.Length
    $TotalLength = $_.FullName.Length
    $RelativePath = $_.FullName.Substring($SourceDirLength, $TotalLength - $SourceDirLength)
    $TargetPath = Join-Path -Path $TargetDir -ChildPath $RelativePath
    Copy-Item -Path $_.FullName -Destination $TargetPath -Recurse 
}

That snippet will copy all Archive folders including their subfolders to the $TargetDir.

The regex pattern '\\Archive(?!\\)' will match all paths with a folder with the name Archive in it but ignores their subfolders.

Edit:
When you tested the code succesfully with test data you can of course change Copy-Item to Move-Item. :wink:

2 Likes

Thank you for the warm welcome, Olaf!

The script works for me. I’m into my first week of learning PowerShell, so thank you so much! Much appreciated! You’re a genius!

Is there a way that I can get a report of all the files are copied or moved? Thank you.

You should ALWAYS read the help for the cmdlets you’re about to use COMPLETELY including the examples to learn how to use them.

Most cmdlets, which by default do not generate any output, can be forced to output something with the parameter -PassThru. This output can be piped to a TXT or CSV file.

If that does not work you might try one of the common parameters supported by almost all cmdlets:

-OutVariable for example.

2 Likes

Thank you very much! Very helpful information.

I added Start-Transcript and Stop-Transcript to export to a report file.

I also added -Verbose and -PassThru. They are what I need.

I’m sorry. I figured it out now. Miss-typed a word.

That happens to the best of us … :wink: :stuck_out_tongue_winking_eye: :smiley:

:rofl: I know right. kakakaa. I figured it out right after I asked you for help. OMG. lol

That happens quite often. I think it could be because you just wrapped your head around the issue explaining it to someone else (sometimes even in a foreign language) and then your brain is almost there but you do not realise it yet.

May I ask where you’re from?

Totally understand. I’m Vietnamese. SQL dev guy and learning PowerShell. How about you?

I’m German. System engineer doing PowerShell since version 1.1.
:man_beard:

Cheers.
:slightly_smiling_face: :love_you_gesture:t4:

Cheers. :grinning: :sunglasses: :beers: That sounds like a very long time ago. :slight_smile: You must love it alot.

It is. 15 Years.
I do.
:slightly_smiling_face:

1 Like