Creating junctions in repository using PowerShell

I am writing some PowerShell scripts for my own use to handle initializing of repositories and backups…
I prefer to create separate folders for each repository and use NTFS Junctions to point to actual source folders. (It is much easier to manage sources this way while duplicacy insists on using current folder for repository).

But I am running into the issue - PowerShell 5.1 new-Item creates junctions a bit differently compared to mklink command… For the rest of the OS they are the same, but duplicacy does not follow those links!

Here is how to reproduce and see the difference:

c:\temp>powershell
......   
PS C:\temp> & cmd.exe /c mklink /j use-mklink c:\users
Junction created for use-mklink <<===>> c:\users

PS C:\temp> New-Item -ItemType Junction -Path use-new-item -Target c:\users
Directory: C:\temp
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d----l         1/4/2020  11:53 PM                use-new-item

PS C:\temp> & cmd.exe /c dir /l 
......
01/04/2020  11:52 PM    <JUNCTION>     use-mklink [c:\users]
01/04/2020  11:53 PM    <JUNCTION>     use-new-item [\??\C:\users]


(I removed some wasted space from output)
You can see the difference in the dir output - junction, created with New-Item has “??” in front of the target. This breaks duplicacy logic on following symlinks - it will skip such links.

Not sure who’s actual fault this is. On one hand, I’d expect PS to create same links as mklink, but it still creates completely valid, correct and usable links for NTFS, on the other hand, duplicacy has its own logic for handling these and probably was never tested with such links which are created with full absolute path syntax…

Anyone knows how to make New-Item behave the same as mklink? Don’t really want to call mklink when native option exists…

You can instruct New-Item to do exactly that. Use -ItemType SymbolicLink instead of -ItemType Junction.

Example from my own setup:

New-Item -Path "C:\duplicacy repositories\tbp-nuc\C__Users_link" -ItemType SymbolicLink -Value "C:\Users"

This creates Symlink, not Junction:

01/05/2020  03:07 AM    <SYMLINKD>     new-item-symlink [C:\users]
01/04/2020  11:52 PM    <JUNCTION>     use-mklink [c:\users]
01/04/2020  11:53 PM    <JUNCTION>     use-new-item [\??\C:\users]

There are some differences between symlinks and junctions and I’d prefer to have junctions.

Ah, if you must have junctions I’m out of ideas, sorry.

Yeah, junctions are more secure.
The workaround with executing mklink works, I just want to have duplicacy handle PS-created junctions properly - this issue is not easy to troubleshoot and may cause data not being backed up if someone adds new junction to existing repository with PS…
Check the code, I think the fix should be quite simple to check for specific path prefix for junction and ignore it :slight_smile:

I’m gonna be pedantic here but :d: specifies that it only supports top level symlinks and not junctions: Move duplicacy folder/Use symlink repository.

This is more like semantics :slight_smile:
Code has distinct support for both, they are separate types of NTFS reparse points.