当我尝试创建到尚不存在的 Windows 驱动器的目录连接时,收到以下消息:
C:\>mklink H H:\ /J
Local volumes are required to complete the operation.
我希望在 Windows 上有一个目录,将每个驱动器号连接到该目录中的相应字母。我希望通过应用程序共享来自任何外部设备的媒体,而无需在出现“新”驱动器号时更改设置。
符号链接似乎可以指向不存在的目标,因为操作系统不会检查目标是否存在,但它们无法链接到不存在的驱动器。是否有任何已知的解决方案来设置这样的目录连接?
一种解决方案是创建一个目录符号链接(通过使用 /D 标志而不是 /J 标志),但这不是我想要的,我想要一个目录连接点。
答案1
只有连接才有可能
使用 SUBST 来欺骗操作系统。
这很重要的使用父文件夹来/deny Everyone:(S,RD)
阻止操作系统在维护期间无限循环地爬行。例如搜索、搜索索引器、防病毒、文件历史记录,谁知道还有什么。
详细信息和脚本如下
我看到您已经了解了下面的大部分内容,所以让我们为其他人总结一下。
符号链接
目录符号链接和连接点是非常不同的东西。
您应该关注的主要区别是,您无法访问远程计算机上链接到该远程计算机本地路径的符号链接。远程计算机上到 F:\ 的符号链接将尝试打开本地 PC 的 F:\。
符号链接就像一个链接文件,其中包含有关真实对象路径的信息。您可以将符号链接到任何内容,甚至是相对路径。
您可以创建指向不存在驱动器的目录符号链接,但这不会帮助您通过 LAN
连接点是 NTFS 的东西。但是,虽然连接点必须位于 NTFS 上,但它可以指向其他 FS 上的文件夹。它“重定向”对连接文件夹的访问。您可以访问指向远程文件夹的远程计算机上的连接点。
注意权限。目标目录和连接点的权限。(带有 /L 的 icacls)
对于文件,有文件符号链接和硬链接。Directory 没有硬链接,但 Junction 与之非常接近。硬链接是指向驱动器上同一位置的多个文件记录。因此,您无法跨驱动器进行硬链接。
注意:不应创建连接点来连接动态位置。即使不同的 FS 以相同的字母安装,它也能正常工作,但这不是受支持的方式。您应该为每个驱动器创建一个共享。但这会使网络位置变得混乱,并且无法使用权限来控制访问。
这是从我的自定义脚本中截取的。它是可移植的,将其放入 bat 文件中并以管理员身份运行。
- 创建 Drives 共享,Junction 指向整个字母表中的字母驱动器。任何经过身份验证的用户都可以访问共享驱动器。(不包括来宾和没有密码的用户)用户将拥有与本地登录相同的访问权限,但 UAC 不会授予管理员更高的访问权限。
- 为当前用户的下载创建下载私人共享 - 如果你不想要它,只需删除该部分
- 这两个共享的文件夹位于“%PUBLIC%\Private shares”中,例如“c:\Users\Public\Private shares”。此文件夹将直接无法访问,以避免后台服务陷入循环。您仍然可以通过在地址栏中输入完整路径或创建 Windows 快捷方式来直接访问其中的文件夹
- 要调整整个文件夹的权限,请编辑“私人共享”,但要调整某些驱动器号的权限,必须使用带有 /L 参数的 icacls
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)
如果你需要去除使用此脚本创建的文件夹,您需要使用“属性-权限”将其解锁,或者通过此命令以管理员身份运行:icacls "%PUBLIC%\Private shares" /remove:d Everyone
不要让此文件夹保持解锁状态,然后立即删除它,或者使用以下命令再次锁定它icacls "%PUBLIC%\Private shares" /deny Everyone:(S,RD)
EDIT 2019:我现在正在使用 PowerShell。这是创建所有驱动器共享的部分(它的作用几乎与上面的批处理相同):
$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