ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

域文件服务器共享盘配置:AD权限、GPO驱动器映射与排错

域文件服务器共享盘配置:AD权限、GPO驱动器映射与排错

简介:《域文件服务器设置-共享盘》面向企业IT管理员和Server 2016初学者,聚焦域环境下共享盘的规划与配置,解决AD组织单位、用户组、共享权限与登录自动映射之间的衔接问题。压缩包仅含1个doc文件,约468KB,内容集中,便于按步骤对照查阅。文档涵盖在AD中创建OU、用户和组,将文件服务器加入域并建立共享文件夹、分配NTFS权限,以及借助bat脚本、net use命令、共享文件夹对象、GPO驱动器映射和登录脚本,实现域用户登录后自动连接共享盘。已有375人学习,适合需要梳理域共享盘部署流程、权限分配思路和组策略映射方案的管理员参考,也可作为实验搭建与排错速查材料。

1. 域内共享盘为什么总在“某个同事的电脑上”失效

周一早上八点四十,财务的同事在群里说 Z 盘没了,手里那张表还开着,保存直接报错。这种事在域环境里一个月总要来一次:域文件服务器上的共享盘本身没坏,坏的是映射那一环——登录脚本没跑起来、GPO 没轮到这台机器、盘符被另一条策略先占了,甚至只是用户上周手动连过一次别的路径。这篇就把一套域文件服务器共享盘的配置从头拆到尾:在 Windows Server 2016 上把 AD 的 OU、用户、安全组建好,文件服务器加域、共享目录按组授权,再落到登录脚本和 GPO 驱动器映射两条路线的具体参数,最后是我自己翻过车的几个地方。适合正在给公司搭公共盘、或者接手一套前人留下的映射策略、每次排查只能靠“重启试试”的同行。

2. 先把 AD 底座打牢:OU、用户组与按组授权的共享目录

2.1 OU 与安全组的分层,决定后面能不能“一次改全公司”

很多人上来就在域根下建用户、建共享,跑通了就算完。等到第三个部门要加盘、第五个人调岗,才发现权限是一锅粥:每个人在 NTFS 上都挂了显式 ACE,谁走谁留全靠翻记录。合格的做法是先定 OU 骨架,再定组模型,最后才是共享目录。OU 的作用不只是“装用户”,它还是 GPO 的链接点——你后面那条驱动器映射策略要链到用户所在的 OU 上,OU 分得清楚,策略才能只对需要的人生效,登录时也不用每个用户都把全公司的策略处理一遍。

组模型我一般用 AGDLP 的简化版,单域小环境也够用:用户账户(A)加入全局组(G),全局组加入域本地组(DL),域本地组去拿 NTFS 权限(P)。多一层看着啰嗦,但好处很实在——全局组的成员可以来自任何域,域本地组只在本域授权,将来公司合并、加个子域,权限那一层不用动。命名上带资源和权限,比如GG-财务-读写、DL-FS01-财务-读写,看到名字就知道它该挂在哪个目录上。

下面这段在域控上跑,把 OU、组、用户一次性建出来。域名用example.local,实际替换成你自己的;IP 段是文档保留地址,照抄前先改成你环境里的。

# 在域控 DC01 上以域管理员身份运行 Import-Module ActiveDirectory $root = "OU=example,DC=example,DC=local" $ous = @("Users","Users\财务","Users\研发","Users\行政","Groups","Groups\GG","Groups\DL","Computers","Servers") foreach ($o in $ous) { $dn = "OU=" + ($o -replace '\\', ',OU=') + "," + $root if (-not (Get-ADOrganizationalUnit -LDAPFilter "(distinguishedName=$dn)" -ErrorAction SilentlyContinue)) { New-ADOrganizationalUnit -Name ($o -split '\\')[-1] -Path (Split-Path $dn -Parent) -ProtectedFromAccidentalDeletion $true } } # 组:全局组装人,域本地组装权限 New-ADGroup -Name "GG-财务-读写" -GroupScope Global -Path "OU=GG,OU=Groups,$root" New-ADGroup -Name "GG-研发-读写" -GroupScope Global -Path "OU=GG,OU=Groups,$root" New-ADGroup -Name "GG-全员-只读" -GroupScope Global -Path "OU=GG,OU=Groups,$root" New-ADGroup -Name "DL-FS01-财务-读写" -GroupScope DomainLocal -Path "OU=DL,OU=Groups,$root" New-ADGroup -Name "DL-FS01-研发-读写" -GroupScope DomainLocal -Path "OU=DL,OU=Groups,$root" New-ADGroup -Name "DL-FS01-全员-只读" -GroupScope DomainLocal -Path "OU=DL,OU=Groups,$root" # 全局组进域本地组 Add-ADGroupMember -Identity "DL-FS01-财务-读写" -Members "GG-财务-读写" Add-ADGroupMember -Identity "DL-FS01-研发-读写" -Members "GG-研发-读写" Add-ADGroupMember -Identity "DL-FS01-全员-只读" -Members "GG-全员-只读"

