文件夹安全权限转换对应的共享权限
需求:公司域控及共享服务器硬件升级,由普通的台式主机更换成专业的服务器。这就需要搭建备域控,并对共享文件进行完整的迁移。
使用 robocopy 工具(以管理员权限运行CMD)
参考:Jack_孟 - robocopy命令简介,ROBOCOPY source destination [file [file]...] [options]
复制文件夹全部内容及保留所有文件信息,同时保留用户相关 NTFS 权限。如果不在一个域中,就会出现未知用户。
ROBOCOPY \\Cs-dc2\张三组 E:\张三组 /E /COPYALL
编写脚本实现安全权限转换对应的共享权限
首先打开共享设置
共享文件夹的名称往往与文件夹的实际名称相同,一来是系统默认便是如此,二来方便管理。
# 接收用户输入的文件夹路径
$folderPath = Read-Host -Prompt "请输入文件夹路径(例如:C:\共享文件夹\质检)"
# 接收用户输入的共享名称
$shareName = Read-Host -Prompt "请输入共享名称(例如:质检)"
try {
# 获取文件夹的 NTFS 安全权限
$acl = Get-Acl -Path $folderPath
# 禁用文件夹的权限继承,并将现有的继承权限转换为显式权限
$acl.SetAccessRuleProtection($true, $false)
Set-Acl -Path $folderPath -AclObject $acl
Write-Output "已禁用权限继承并设置显式权限。"
} catch {
Write-Output "获取文件夹权限或禁用继承时出错: $_"
exit
}
# 建立有效的 NTFS 用户权限列表
$ntfsUsers = @{ }
foreach ($access in $acl.Access) {
$user = $access.IdentityReference.Value
$permissions = $access.FileSystemRights.ToString()
if ($permissions.Contains("FullControl")) {
$ntfsUsers[$user] = "Full"
}
elseif ($permissions.Contains("Modify")) {
$ntfsUsers[$user] = "Change"
}
elseif ($permissions.Contains("ReadAndExecute") -or $permissions.Contains("Read")) {
$ntfsUsers[$user] = "Read"
}
else {
Write-Output "未匹配权限类型:$permissions,跳过用户 $user 的共享权限设置"
}
}
# 定义例外列表,仅适用于 NTFS 权限(不加入共享权限)
$exceptionList = @(
"CREATOR OWNER",
"SYSTEM",
"Users",
"Administrators",
"BUILTIN\Administrators",
"NT AUTHORITY\SYSTEM",
"NT AUTHORITY\Authenticated Users"
)
try {
# 清除现有的共享权限,确保只为 NTFS 权限中非例外用户添加共享权限
Get-SmbShareAccess -Name $shareName | ForEach-Object {
Revoke-SmbShareAccess -Name $shareName -AccountName $_.AccountName -Force
}
Write-Output "已清除现有共享权限。"
# 设置共享权限为 NTFS 权限中非例外用户的权限
foreach ($user in $ntfsUsers.Keys) {
if (-not $exceptionList.Contains($user)) {
try {
# 检查用户是否为SID格式(避免没有账户名的错误)
if ($user -match "^S-\d-\d+-(\d+-){1,14}\d+$") {
Write-Output "跳过SID格式用户 $user 的共享权限设置。"
} else {
Grant-SmbShareAccess -Name $shareName -AccountName $user -AccessRight $ntfsUsers[$user] -Force
Write-Output "已为用户 $user 设置共享权限:$ntfsUsers[$user]"
}
} catch {
Write-Output "为用户 $user 设置共享权限时出错(账户名与安全标识无映射): $_"
}
}
}
} catch {
Write-Output "清除共享权限时出错: $_"
}
try {
# 移除非 NTFS 列表中的用户,并为例外用户添加自定义 NTFS 权限
foreach ($access in $acl.Access) {
$user = $access.IdentityReference.Value
if (-not $ntfsUsers.ContainsKey($user) -and -not $exceptionList.Contains($user)) {
$acl.RemoveAccessRule($access)
Write-Output "已移除用户 $user 的NTFS权限"
}
}
# 删除 Everyone 的共享和 NTFS 权限
Revoke-SmbShareAccess -Name $shareName -AccountName "Everyone" -Force
$acl.Access | Where-Object { $_.IdentityReference -eq "Everyone" } | ForEach-Object { $acl.RemoveAccessRule($_) }
Write-Output "已删除 Everyone 的共享和 NTFS 权限。"
# 添加例外列表中的系统账户权限
$usersRule = New-Object System.Security.AccessControl.FileSystemAccessRule("Users", "ReadAndExecute, ListDirectory, Read", "ContainerInherit, ObjectInherit", "None", "Allow")
$adminsRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$systemRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$creatorOwnerRule = New-Object System.Security.AccessControl.FileSystemAccessRule("CREATOR OWNER", "FullControl", "ContainerInherit, ObjectInherit", "InheritOnly", "Allow")
# 将新的规则添加到 ACL 中
$acl.AddAccessRule($usersRule)
$acl.AddAccessRule($adminsRule)
$acl.AddAccessRule($systemRule)
$acl.AddAccessRule($creatorOwnerRule)
# 将更改后的 ACL 应用到文件夹
Set-Acl -Path $folderPath -AclObject $acl
Write-Output "共享和 NTFS 权限设置已完成,保留了系统级用户,并已删除多余的成员。"
} catch {
Write-Output "设置或更新 NTFS 权限时出错: $_"
}
后话
文件迁移工具实测后对比
FMST
看了 虎头 - 利用FSMT进行文件服务器迁移及整合 提到的FSMT,光是找资源都费了老半天,在server2019上使用较为麻烦,需要额外安装 .net2.0,以及界面老旧,看英文也挺不方便。安装上了,但操作有报错提示,于是不再深究,直接换方案了。
Windows迁移工具
老收藏家 - 浅谈NTFS权限迁移与共享权限迁移(上) 提到安装 ,也就是Windows迁移工具。
当时安装完,使用时一直处于以下状态,于是也放弃了。
- 正在打开连接。请在目标服务器上运行 Receive-SmigServerData。
- 正在打开连接。请在源服务器上运行 Send-SmigServerData。
- Send-SmigServerData : 开始连接的传输失败。 此 cmdlet 无法连接到目标服务器。有关详细信息,请转到 Windows Server 2016 TechCenter,参阅《文件服务迁移指南》中“疑难解答”部分的“数据迁移连接”。
其他方法
老收藏家 - 浅谈NTFS权限迁移与共享权限迁移(下) 提到的 Permcopy 使用效果不理想,以及相关搜索到的注册表导入的方式,也行不通。