适用场景
本教程适合在 Windows Server 2019、2022 或 2025 上,为一个已经存在的域安全组或本机安全组建立新的部门文件共享。成果是:普通成员可以读取、创建和修改文件,管理员保留完全控制,未获授权的用户不会因为访问枚举而看到无权进入的内容。操作对象必须是新建的空目录;如果要接管已有数据目录,应先审计继承关系、所有者和现有访问控制项,不要直接套用本教程的重置命令。
不要把 SMB 端口直接发布到互联网,也不要通过给所有人完全控制来临时解决权限问题。远程操作前应保留本地控制台或带外管理入口,并安排维护窗口。
原理
Windows 文件共享有两层授权。共享权限决定用户能否通过 SMB 进入共享,NTFS 权限决定用户能否读取、写入、删除具体文件。远程访问时两层都会生效,实际能力受更严格的一层限制。因此,只配置共享权限或只配置文件夹安全权限,都会留下难以解释的访问结果。
访问控制项可以继承给子目录和文件。(OI) 表示对象继承,(CI) 表示容器继承,M 表示修改,F 表示完全控制。本教程不给普通组完全控制,因为完全控制还允许修改权限和所有权。基于访问的枚举只隐藏用户无权访问的项目,它不是额外授权机制。SMB 加密保护传输内容,但不能代替身份验证、NTFS 权限和备份。
准备工作
确认文件服务器已安装并启用 SMB 文件共享能力,已有一个专门用于授权的安全组,并且管理员清楚服务器本地路径和唯一的共享名称。不要在命令中输入账号密码。打开开始菜单(Start menu),以管理员身份启动 Windows PowerShell(Windows PowerShell)。先设置三个变量:
$ShareName = '<共享名>'
$Path = '<本地文件夹完整路径>'
$GroupName = '<域或本机安全组名>'
$Admins = (New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544')).Translate([System.Security.Principal.NTAccount]).Value
<共享名> 是客户端看到的名称;<本地文件夹完整路径> 是服务器本地的新目录;<域或本机安全组名> 是已由管理员建立并审核成员的组。尖括号内都是占位符,必须替换,但不要把密码或密钥放入变量。最后一行用内置管理员组的固定 SID 解析本地化名称,避免中英文系统名称不同。
分步骤操作
- 先确认目标没有重名,路径也不是现有业务目录:
Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue
Test-Path -LiteralPath $Path
([System.Security.Principal.NTAccount]$GroupName).Translate([System.Security.Principal.SecurityIdentifier])
第一条和第二条预期都不返回现有对象;第三条应返回一个 SID,表示组名可解析。如果共享或路径已经存在,停止并换用经批准的新名称,不要覆盖。
- 创建空目录并设置 NTFS 权限:
New-Item -ItemType Directory -Path $Path
icacls $Path /inheritance:r
icacls $Path /grant:r '*S-1-5-18:(OI)(CI)F' '*S-1-5-32-544:(OI)(CI)F' ($GroupName + ':(OI)(CI)M')
/inheritance:r 删除从父目录继承的访问项,所以只适用于刚创建且为空的专用目录。后续命令保留系统账户和内置管理员完全控制,并给授权组修改权限。每条命令都应显示成功处理;若出现账户映射失败,不要改用 Everyone,应回头检查组名及服务器与域的连接。
- 创建共享并同时设置共享层权限:
New-SmbShare -Name $ShareName -Path $Path -ChangeAccess $GroupName -FullAccess $Admins -FolderEnumerationMode AccessBased -EncryptData $true
ChangeAccess 允许授权组通过 SMB 修改内容;FullAccess 只授予管理员组;AccessBased 启用基于访问的枚举;EncryptData 要求此共享使用 SMB 加密。正式启用加密前,应确认客户端支持 SMB 3.x。仍在使用不支持加密的旧客户端时,应先完成升级,而不是为整个服务器关闭安全能力。
- 查看两层权限和共享属性:
Get-SmbShare -Name $ShareName | Format-List Name,Path,ShareState,FolderEnumerationMode,EncryptData
Get-SmbShareAccess -Name $ShareName
icacls $Path
输出中的路径必须等于目标目录,共享状态应在线,枚举模式应为 AccessBased,加密应为 True。共享访问列表和 icacls 结果中不应意外出现宽泛的普通用户组。
- 从一台受管客户端用文件资源管理器(File Explorer)打开:
\\<服务器名称>\<共享名>
<服务器名称> 和 <共享名> 是占位符,应分别替换为实际服务器 DNS 名称和刚创建的共享名。使用已属于授权组的日常账户测试,不要临时分享管理员凭据。创建一个无敏感内容的测试文件,修改后关闭,再删除它;随后用未授权的受管测试账户确认访问被拒绝。
验证方法
验证需要同时覆盖正向和反向结果。授权组成员应能列目录、创建、修改和删除自己的测试文件,但不能修改目录权限;管理员应能维护权限;未授权账户应无法打开共享。服务端执行以下只读命令观察连接:
Get-SmbSession
Get-SmbOpenFile
确认客户端连接到了预期服务器和共享,并在测试结束后关闭文件。还应检查备份任务是否包含新目录,因为共享建立成功并不意味着数据已经受备份保护。
常见错误
出现拒绝访问时,先分别检查 Get-SmbShareAccess 和 icacls,不要反复叠加授权。用户刚加入域组后,现有登录令牌可能还没更新,注销再登录比重启服务器更合适。能列目录却不能写入,通常是共享层或 NTFS 层只有读取权限。名称能解析但连接失败时,再检查 DNS、TCP 445、防火墙策略和文件服务器服务。旧客户端启用加密后无法连接,多半是协议能力不足,不应通过启用 SMB1 解决。显式拒绝项优先级高,初学者不应随意增加 Deny 项。
安全与回退
不要向互联网开放 TCP 445,不要启用来宾访问,也不要把个人账户直接散落在权限列表中;用安全组管理成员更易审计。修改共享前查看是否有会话和打开文件,避免用户缓存尚未写回时强制断开。
若测试失败并决定撤销,先让客户端关闭文件,再执行:
Get-SmbSession
Get-SmbOpenFile
Remove-SmbShare -Name $ShareName
Remove-SmbShare 只删除共享定义,不会删除目录内的数据,但会断开仍在使用该共享的客户端,因此必须确认无活动写入并阅读确认提示。若目录始终为空,可在确认 $Path 精确无误后通过文件资源管理器删除;若已有数据,先保留目录和权限,完成数据备份与迁移后再处理。不要为了回退而递归删除不确定的路径。
参考资料与转载说明
本文依据上述公开资料进行中文原创整理,不是逐句翻译,也不替代厂商手册。操作前请核对自己的版本、型号和备份。
评论一下?