逐段说一下逻辑。第一段遍历 OU 列表,注意-Path必须是已存在的父容器,所以我按层级顺序排了数组,父级先建;ProtectedFromAccidentalDeletion打开,防止有人在图形界面里手滑删掉整个部门。第二段建六类组,全局组和域本地组分开放在两个 OU 里,是为了后面做 GPO 的时候能用 OU 圈定范围。第三段把全局组塞进域本地组,这一步走完,以后新员工入职只需要Add-ADGroupMember -Identity "GG-财务-读写" -Members "新账号",权限自动继承,不用碰文件服务器。

提示:如果环境里已经有历史遗留的“用户直接挂 NTFS 权限”,不要一次性全删。先并到组里,观察一到两周,再用脚本清理孤儿 ACE,不然总有人第二天打不开文件。

2.2 文件服务器加域与共享权限、NTFS 权限的叠加规则

文件服务器 FS01 装完 Windows Server 2016,改好计算机名、配好静态地址和 DNS 指向域控,然后加域重启。这一步的顺序不能反:先配 DNS 再Add-Computer,否则加域时报“找不到域”十有八九是 DNS 指到了路由器。加域完成后,把 FS01 的计算机账户挪到OU=Servers下,方便后面按 OU 下发服务器侧的策略。

接下来是权限模型,这里是最容易埋雷的地方。SMB 共享权限和 NTFS 权限是取交集的:共享给了 Read,NTFS 给 Modify,最终用户只能读;共享给了 Full,NTFS 给 Modify,最终是 Modify。微软的推荐做法是共享权限放宽到Authenticated Users更改,把精细控制全压在 NTFS 上,理由很实际——共享权限颗粒度粗,改一次要断开重连,而 NTFS 可以精确到子目录、可以继承、可以用icacls批量刷。

我一般这样落地:共享层给Domain Admins完全控制、Authenticated Users更改;NTFS 层禁用继承、移掉默认的Users读、再给对应的DL-FS01-*组授权。

# 建目录 New-Item -Path "D:\Share\Finance" -ItemType Directory -Force New-Item -Path "D:\Share\RD" -ItemType Directory -Force New-Item -Path "D:\Share\Public" -ItemType Directory -Force # 共享层:显式写全,别依赖默认值 New-SmbShare -Name "Finance" -Path "D:\Share\Finance" ` -FullAccess "EXAMPLE\Domain Admins" ` -ChangeAccess "EXAMPLE\Authenticated Users" ` -FolderEnumerationMode AccessBased # NTFS 层:断继承、清掉 Users、按组给 Modify icacls "D:\Share\Finance" /inheritance:d icacls "D:\Share\Finance" /remove:g "EXAMPLE\Users" "EXAMPLE\Authenticated Users" icacls "D:\Share\Finance" /grant "EXAMPLE\DL-FS01-财务-读写:(OI)(CI)(M)" icacls "D:\Share\Finance" /grant "EXAMPLE\DL-FS01-全员-只读:(OI)(CI)(RX)"

icacls那四行的含义分别是:/inheritance:d禁用继承并把当前继承来的 ACE 复制成显式条目(不是删掉,删掉用:r,那个更危险);/remove:g摘掉从 D 盘继承下来的Users读权限,这一步不做,全公司都能读财务目录;(OI)(CI)表示对象继承和容器继承,新加的子文件夹自动带上;(M)是修改,(RX)是读取和执行。-FolderEnumerationMode AccessBased打开了 ABE,用户看不到自己没有权限的子文件夹——这个功能在老员工眼里像“目录消失了”,上线前要跟业务打招呼。

