# [Powershell] Copy and rename files as defined in a CSV mapping file

Ha! What a title. I have no idea how else to describe it.

This is really a Part 2 to my earlier blog post, Powershell: Create files in a directory from a CSV list

In that post, I created a massive list of documents. Now the script I really needed was to rename them based on a mapping in a CSV document.

Brief:

• Copy a file from one directory to another, renaming them based on a mapping CSV document;
• Actions get logged;
• Check file exists before copying, log then skip
• Log if the file is being overwritten or not

SourceID,DestinationID

The Powershell Code:

$mappinglist = ".\mapping.csv"$sourcedocs = "\path\to\source\folder"
$destdocs = "\path\to\destination\folder"$date = get-date -format yyyyMMddHHmm
$logfile = ".\$date-documentcopy.log"

Add-Content $logfile "###$date Starting Document Copying ###"
Import-Csv $mappinglist | Foreach-Object {$srcfile = $_.SourceFile ;$destfile= $_.DestinationFile; If (!(Test-Path$destdocs\$destfile)) { Add-Content$logfile "$srcfile ($destfile) not found in destination directory"
Write-Host "$srcfile ($destfile) not found in destination directory"
}
if (Test-Path $sourcedocs\$srcfile) {
Write-Host "$srcfile copying to$destdocs\$destfile" Copy-Item$sourcedocs\$srcfile$destdocs\$destfile" Add-Content$logfile "$srcfile copied to$destdocs\$destfile" } else { Write-Host "$srcfile source document not found ... skipping"
Add-Content $logfile "$srcfile source document not found ... skipping"
}
}
Add-Content $logfile "###$date Finished Document Copying  ###"

Notes:
Most of the code is done in a few lines, however for my purpose, I really needed to have everything logged as we generate formal reports on basically everything we do!
I’m a big fan of timestamping my log files, hence the $date-documentcopy.log line. Also, I like being able to see what’s going AND having it log to file, so I duplicate the Add-Content and the Write-Host lines. I rather like the Write-Host “copying” and Add-Content “copied” line. The reason for this is I have some large files (>2GB) so *if* it fails I can see on-screen which record it was but the log has it once it’s finished. # [Powershell] Create files in a directory from a CSV list I’ve recently been using Powershell more and more to replace either broken and/or ageing ‘batch’ files at work plus also come personal projects I’ve been working on. Some of them took a bit of digging around between various sites/blogs to put together, so I’ve decided to re-post them with a final solution. Warning: I’m a pretty crap blogger, so don’t expect regular updates! Anyway, this one is I wanted to test a copy and rename script but needed some testing data first. So this creates a file in a folder with the name taken from a list in a CSV. The ID didn’t have a file extension so I’m randomly creating one from a small list. Brief: Take a list of ID’s from a CSV and create a file in a folder using the ID as the filename with a random file extension. $docext = @("msg","docx","doc","xlsx","xls","pdf")

$path = ".\filename_list.csv" Import-Csv$path | Foreach-Object {
$filename =$_.filename;
$ext =$docext | Get-Random -Count 1;
if (!(Test-Path "C:\path\to\files\$filename.*")) {$filename | Out-File "C:\path\to\files\$filename.$ext";
Write-host "creating file $filename"; } else { Write-Host "file already exists"; } }  A brief run down. The @docext is an array of possible extensions, as mine list only has an ID, not the extension. I wanted to make one up for my test. The$ext = \$docext | Get-Random -Count 1; grabs one of these random extensions.
I run a Test-Path to see if the filename exists so it doesn’t create two files with different extensions. I use a wildcard to check.
Lastly I Write-Host so I can see what’s going on.