melro
melro

Reputation: 13

Copying files to specific folder declared in a CSV file using Powershell Script

i am quite new to powershell and i am trying to make a script that copy files to certain folders that are declared in a CSV file. But till now i am getting errors from everywhere and can't find nothing to resolve this issue.

I have this folders and .txt files created in the same folder as the script.

Till now i could only do this:

$files = Import-Csv .\files.csv 
$files
 foreach ($file in $files) {
    $name = $file.name
    $final = $file.destination
    Copy-Item $name -Destination $final   
  }

This is my CSV

name;destination
file1.txt;folderX
file2.txt;folderY
file3.txt;folderZ

Upvotes: 1

Views: 1994

Answers (1)

sheldonhull
sheldonhull

Reputation: 1935

As the comments indicate, if you are not using default system delimiters, you should make sure to specify them.

I also recommend typically to use quotes for your csv to ensure no problems with accidentally including an entry that includes the delimiter in the name.

@"
"taco1.txt";"C:\temp\taco2;.txt"
"@ | ConvertFrom-CSV -Delimiter ';' -Header @('file','destination')

will output

file      destination
----      -----------
taco1.txt C:\temp\taco2;.txt

The quotes make sure the values are correctly interpreted. And yes... you can name a file foobar;test..txt. Never underestimate what users might do. 😁

If you take the command Get-ChildItem | Select-Object BaseName,Directory | ConvertTo-CSV -NoTypeInformation and review the output, you should see it quoted like this.

Sourcing Your File List

One last tip. Most of the time I've come across a CSV for file input lists a CSV hasn't been needed. Consider looking at grabbing the files you in your script itself.

For example, if you have a folder and need to filter the list down, you can do this on the fly very easily in PowerShell by using Get-ChildItem.

For example:

$Directory = 'C:\temp'
$Destination = $ENV:TEMP
Get-ChildItem -Path $Directory -Filter *.txt -Recurse | Copy-Item -Destination $Destination

If you need to have more granular matching control, consider using the Where-Object cmdlet and doing something like this:

Get-ChildItem -Path $Directory -Filter *.txt -Recurse | Where-Object Name -match '(taco)|(burrito)' | Copy-Item -Destination $Destination

Often you'll find that you can easily use this type of filtering to keep CSV and input files out of the solution.

example

Using techniques like this, you might be able to get files from 2 directories, filter the match, and copy all in a short statement like this:

Get-ChildItem -Path 'C:\temp' -Filter '*.xlsx' -Recurse | Where-Object Name -match 'taco' | Copy-Item -Destination $ENV:TEMP -Verbose

Hope that gives you some other ideas! Welcome to Stack Overflow. 👋

Upvotes: 1

Related Questions