参数上还有两个值得注意的点。一是New-SmbShare如果你不写-FullAccess/-ChangeAccess/-ReadAccess,默认共享 ACL 未必是你想要的那套,显式写全最稳。二是 Windows Server 2016 上建议直接关掉 SMB1,这条对勒索软件横向移动的遏制效果比装杀毒软件实在:

Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EnableSMB2Protocol, EncryptData

EncryptData默认是关的。开它会要求客户端至少 SMB3,老旧的扫描仪、NAS 一体机可能直接连不上,所以我在生产上一般是先开一台测试共享观察一周,再全量。

2.3 共享目录骨架与“权限不靠人、只靠组”的落地检查

目录骨架建议一次规划到位,后面加部门只是加子目录,不动根。我习惯按“资源 + 权限层级”两层:根下按业务分(Finance、RD、Public),每个业务目录下再分01-共享、02-归档、03-个人,归档给只读,个人目录用%USERNAME%加 ABE 隐藏。这样做的好处是备份策略、配额策略、审计策略都能按目录批量套,不用一个个点。

配完必须验,不能靠“我觉得应该对了”。下面三条命令分别看共享 ACL、NTFS 上还有没有漏网的Users、以及某个测试账号的实际有效权限。

# 1. 共享层 Get-SmbShareAccess -Name "Finance" | Format-Table Name, AccountName, AccessControlType, AccessRight -AutoSize # 2. NTFS 层:捞出所有 Users / Everyone 的 ACE,包括继承来的 Get-ChildItem "D:\Share" -Directory | ForEach-Object { $p = $_.FullName (Get-Acl $p).Access | Where-Object { $_.IdentityReference -match 'Users|Everyone|Authenticated' } | Select-Object @{n='Path';e={$p}}, IdentityReference, FileSystemRights, IsInherited } # 3. 有效权限(需要 RSAT,在管理机上跑) (Get-Acl "\\FS01\Finance").Access | Where-Object { $_.IdentityReference -like "*DL-FS01*" } | Format-Table IdentityReference, FileSystemRights, AccessControlType

第二条命令是我每次交付前必跑的一条。血泪经验:共享权限设得再漂亮,只要 NTFS 上还留着一条继承自D:\的BUILTIN\Users:(RX),整个部门目录就是全员可读,而且图形界面里翻三层才看得到。第三条严格说不算“有效权限”计算,只是把 ACL 里的组条目列出来,真要算有效权限得用Effective Access选项卡或者Get-Acl配合组展开,但在排查“为什么他能进”的时候,先看组条目通常已经够了。

注意:加域后的文件服务器,本地组Users里仍然包含NT AUTHORITY\Authenticated Users,而域用户访问共享时就是 Authenticated Users 身份。所以“我把域用户从本地 Users 组踢了”这种操作没有任何意义。

3. 登录脚本还是 GPP 驱动器映射:两条路线的取舍与写法

3.1 net use 登录脚本的参数细节与幂等写法

net use是最老也最可控的一条路。它的优势是逻辑透明、能写判断、能记日志、出问题一眼看出是哪一行;劣势是脚本本身没有“重试”和“清理”机制,写得不严谨就会在用户机器上留一堆半死不活的连接。判断标准很简单:如果只需要“把固定几个盘映射给固定几组人”,GPP 更省事;如果映射前要先探测网络、按计算机名分流、映射失败要写日志给桌面支持看,那就写脚本。

一段能上生产的登录脚本大概长这样:

@echo off setlocal set LOG=%TEMP%\logon_fs01_%USERNAME%.log echo [%DATE% %TIME%] user=%USERNAME% computer=%COMPUTERNAME% server=%LOGONSERVER% >> "%LOG%" rem 先清掉可能残留的同盘符连接,避免 1219 net use Z: /delete /y >nul 2>&1 rem /persistent:no 是关键:不写进注册表,避免换服务器后指向旧路径 net use Z: "\\FS01\Finance" /persistent:no >> "%LOG%" 2>&1 if errorlevel 1 echo Z: 映射失败,错误码=%errorlevel% >> "%LOG%" net use Y: "\\FS01\Public" /persistent:no >> "%LOG%" 2>&1 if errorlevel 1 echo Y: 映射失败,错误码=%errorlevel% >> "%LOG%" endlocal exit /b 0

