Search code examples
powershellcopy-pastecopy-item

Is there a way to add a postfix to this script?


So I asked here before about helping with a script to copy and paste files from one folder to another.

However, after I was done, I found that some of the files went missing. I had 600,393 files but when I checked my new folder it only had 600,361 files.

I think it may have been overwritten by duplicates even though the naming convention was supposed to stop those kinds of problems.

Here's the script

$destfolder = '.\destfolder\'
Get-ChildItem -Recurse -File .\srcfolder\ |
  Invoke-Parallel {
    $_ | Copy-Item -Destination (
      Join-Path $using:destfolder ($_.directory.parent.name, $_.directory.name, $_.name -join '-') 
    ) -Verbose -WhatIf
  }

(Thanks to the great dudes on r/software, r/Techsupport, and mklement0)

So is there a way to add a postfix that adds a 0 to the name of any file that has the same name as a file already in a folder?

like directory-subdirectory-0-filename.ext

EDIT- Problem is all the files are read-only not hidden, I don't want any hidden files.


Solution

    • Note that Get-ChildItem doesn't include hidden items by default, which may explain at least part of the the discrepancy.

      • Use the -Force switch to include hidden items.
    • Separately / additionally, you can deal with name collisions as follows:

    $destfolder = '.\destfolder\'
    Get-ChildItem -Force -Recurse -File .\srcfolder\ |
      Invoke-Parallel {
        $newName = Join-Path $using:destfolder ($_.directory.parent.name, $_.directory.name, $_.name -join '-')
        # Try to create the file, but only if it doesn't already exist.
        if ($null -eq (New-Item $newName -ErrorAction SilentlyContinue)) {
          # File already exists -> create duplicate with GUID.
          $newName += '-' + (New-Guid)
        }
        $_ | Copy-Item -Destination $newName -Verbose
      }
    

    Note:

    • With multi-threaded execution, assigning sequence numbers to duplicates would be a nontrivial undertaking, as each thread would have to "reserve" a sequence number and ensure that no other thread claims it before copying to a file incorporating this number is complete.

    • To avoid such challenges, the above approach simply appends a - plus a GUID to the target file name.