Forum Discussion
Copy Files Based on CSV input file (Import-CSV, Copy-Item)
RangerZ Does this work?
=========================
Code for FILE and PATH
=========================
#Import the CSV
$CSVData = Import-CSV -Path "D:\Organizer-2023\Organizer2022test2.csv"
#Get the data in Table-like format
$CSVData | Format-Table
# Select specific columns from the pipeline
$SpecificData = $CSVData | Select-Object PATH, FILE
# Display the data in Table format
$SpecificData | Format-Table
# Display the file to the local folder
ForEach ($Row in $CSVData) {
Copy-Item "$($Row.Path)$($Row.file)" -Destination "D:\Organizer-2023\$($Row.file)"
}
- RangerZDec 20, 2023Copper Contributor
Harm_VeenstraThank you!
The code changes work great!
It failed the first time, but highlighted an error in the CSV that I did not see with the original code. My PATH values did not include a trailing "\". The path just ended in FOLDER as opposed to FOLDER\, so when joined with the file name the path was not valid. After clean up, I tried it with the old code and it still failed. With yours I copied about 530 files in under 5 minutes!! Thank you!!
I have 2 additional questions please.
As noted above, I will reverse the source and destination to restore the modified file to it's original location. I think I want to append -Force to the end. I tested this by rerunning the above with -Force expecting to see the Created Time change to a more current time but did not. So I am unclear if this is correct or not, and is there an easy way to make the process verbose, for example list the file name's as it runs just so I can see it's doing something real.
Can you offer a reference or would you speak to the use of the additional $ in the syntax please.
- LainRobertsonDec 20, 2023Silver Contributor
Hey, Steve.
If you're asking about the additional $ in line 18:
Copy-Item "$($Row.Path)$($Row.file)" -Destination "D:\Organizer-2023\$($Row.file)"
Then it's to symbolise enclosed code.
So, where you had "()", that did not symbolise that the content within the ellipses was to be interpreted as code.
Conversely, "$()" says to PowerShell, "treat the stuff within the ellipses as code".
This is important as if you look at your original format of:
"($Row.Path)"
Then what you get is the value of the $Row object with the string literal of ".Path" appended to it, which is not what you had in mind.
If you use Harm's format of:
"$($Row.Path)"
Then what you get is the value of the $Row.Path property within the $Row object, which is what you had intended.
On another note, if you're looking to make your "Copy" command more resilient to the presence or omission of leading/trailing backslashes, you can use to the built-in Join-Path commandlet. Taking this approach means you do not have to worry so much about the format of your CSV file.
Copy-Item -Path (Join-Path -Path $Row.Path -ChildPath $Row.file) -Destination (Join-Path -Path "D:\Organizer-2023\" -ChildPath $Row.file);
Join-Path examples
Cheers,
Lain
- RangerZDec 20, 2023Copper Contributor
LainRobertsonThanks for your information and additional code suggestions
The Join-Path component is very interesting. I have already downloaded my files, but will need to send them back, so I will test this, but probably not until the weekend.The first thing that jumps out at me is that the expression looses the $() symbol in it's entirety.
I have now tested the -Force, and it does appear to work as desired, but I would still be interested to know if I can append some "output" parameter after force that says it created Row.FILE in the PowerShell display, or even the number of records written at the end would be good.