关键参数逐个说。/persistent:no是这段脚本里最重要的一行,它决定映射关系不写入HKCU\Network;如果不写这个参数,用户在 A 服务器时期映射的 Z 盘会一直跟着他的账户漫游,等服务器换成 B,盘符还指着旧 UNC,现象就是“点开报错但net use里看着有”。/delete /y放在前面是为了幂等,/y静默确认,不加会卡在交互提示上,用户登录界面就一直转圈。exit /b 0保证脚本即使中间失败也返回 0,避免登录过程被判定为失败而弹出“登录脚本执行失败”的提示框——这个框一出来,用户第一反应就是打电话。

错误码要背下来几个:5拒绝访问(多半是 NTFS 或共享权限没给到组)、53找不到网络路径(DNS 或网络不通)、67网络名找不到(共享名拼错)、1219同一服务器已用不同凭据连接、1311没有可用的登录服务器。脚本里把%errorlevel%打进日志,桌面支持拿到日志就能定位,不用远程连过去猜。

3.2 GPP 驱动器映射的 Action、Reconnect 与组过滤

组策略首选项里的驱动器映射,位置在用户配置 > 首选项 > Windows 设置 > 驱动器映射。它的好处是图形化、能按组过滤、能带标签、能设置“首次可用时连接”,而且不需要写代码;坏处是屏蔽了细节,很多人在 Action 那一栏随手选个 Create 就发布,后面改路径不生效,回头查半天。

Action 有四个值,差别必须搞清楚。Create只在盘符不存在时创建,已存在就跳过——所以你把 UNC 从旧服务器改成新服务器,用户机器上一点反应都没有。Replace先删后建,每次登录都断一次重连,用户正在编辑的 Excel 会掉线。Update是改属性但保留已有连接,路径变了会更新,路径没变就不动,这是生产上最常用的。Delete用于下线旧盘。我的习惯是:新盘上线用Create,稳定后统一改Update,下线盘单独建一条Delete策略并保留一个季度再删。

Reconnect勾选框等价于/persistent:yes,会在客户端保留重连记录。域内环境我一般勾上,因为笔记本带出公司再带回来,重连能省一次手动操作;但前提是 UNC 用的是主机名而不是 IP,DNS 得靠谱。

组过滤不要用 GPO 的“安全筛选”去做,用 GPP 自带的 Item-Level Targeting。在驱动器映射条目的共同选项卡里勾选“目标”,加一条“安全组成员身份”,填EXAMPLE\DL-FS01-财务-读写。这样做的好处是:GPO 本身仍然对 OU 里所有人可读可应用,只是这一条映射项按组判断,日志里不会出现“策略被筛选掉”的假象。反过来,如果你直接在 GPO 的安全筛选里把Authenticated Users删掉、只留一个业务组,很容易把计算机账户的读取权限一起削掉,后面会讲这个坑。

还有一处容易被忽略:用户配置 > 管理模板 > 系统 > 组策略 > 驱动器映射下面有个“不处理慢速网络连接上的驱动器映射”。分支机构的链路一慢,这条策略就会让映射整体跳过,而用户在总部测试一切正常。

3.3 两者的执行顺序和混用代价

登录脚本和 GPP 驱动器映射不是互斥的,很多存量环境里两条都在跑,然后就有了“同一台机器上有人有 Z 盘有人没有”的玄学。原因是执行顺序:组策略的客户端扩展按固定顺序处理,脚本(Scripts)在首选项(Preferences)之前执行。也就是说,脚本先跑,GPP 后跑;如果两边都映射 Z 盘且路径不同,最终生效的是 GPP 那条,脚本那 20 秒里用户看到的盘符会闪一下再变。

更麻烦的是盘符抢占。两台文件服务器、三条 GPO、四个部门,如果没人做盘符规划表,迟早出现“财务的 Z 是 Finance,研发的 Z 是 RD”,谁先应用谁赢,输的那个用户每次登录结果都可能不一样。我见过最离谱的一次是同一个用户在会议室和工位上盘符内容不同,因为会议室那台机器缓存了另一条策略。

