Only Junctions are possible for this
Use SUBST to trick the OS.
It's quite important to use a parent folder with /deny Everyone:(S,RD)
to block the OS from crawling in endless loop while doing maintenance. Like Search, Search indexer, Antivirus, File History, who knows what else.
details and script below
I see you got understanding of most of the following, so let's just sum it up for others.
Symlinks
Directory Sym-links and Junctions are very different things.
The major difference which should concern you is, that you can't access sym-links on remote computer which links to local paths of that remote computer. Sym-link to F:\ on remote computer will try to open local PC's F:\ instead.
Sym-link is like a link file which contains info about the real object's path. You can sym-link to whatever, even relative paths.
You can create a directory sym-link to a nonexistent drive, but that will not help you over LAN
Junction is a NTFS thing. But while a Junction must be on NTFS, it can point to a folder on other FS. It "re-directs" access to the junctioned folder. You can access junctions on remote machines pointing to remote folders.
Watch out for permissions. both of target Directory and Junction. (icacls with /L)
For files, there are file sym-links and hardlinks. There are no hardlinks for Directory, but Junction is quite a close thing to it.
Hardlinks are multiple file records pointing to the same position on a drive.
For that reason, you can't hardlink across drives.
Note: Junctions shouldn't be created to link dynamic places. It's working ok, even if a different FS is mounted as the same letter, but it's not a supported way. You should create a share for each drive. But that would make a mess in Network Locations and there would be no way to control access using permissions.
This is a cut from my customization script. It's portable, put it in a bat file and run as Admin.
- creates Drives share, with Junction points to drives of letters from the whole alphabet. Share Drives will be accessible by any Authenticated user. (not Guest and User without password) Users will have the same access as if logged in locally, but UAC will not come to give elevated access even for Admins.
- creates Download-Private share for current user's Downloads - just remove the section if you don't want it
- Folders of these two Shares are placed in "%PUBLIC%\Private shares" e.g. "c:\Users\Public\Private shares" This folder will be directly inaccessible to avoid background services to end up in a loop. You can still access folders inside it directly by writing full path in address bar, or by creating a windows shortcut to it
- to tweak permissions for the whole folder edit "Private shares", but to tweak for certain drive letters, you must use icacls with /L parameter
echo. & echo === "Private shares"
echo *** Creating Folders
rem --- Private shares - inheriting Authenticated Users access from Public folder
if not exist "%PUBLIC%\Private shares" mkdir "%PUBLIC%\Private shares"
rem - remove DENY temporarily
icacls "%PUBLIC%\Private shares" /remove:d Everyone 2>nul
if not exist "%PUBLIC%\Private shares\Drives" mkdir "%PUBLIC%\Private shares\Drives"
echo *** Creating Downloads-Private share
echo * Creating link
mklink /J "%PUBLIC%\Private shares\Downloads-%USERNAME%" "%USERPROFILE%\Downloads"
echo * Creating shares
net share Downloads-Private /delete 2>nul
net share Downloads-Private="%PUBLIC%\Private shares\Downloads-%USERNAME%" /unlimited /remark:"Only for authenticated users" /grant:everyone,FULL
echo *** Creating Drives share
echo * Creating link
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
subst %%a: \
mklink /J "%PUBLIC%\Private shares\Drives\%%a" %%a:\
subst %%a: /d
)
echo * Creating shares
net share Drives /delete 2>nul
rem - /grant:everyone,FULL --- No worry, this is on Microsoft's recommendation. Grant full access to shares and handle access through permissions. It's more portable, safer and simpler.
net share Drives="%PUBLIC%\Private shares\Drives" /unlimited /remark:"Only for authenticated users" /grant:everyone,FULL
echo *** Changing "Private share" permissions
rem - this is the same way as Windows is handling legacy folders inside Users directory
rem this must be done, or many services will keep crawling though an endless path loop
icacls "%PUBLIC%\Private shares" /deny Everyone:(S,RD)
If you need to remove the folder which is created using this script, you need to unlock it using Properties-Permission, or by this command run as Admin: icacls "%PUBLIC%\Private shares" /remove:d Everyone
Don't keep this folder unlocked, delete it right after, or lock it again using icacls "%PUBLIC%\Private shares" /deny Everyone:(S,RD)
EDIT 2019: I am using PowerShell for this now. This is the part, which creates all drives shares (it does nearly the same as Batch above):
$aclFSR_Syn_ReadData = [System.Security.AccessControl.FileSystemRights]::Synchronize -bor [System.Security.AccessControl.FileSystemRights]::ReadData
$aclInh_None = [System.Security.AccessControl.InheritanceFlags]::None
$aclProp_NoFlags = [System.Security.AccessControl.PropagationFlags]::None
$aclT_Deny = [System.Security.AccessControl.AccessControlType]::Deny
$aclRule_Interactive_SRD_NoInh_Deny = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList 'INTERACTIVE', $aclFSR_Syn_ReadData, $aclInh_None, $aclProp_NoFlags, $aclT_Deny
$PathPrivate = 'C:\PATH\TO\SHARED_LOCAL_FOLDER
$aclDrives = Get-Acl -Path "$PathPrivate\Drives"
# - remove DENY temporarily
[void]$aclDrives.RemoveAccessRuleAll($aclRule_Interactive_SRD_NoInh_Deny)
Set-Acl -Path "$PathPrivate\Drives" -AclObject $aclDrives
# --- Drives Share
Write-Host "`n - Drives Share"
Write-Host "Linking drives: " -NoNewline
foreach ($d in @("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")) {
Write-Host "$d, " -NoNewline
if (-not (Get-PSDrive -Name $d -ErrorAction SilentlyContinue)) {
New-PSDrive -Name $d -PSProvider FileSystem -Root '\' | Out-Null
$tmpDrive = $true
} else { $tmpDrive = $false }
if (-not (Test-Path -Path "$PathPrivate\Drives\$d")) { New-Item -Path "$PathPrivate\Drives\$d" -ItemType Junction -Value "${d}:\" | Out-Null }
if ($tmpDrive) { Remove-PSDrive -Name $d }
}
Write-Host ''
Remove-SmbShare -Name 'Drives' -Confirm:$false -ErrorAction SilentlyContinue
New-SmbShare -Name 'Drives' -Path "$PathPrivate\Drives" -Description 'Only for authenticated users' -FullAccess Everyone | Out-Null
Write-Host "Applying permissions for Drives"
# - Blocking access to Private share folder to avoid searcher loops
[void]$aclDrives.AddAccessRule($aclRule_Interactive_SRD_NoInh_Deny)
# - limit access to authorized accounts only (optional)
# [void]$aclDrives.AddAccessRule($YOUR_ACL_RULE_TO_LIMIT_THE_SHARE)
Set-Acl -Path "$PathPrivate\Drives" -AclObject $aclDrives