You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何PowerShell设置文件夹ACL脚本仅部分电脑生效?求故障原因

PowerShell ACL脚本部分机器失效问题排查

问题现象

尝试将本地NT Authority\Authenticated Users添加到$env:ProgramData\MTSLogs文件夹的权限列表中,多数机器运行正常,但部分机器抛出错误:

Exception calling "SetAccessRule" with "1" argument(s): "Some or all identity references could not be translated."

已尝试以SYSTEM和管理员身份运行脚本,问题依旧。

原脚本代码:

$AuthenticatedUsersSID = New-Object System.Security.Principal.SecurityIdentifier 'S-1-5-11'
$ACL = Get-Acl -Path "$($env:ProgramData)\MTSLogs" | select -ExpandProperty Access | where IdentityReference -eq "NT AUTHORITY\Authenticated Users" -ErrorAction SilentlyContinue
if (!(($ACL.FileSystemRights -eq "Modify, Synchronize") -and($ACL.AccessControlType -eq "Allow") -and ($ACL.InheritanceFlags -eq "ContainerInherit, ObjectInherit"))) {
    Write-Output "ACL is incorrect.  Remediating..."
    $NewACL = Get-Acl -Path "$($env:ProgramData)\MTSLogs"
    $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($AuthenticatedUsersSID,"Modify","3","0","Allow")
    $NewACL.SetAccessRule($AccessRule)
    $NewACL | Set-Acl -Path "$($env:ProgramData)\MTSLogs"
}

问题原因

  1. SID身份解析失败:虽然直接使用了S-1-5-11(对应Authenticated Users的SID),但部分机器可能因系统语言/区域设置异常、本地安全标识符数据库损坏,导致无法将SID正确转换为对应的NT账户名称,触发身份引用翻译错误。
  2. 枚举值使用不规范:脚本中创建访问规则时用数字3和0代表继承标志和传播标志,虽然对应ContainerInherit, ObjectInherit和None,但数字写法不够直观,且在部分特殊系统环境下可能存在解析偏差。
  3. ACL检查逻辑漏洞:如果目标文件夹原本没有NT AUTHORITY\Authenticated Users的权限条目,$ACL会为空,此时直接访问$ACL.FileSystemRights会导致隐式错误,影响后续判断逻辑。

修复方案

1. 显式转换SID为NTAccount对象

先将SID转换为对应的NT账户对象,确保身份引用能被系统正确识别,避免SID直接解析失败:

$AuthenticatedUsersSID = New-Object System.Security.Principal.SecurityIdentifier 'S-1-5-11'
$AuthenticatedUsersAccount = $AuthenticatedUsersSID.Translate([System.Security.Principal.NTAccount])

2. 使用枚举值替代数字

直接调用.NET枚举类型,提升代码可读性和兼容性:

$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    $AuthenticatedUsersAccount,
    [System.Security.AccessControl.FileSystemRights]::Modify -bor [System.Security.AccessControl.FileSystemRights]::Synchronize,
    [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit,
    [System.Security.AccessControl.PropagationFlags]::None,
    [System.Security.AccessControl.AccessControlType]::Allow
)

3. 优化ACL检查逻辑

先判断$ACL是否存在,避免空值引发的隐式错误:

$logPath = "$($env:ProgramData)\MTSLogs"
$ACL = Get-Acl -Path $logPath | Select-Object -ExpandProperty Access | Where-Object {
    $_.IdentityReference.Value -eq $AuthenticatedUsersAccount.Value
} -ErrorAction SilentlyContinue

$isAclCorrect = $false
if ($ACL) {
    $requiredRights = [System.Security.AccessControl.FileSystemRights]::Modify -bor [System.Security.AccessControl.FileSystemRights]::Synchronize
    $requiredInheritance = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
    
    $isAclCorrect = ($ACL.FileSystemRights -eq $requiredRights) `
                    -and ($ACL.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow) `
                    -and ($ACL.InheritanceFlags -eq $requiredInheritance)
}

4. 增加文件夹存在检查

避免因目标文件夹不存在引发额外异常:

if (-not (Test-Path -Path $logPath)) {
    Write-Output "日志文件夹不存在,创建中..."
    New-Item -Path $logPath -ItemType Directory -Force | Out-Null
}

修改后的完整脚本

$logPath = "$($env:ProgramData)\MTSLogs"
$AuthenticatedUsersSID = New-Object System.Security.Principal.SecurityIdentifier 'S-1-5-11'
$AuthenticatedUsersAccount = $AuthenticatedUsersSID.Translate([System.Security.Principal.NTAccount])

# 检查文件夹是否存在
if (-not (Test-Path -Path $logPath)) {
    Write-Output "日志文件夹不存在,创建中..."
    New-Item -Path $logPath -ItemType Directory -Force | Out-Null
}

# 检查现有ACL是否符合要求
$ACL = Get-Acl -Path $logPath | Select-Object -ExpandProperty Access | Where-Object {
    $_.IdentityReference.Value -eq $AuthenticatedUsersAccount.Value
} -ErrorAction SilentlyContinue

$isAclCorrect = $false
if ($ACL) {
    $requiredRights = [System.Security.AccessControl.FileSystemRights]::Modify -bor [System.Security.AccessControl.FileSystemRights]::Synchronize
    $requiredInheritance = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
    
    $isAclCorrect = ($ACL.FileSystemRights -eq $requiredRights) `
                    -and ($ACL.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow) `
                    -and ($ACL.InheritanceFlags -eq $requiredInheritance)
}

# 修复ACL
if (-not $isAclCorrect) {
    Write-Output "ACL配置异常,开始修复..."
    $NewACL = Get-Acl -Path $logPath
    $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
        $AuthenticatedUsersAccount,
        [System.Security.AccessControl.FileSystemRights]::Modify -bor [System.Security.AccessControl.FileSystemRights]::Synchronize,
        [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit,
        [System.Security.AccessControl.PropagationFlags]::None,
        [System.Security.AccessControl.AccessControlType]::Allow
    )
    $NewACL.SetAccessRule($AccessRule)
    $NewACL | Set-Acl -Path $logPath
    Write-Output "ACL修复完成"
}

内容的提问来源于stack exchange,提问作者Pete Mitchell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 16:34:52