所以结论很直接:一个盘符只允许一条路径,一条路径只允许一种下发方式。要么全走 GPP,要么全走脚本。迁移期可以两条并存,但必须用不同的盘符字母,并且在下发前把规划表贴到变更单上。脚本里也可以加一道防御,先判断盘符是不是已经被 GPP 占了:

rem 如果 Z: 已存在且指向的不是 FS01,就先不动它,交给 GPP 处理 net use Z: 2>nul | find /i "\\FS01\Finance" >nul if errorlevel 1 ( echo Z: 已被其他路径占用,跳过 >> "%LOG%" goto :next )

这段逻辑的价值不在于多聪明,而在于把“冲突”写进日志而不是变成用户面前的随机现象。

4. GPO 落地:从 AD 发布共享到 OU 链接的完整配置

4.1 在 AD 中发布共享文件夹对象

AD 里那个“共享文件夹”对象,很多人以为它就是映射,其实不是。它只是在目录里登记一个 UNC 路径,让用户在“网络位置”或者老式“网上邻居”里能浏览到,双击打开,不占盘符、不做持久连接。适用的场景是“偶尔访问、不需要固定盘符”的公共资料,比如制度文件、软件安装包。

操作路径:域控上打开“Active Directory 用户和计算机”,定位到目标 OU(比如OU=Users,OU=财务),右键新建 → 共享文件夹,名称填Finance,网络路径填\\FS01\Finance。注意路径里不要带盘符,也不要带尾部反斜杠。建完之后在对象属性里可以设关键字,方便用户搜索。

这个对象的实际价值有限,但它有一个好处:路径变更时只改这一处,用户侧的“网络位置”快捷方式跟着变。如果你全部走盘符映射,那就跳过这步,别为了“看起来完整”硬加一个对象,后面还要维护两套路径。

4.2 新建 GPO、链接 OU 与安全筛选

GPO 的新建和链接在“组策略管理”里做。关键点是链接位置:驱动器映射属于用户配置,所以 GPO 必须链到用户账户所在的 OU,链到计算机 OU 上不会生效(除非开了环回处理)。我一般一个部门一条 GPO,命名GPO-用户-驱动器映射-财务,链接到OU=财务,这样财务的人调岗到研发,OU 一动,盘符自动换。

安全筛选的默认值是Authenticated Users拥有“读取”和“应用组策略”,这个默认值不要动。想只让某个组生效,正确姿势是在 GPP 条目里做 Item-Level Targeting,前面已经说过。如果业务上确实要求“这条 GPO 只对某组可见”,那在移除Authenticated Users之后,必须手动给Domain Computers加“读取”权限,否则计算机会在启动时报告“无法访问组策略对象”,事件日志里是一串 1058。这个坑在微软的安全公告之后变得尤其常见,很多老教程还在教人“删掉 Authenticated Users 只留业务组”,照着做就会翻车。

还有两个提速的细节。一是这条 GPO 里只保留用户配置,把计算机配置下的东西全部禁用(右键 GPO → 属性 → 常规里没有直接开关,是在 GPMC 的“详细信息”里看),减少客户端处理量。二是如果 OU 里挂了多条 GPO,注意链接顺序,数字小的优先级高,同一条设置多处定义时以高优先级为准。

4.3 登录脚本在 GPO 中的放置与 SYSVOL 路径

如果选脚本路线,脚本文件必须放在所有域用户登录时都能读到的地方。标准位置是\\example.local\SYSVOL\example.local\scripts\,这个目录默认对Authenticated Users可读,不用额外授权。挂载位置在 GPO 的用户配置 > 策略 > Windows 设置 > 脚本(登录/注销),双击“登录”→ 添加 → 浏览到那个 UNC 路径选中 bat 文件。

