0

I am trying to Copy Directories - folders and Sub folders to another location using a CSV file that lists the source and destination of each directory or folder to be copied.

The Contents of the CSV are as such below: enter image description here

I have referenced this thread:

https://serverfault.com/questions/399325/copying-list-of-files-through-powershell

 Import-CSV C:\Users\WP\Desktop\a.csv | foreach{Copy-item "$_.Source" "$_.Destination"}

Error Received

CategoryInfo          : ObjectNotFound: (@{Source=C:String) [Copy-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.CopyItemCommand

The other question I have is if in the CSV I want to copy to a folder that does not exists in the destination - can I use the CSV to command powershell to create the folder?

Thank you for your advice.

3 Answers 3

1

PowerShell will not expand the variable and access the property of the object inside the variable if you have them placed in double quotes by default. Only the '$_' is being expanded and '.source' is being tacked on to the end of the string, so from the view of the shell, your command looks something like Copy-item "{source=C:\Users\WP\Desktop\a;Destination=C:\Users\WP\Desktop\a}.Source" "{source=C:\Users\WP\Desktop\a;Destination=C:\Users\WP\Desktop\a}.Destination", which is probably not what you mean.

Here is the syntax that should work (I also included -Recurse so that it will copy the items inside the directory as well)

Import-CSV C:\Users\WP\Desktop\a.csv | foreach{Copy-item  -Path $_.Source -Destination $_.Destination -Recurse}

Note: if you want to access the properties on an object inside of double quotes, use this syntax "$($_.source)".

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you to both - John's Answer Created the folder at destination as well.
1

For a csv like this:

Source,Destination
D:\junk\test1,D:\junk\test3 
D:\junk\test2,D:\junk\test4 

You can use code like the following:

$csv = Import-Csv D:\junk\test.csv 
$csv | ForEach-Object {
    if (-not (Test-Path $_.Destination)) {
        New-Item -Name $_.Destination -ItemType Directory -Force -WhatIf
    }
    Copy-Item $_.Source $_.Destination -Recurse -Force -WhatIf
}

Suggestions for learning more about PowerShell:

  1. Use WhatIf to test things.

  2. Research what each line of this code does.

  3. Experiment with code to see what it does.

  4. Learn and use the debugger (PowerShell ISE) to help you write better code.

  5. Remove the WhatIf parameters from the code to have it execute for real...

3 Comments

Thank you - it seemed to work :) - I will spend some time investigating. I appreciate all the help. Just in case if the folder does not exists - will this create the folder at the destination ?
AFAIK, the -Recurse parameter causes folders at the destination to be created if necessary.
Yes, I added the Test-Path and New-Item call more for the "teaching" aspect. Not all code that can be written in one line should be, and depending on what the user intends to do next might make things easier (maybe copy file, maybe log actions, etc).
0

If you have dozens of problems that all involve doing the same thing with each element of a list, you might want to consider getting or writing a generic CSV template expander tool, like Expand-csv. With this tool you start with a CSV file and a template, and generate a script that contains all the commands.

Sample.csv looks like this:

Source,Destination
C:\Users\WP\Desktop\a,C:\Users\WP\Desktop\c
C:\Users\WP\Desktop\b,C:\Users\WP\Desktop\d

Sample.tmplt looks like this:

Copy-Item -Path $Source -Destination $Destination -Recurse

And the command to invoke Expand-csv looks like this:

Expand-csv Sample.csv Sample.tmplt > Sample.ps1

The output file, Sample.ps1 contains one copy command for each entry in the CSV file

And here is the definition of Expand-csv:

<#  This function is a table driven template tool. 
    It's a refinement of an earlier attempt.

    It generates output from a template and
    a driver table.  The template file contains plain
    text and embedded variables.  The driver table 
    (in a csv file) has one column for each variable, 
    and one row for each expansion to be generated.

    5/13/2015

#>

function Expand-csv {
   [CmdletBinding()]
   Param(
      [Parameter(Mandatory=$true)]
      [string] $driver,
      [Parameter(Mandatory=$true)]
      [string] $template
   )
   Process
   {
      $OFS = "`r`n"
      $list = Import-Csv $driver
      [string]$pattern = Get-Content $template

      foreach ($item in $list) {
         foreach ($key in $item.psobject.properties) {
            Set-variable -name $key.name -value $key.value
            }
         $ExecutionContext.InvokeCommand.ExpandString($pattern) 
         }
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.