Sim*_*her 4 windows symbolic-link external-hard-drive
当我尝试创建到尚不存在的 Windows 驱动器的目录连接时,我收到以下消息:
C:\>mklink H H:\ /J
Local volumes are required to complete the operation.
Run Code Online (Sandbox Code Playgroud)
我想在 Windows 上有一个目录,将每个驱动器号连接到该目录中的相应字母。我想通过应用程序共享任何外部设备的媒体,而无需在“新”驱动器号出现时更改设置。
符号链接似乎可以指向不存在的目标,因为操作系统不会检查目标是否存在,但它们无法链接到不存在的驱动器。是否有任何已知的解决方案来设置此类目录连接?
一种解决方案是创建目录符号链接(通过使用 /D 标志而不是 /J 标志),但这不是我想要的,我想要一个目录连接。
只能使用连接点来
使用 SUBST 来欺骗操作系统。在进行维护时,使用父文件夹来阻止操作系统无限循环爬行
非常重要。/deny Everyone:(S,RD)比如搜索、搜索索引器、防病毒、文件历史记录,谁知道还有什么。
详细信息和脚本如下
我发现您已经了解了以下大部分内容,所以让我们为其他人总结一下。
符号链接
目录 符号链接和连接点是非常不同的东西。
您应该关心的主要区别是,您无法访问远程计算机上链接到该远程计算机的本地路径的符号链接。到远程计算机上的 F:\ 的符号链接将尝试打开本地 PC 的 F:\。
符号链接就像一个链接文件,其中包含有关真实对象路径的信息。您可以符号链接到任何内容,甚至是相对路径。
您可以创建一个指向不存在的驱动器的目录符号链接,但这对您通过 LAN 没有帮助
Junction是 NTFS 的东西。但是,虽然连接点必须位于 NTFS 上,但它可以指向其他 FS 上的文件夹。它“重定向”对联结文件夹的访问。您可以访问远程计算机上指向远程文件夹的联结。
注意权限。目标目录和连接点。(带有 /L 的 icacls)
对于文件,有文件符号链接和硬链接。Directory 没有硬链接,但 Junction 与它非常接近。硬链接是指向驱动器上同一位置的多个文件记录。因此,您无法跨驱动器进行硬链接。
注意:不应创建连接点来链接动态地点。即使将不同的 FS 安装为相同的字母,它也可以正常工作,但这不是受支持的方式。您应该为每个驱动器创建一个共享。但这会使网络位置变得混乱,并且无法使用权限来控制访问。
这是我的自定义脚本的剪辑。它是可移植的,将其放入bat 文件中并以管理员身份运行。
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)
Run Code Online (Sandbox Code Playgroud)
如果您需要删除使用此脚本创建的文件夹,则需要使用“属性”-“权限”来解锁它,或者通过以下命令以管理员身份运行:icacls "%PUBLIC%\Private shares" /remove:d Everyone
不要保持此文件夹解锁,立即删除它,或使用以下命令再次锁定它:icacls "%PUBLIC%\Private shares" /deny Everyone:(S,RD)
编辑 2019:我现在正在使用 PowerShell 执行此操作。这是创建所有驱动器共享的部分(它的作用与上面的 Batch 几乎相同):
$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
Run Code Online (Sandbox Code Playgroud)