这里有两个实操细节。第一,通过 GPMC 的浏览对话框添加脚本时,系统会把文件复制一份到该 GPO 自己的User\Scripts\Logon\{GUID}\目录下,所以你在 SYSVOL 根下改了文件,GPO 里跑的可能还是旧副本——改脚本一定要回到 GPMC 里重新浏览添加,或者直接改 GPO 目录下那份。第二,bat 文件的编码要用 ANSI(GBK)或者 UTF-8 无 BOM。带 BOM 的 UTF-8 在 cmd 下执行,第一行会变成锘?echo off,报“不是内部或外部命令”,而且这个错误只在用户登录的瞬间闪一下,很难看到。

脚本内容里如果要写中文路径或者中文日志,编码问题会更明显。我的做法是脚本里全用英文和变量,日志靠%USERNAME%、%COMPUTERNAME%这类变量拼,不做中文输出。

验证脚本有没有真的跑,最快的办法是看%TEMP%下有没有那个日志文件,以及文件里的时间戳是不是本次登录。没有日志文件,说明脚本根本没被执行,去查 GPO 有没有链到用户 OU、用户有没有读权限;有日志但映射失败,就看里面的错误码。

5. 排查与避坑:盘符消失、1219、策略已应用但没效果

5.1 现象:盘符时有时无,重启就好

现象很典型:同一个用户,今天开机有 Z 盘,明天没有,重启一次又回来了,gpresult /r显示策略应用成功。原因通常不是策略没下发,而是盘符冲突或者连接残留。两条 GPO 抢同一个字母,或者脚本和 GPP 同时映射同一个盘,谁先执行谁占位,后到的失败但不报错(脚本里没检查 errorlevel 就静默过去了)。另一种情况是用户之前手动net use Z: \\旧服务器\旧共享 /persistent:yes,注册表里留了记录,新策略用Update时因为盘符已被占用而跳过。

解决分三步。先清残留:在用户机器上net use * /delete /y,再检查HKCU\Network下有没有 Z 键,有就删。再统一 Action:所有驱动器映射条目改成Update,并且在新策略上线时先推一条Delete把旧盘清掉。最后建盘符规划表,一个字母对应一个 UNC,写进变更文档,新需求先查表再分配。从那以后我每接一个环境,第一件事就是把现有 GPO 里的驱动器映射全部导出来做成表,冲突一眼就能看出来。

5.2 现象:登录时报“发生系统错误 1219”

现象是脚本执行到net use那行卡住或者弹窗,日志里写着 1219,提示“不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接”。原因是这台机器已经用另一套凭据连过同一台文件服务器,Windows 不允许对同一服务器建立两组不同身份的连接。常见触发场景:用户先用本地管理员账号映射了一次,再登录域账户;或者脚本里写了/user:EXAMPLE\svc_share,而系统已经有当前用户的连接。

解决是先断再连,而且要断到服务器级别而不是共享级别:net use \\FS01\IPC$ /delete /y,再net use * /delete /y。脚本里保留开头那句net use Z: /delete /y能解决大部分同盘符冲突,但解决不了“同服务器不同盘符不同凭据”。根本办法是不要在登录脚本里写/user:参数,域内映射一律用当前登录用户的凭据,需要不同权限就换组,不要换账号。凭据管理器里如果存了 FS01 的条目,也要清掉,否则每次登录都会自动带上去。

5.3 现象:gpresult 显示 GPO 已应用,但盘符就是不出来

这是最消耗时间的一类。gpresult /r /scope:user里明明能看到那条 GPO,状态是“已应用”,可资源管理器里没有盘。原因有三类:一是 GPP 的驱动器映射在慢速链接下被跳过,分支机构的用户天天中招;二是映射条目的 Item-Level Targeting 判断失败,最常见的是组名写错、组在另一个域、或者用了域本地组做跨域判断(域本地组的成员关系不跨域展开);三是 GPO 里的驱动器映射建在了“计算机配置”下,而链接的是用户 OU。

排查顺序建议固定下来:先看事件日志Microsoft-Windows-GroupPolicy/Operational,里面会写每条 CSE 的处理耗时和失败原因;再在用户机器上跑gpresult /h report.html看 GPP 条目的“获胜的 GPO”和筛选结果;最后把 Item-Level Targeting 临时关掉测一次,能出来就说明是筛选条件的问题。慢速链接的判断阈值默认 500 Kbps,链路质量差的环境可以在计算机配置 > 管理模板 > 系统 > 组策略里调整,但更稳的做法是别让映射依赖网络速度判断。

