Copy files as symlinks and maintain the directory structure on Windows?

I have looked at this question: Recursively copy a directory entirely as symlinks, preserving current symlinks and if I'm reading it right I want to do the same thing but in Windows.

So, I have this:

Dir1\Dir_A\File.ext
Dir1\Dir_A\Dir_A_A\file2.ext
Dir1\Dir_B\File2.ext
...

I want that directory structure to be the exact same on the target directory minus the Dir1 but all the files to be symlinks pointing to the source files. So, I end up with this:

Target_Dir\Dir_A\File.ext <- file is symlink, folders are created
Target_Dir\Dir_A\Dir_A_A\file2.ext <- file is symlink, folders are created
Target_Dir\Dir_B\File3.ext <- file is symlink, folders are created
...

How can I achieve this? I'm also looking for a batch script or something that can be executed on a schedule to copy the new files every so often skipping the already created symlinks, kinda like a synchronization job minus the real copying of the files but instead (sym)linking them.


Solution 1:

PowerShell: Recursive folder copy with symbolic link files

You can use get-childitem to create an array variable and loop over the iterated object properties with some conditional if logic to help create a workable solution for your needs.

Essentially this...

  • creates a source-matching destination folder structure
  • creates a source-matching destination symbolic link file structure pointing to each source-matching file

You only need to set the $src value to point to the source root folder location and the $dest value to point to the root destination folder location—the other logic will do all the rest.

$src = "C:\Source\Folder\"
$dest = "C:\Destination\Folder\"
$src = $src.Replace("\","\\")

$i = Get-ChildItem -LiteralPath $src -Recurse
$i | % { Process {
    $apath = $_.FullName -Replace $src,""
    $cpath = $dest + $apath
    If(!(Test-Path (Split-Path -Parent $cpath))){New-Item -ItemType Directory -Force -Path (Split-Path -Parent $cpath)}
    If(!$_.PSIsContainer){If(!(Get-Item $cpath -ErrorAction SilentlyContinue)){New-Item -Path $cpath -ItemType SymbolicLink -Value ([WildcardPattern]::Escape($_.FullName)) -Force}}
    }}

Supporting Resources

  • Get-ChildItem

  • Arrays

  • ForEach-Object

    Standard Aliases for Foreach-Object: the '%' symbol, ForEach

  • If

  • Test-Path

  • Split-Path

  • Get-Item

  • Common Parameters

    • ErrorAction

      • Control command behavior when an error occurs [enum] Valid values: Continue , Stop, Suspend, SilentlyContinue, Ignore, Inquire. [Enum] e.g. -EA SilentlyContinue will supress errors from being printed to stderr.

  • New-Item