Moving files using an array

Hi Guys,

I am trying to write a script that will move about 15 files. I thought it made the most sense to create an array with all the file names in it. So what I ended up with was:

$sourceFolder = 'C:\Temp'
$destFolder = 'C:\Foo'
$myFiles = @(file1,file2,file3)
Move-Item "$sourceFolder\MyFiles[0]" $destFolder

Files do not move and I do not get an error.

Any ideas?

Thanks

There are a few ways you could do this. Move-Item does accept an array for the -Path and -LiteralPath parameters, but you would need to create an array with the full paths of each file first. Alternatively, you can use the pipeline. Here are a few different ways to make this work, starting with the three variables you defined (and there are probably half a dozen more you could come up with, though they’re all variants of the same basic ideas):

$sourceFolder = 'C:\Temp'
$destFolder = 'C:\Foo'
$myFiles = @('file1','file2','file3')

# Pipe FileInfo objects to Move-Item via the pipeline
Get-ChildItem -Path "$sourceFolder\*" -Include $myFiles | Move-Item -Destination $destFolder -WhatIf

# Build an array of paths to pass to Move-Item without pipeline input
Move-Item -Path ($myFiles -replace '^', "$sourceFolder\") -Destination $destFolder -WhatIf

# Use pipeline input combined with a ScriptBlock parameter.  (Kind of nifty, and not very widely known or well documented syntax)
$myFiles | Move-Item -Path { "$sourceFolder\$_" } -Destination $destFolder -WhatIf

Lose the -WhatIf switches, of course. I just included those for demonstration purposes.

Dave,

Thanks for the feedback.

It appears that each of your examples will move all the files in the array. Is there a way to select specific files based on their element ID?

What do you mean by their element ID? Their index in the array?

There are lots of ways you could do that. Since you already have an array in memory, the easiest is probably to use the array index operator. Something like this (in all 3 examples, I’m just making up the assumption that you want to move the first and third files in the array, skipping the second one.)

# Pipe FileInfo objects to Move-Item via the pipeline
Get-ChildItem -Path "$sourceFolder\*" -Include $myFiles[0,2] | Move-Item -Destination $destFolder -WhatIf
 
# Build an array of paths to pass to Move-Item without pipeline input
Move-Item -Path ($myFiles[0,2] -replace '^', "$sourceFolder\") -Destination $destFolder -WhatIf
 
# Use pipeline input combined with a ScriptBlock parameter.  (Kind of nifty, and not very widely known or well documented syntax)
$myFiles[0,2] | Move-Item -Path { "$sourceFolder\$_" } -Destination $destFolder -WhatIf

# Just for giggles, showing off the Select-Object -Index parameter:
$myFiles | Select-Object -Index 0,2 | Move-Item -Path { "$sourceFolder\$_" } -Destination $destFolder -WhatIf

Also, here’s how your original command could be modified to work:

Move-Item "$sourceFolder\$($MyFiles[0])" $destFolder

$() is the subexpression operator, and it’s mostly used to embed expressions such as $MyFiles[0] into a string. Without it, $MyFiles would expand, and [0] would be treated as a literal part of the string (instead of being treated as an operator and array index.)

This seems to work best for me:

Move-Item "$sourceFolder\$($MyFiles[0])" $destFolder

Feel like a kid in a candy store with all these options :wink:

Thanks again.