5.4 现象:盘符有了,点进去提示拒绝访问

映射成功但打不开,说明 SMB 连接建立了、共享权限过了,卡在 NTFS 上。最常见的组合是:共享权限给了Authenticated Users更改,NTFS 上只给了某个 DL 组读取,而用户不在那个组里;或者用户确实在组里,但组是新加的,用户的安全令牌还是登录时的那份,没刷新。后一种情况重新登录一次就好,急的话可以klist purge后再开新会话。

排查用两条命令对照:Get-SmbShareAccess -Name Finance看共享层,icacls "D:\Share\Finance"看 NTFS 层,再看用户所属组whoami /groups | findstr DL-FS01。如果whoami里没有那个组,就别在权限上折腾了,先解决组成员同步。另外注意 AGDLP 里如果全局组嵌了全局组、或者跨域成员,令牌大小会膨胀,超过 1024 个 SID 时部分组会被丢弃,表现也是“明明在组里但没权限”,这个在大型环境里不是传说。

5.5 现象:用户能看到不该看的文件夹,或者看不到该看的

看到不该看的,多半是 NTFS 上还挂着继承来的Users读,或者共享层给了Everyone。在 2.3 那条Get-Acl检查命令里能直接捞出来。看不到该看的,先确认 ABE 是不是开着——ABE 只影响“枚举”,不影响“直接访问”,如果用户有权限但看不到目录,可能是上级目录没给他“遍历”权限,(RX)里的 X 就是遍历,只给(R)会出现“能打开但看不到里面”的怪现象。

还有一种情况是用户通过快捷方式直接访问\\FS01\Finance\子目录,能进,但在\\FS01\Finance下看不到这个子目录。这就是 ABE 加上缺少父目录遍历权限的典型组合。解决方法是给 DL 组在父目录上加(RX)但不加(OI)(CI),只作用于当前层。

6. 验证与进阶:把盘符规划做成可重复执行的一次收口

配完之后我不太相信“点一遍看着对”,习惯用三个动作收口。第一,在客户端跑gpresult /r /scope:user确认 GPO 名称和“已应用”状态;第二,Get-GPOReport -Name "GPO-用户-驱动器映射-财务" -ReportType Html -Path .\gpo.html把策略导出存档,变更前后各存一份,diff 一下就知道谁改了什么;第三,用一张盘符规划表跑校验脚本,把“盘符重复、UNC 不可达、组不存在”这三类问题在上线前拦住。

规划表就是一个 CSV,字段固定:

盘符UNC 路径授权组下发方式负责人
Z\FS01\FinanceDL-FS01-财务-读写GPP-Update基础架构
Y\FS01\PublicDL-FS01-全员-只读GPP-Update基础架构
X\FS01\RDDL-FS01-研发-读写登录脚本基础架构

校验脚本在管理机上跑,需要 RSAT 和到文件服务器的网络可达:

# 上线前校验:盘符冲突、UNC 可达、授权组存在 $plan = Import-Csv .\drive-plan.csv $plan | Group-Object 盘符 | Where-Object Count -gt 1 | ForEach-Object { "盘符冲突: $($_.Name) -> $($_.Group.UNC 路径 -join ', ')" } foreach ($r in $plan) { if (-not (Test-Path $r.UNC 路径)) { "UNC 不可达: $($r.UNC 路径)" } if (-not (Get-ADGroup -Identity ($r.授权组 -split '\\')[-1] -ErrorAction SilentlyContinue)) { "授权组不存在: $($r.授权组)" } } "校验完成,共 $($plan.Count) 条映射"

这段脚本没什么技巧,价值全在“每次都跑”。我吃过一次亏:新加了一个研发的盘,盘符随手写成 Z,跟财务的撞了,测试时只测了研发账号,一切正常;上线第二天财务集体报盘符打不开。后来我把这张表和这段脚本塞进了变更流程,任何新增映射先过校验,Test-Path那一步还能顺带发现 DNS 记录没刷新的问题。再补一句,如果环境里已经有 DFS 命名空间,UNC 最好走\\example.local\share\Finance而不是直连\\FS01\Finance,将来换服务器只改 DFS 目标,客户端一行策略都不用动。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进