0

Using tips gleaned from this, this, and this, I've finally been able to get a series of file backup scripts going. However, there's one little thing that I've been unable to solve. No runtime errors, but when I run this script,

$originalPath = "\\Server\Path\_testData\"
$backupPath   = "\\Server\Path\_backup\"
#       
function supportBackup 
{
  "$($originalPath) copying DOC XLS PPT JPG GIF PDF WAV AVI to $($backupPath)"
  Get-ChildItem $originalPath\* -Include *.doc*, *.xls*, *.ppt*, *.jpg, *.gif, *.pdf, *.wav, *.avi | `
  foreach { 
    $targetFile = $backupPath + $_.FullName.SubString($originalPath.Length); 
    New-Item -ItemType File -Path $targetFile -Force;  
    Copy-Item $_.FullName -destination $targetFile 
  } 
  "Support File Backup Completed"
} 
supportBackup

The original file path gets dumped into the destination directory instead of just the files.

What I want:

\\Server\Path\_backup\files-from-testData-directory

What I get:

\\Server\Path\_backup\_testData\files-from-testData-directory

I know the problem is closely related (if not identical) to this question, but after studying it and trying to apply some of the wisdom from there, using various iterations of the $_.Name variables, I realize I don't have as good an understanding as I thought I did. I need someone to explain to me HOW the destination path and filename are being constructed with the given variables, and what alternate variables (or code) I need to use to achieve my desired results. There's something that's not clicking for me and I need help understanding it.

Community
  • 1
  • 1
dwwilson66
  • 6,806
  • 27
  • 72
  • 117
  • 1
    FYI, you don't need a backtick if you end a line with a pipe symbol. PowerShell automatically interprets the following line as continuing the pipeline. However, personally I find it clearer to *begin* lines with pipe symbols so it's clearer to see what's being piped into what in multi-line pipes. In that case you *do* need a backtick at the end of the preceding line, to escape the newline. So, I'd end line 7 with a backtick, and change the 8th line to this: `|foreach {`. It's not that common a style, but I think it makes complex pipelines easier to follow. – Adi Inbar Sep 07 '13 at 03:18

1 Answers1

5

You're trying too hard. This should suffice:

$originalPath = '\\Server\Path\_testData'
$backupPath   = '\\Server\Path\_backup'
$extensions   = *.doc*,*.xls*,*.ppt*,*.jpg,*.gif,*.pdf,*.wav,*.avi

function supportBackup {
  "$($originalPath) copying DOC XLS PPT JPG GIF PDF WAV AVI to $($backupPath)"
  Get-ChildItem "$originalPath\*" -Include $extensions |
    Copy-Item -Destination "$backupPath\" -Force 
  "Support File Backup Completed"
} 

supportBackup

You can pipe the results of Get-ChildItem directly into Copy-File. The destination path must end with a backslash, though, otherwise the instruction would try to replace the folder $backupPath with a file of the same name, thus causing an error.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • That did what I needed it to in terms of the copy...however my filenames don't print to the console as they copy over. I can live without that for now. :) – dwwilson66 Sep 09 '13 at 12:51
  • 1
    If you need the filenames echoed to success stream or console you could replace `Copy-Item -Destination "$backupPath\" -Force` with `% { Copy-Item $_.FullName -Destination "$backupPath\" -Force; Write-Output $_.FullName }`. Use `Write-Host` instead of `Write-Output` for echoing to the console (cannot be redirected to an output file). Note that displaying the file names in the console window will considerably reduce performance. – Ansgar Wiechers Sep 09 '13 at 14:07
  • Thanks, Yeah...I noticed performance degradation, but for my testing, I like the added security. My original code above echos filenames...but there's no Write-Host; do you know which section echoed to the console, and is there some implied write-to-console in there? – dwwilson66 Sep 09 '13 at 15:05
  • 1
    `Write-Output` writes to the success output stream (vulgo STDOUT), which can be redirected to a file. `Write-Host` writes to the console, so this output cannot be redirected to a file. Use one or the other depending on your requirements. – Ansgar Wiechers Sep 09 '13 at 16:32