Windows 10系统下调用icacls.exe设置权限挂起无响应问题求助
问题原因
- 脚本变量解析错误:原脚本中匹配用户组的规则
"$BUILTIN\\Users"使用双引号包裹,PowerShell会将$BUILTIN识别为未定义的自定义变量,解析为空值,最终匹配规则失效。Windows Server系统可能因环境变量差异未触发该问题,但Windows 10的PowerShell 5.1解析逻辑更严格,会导致后续权限操作的前置判断逻辑异常,甚至触发icacls的未知参数错误导致挂起。 - 外部命令参数转义异常:PowerShell 5.1调用外部exe时的参数解析机制存在历史遗留问题,原脚本中icacls的权限参数带括号、反引号转义的写法在Windows 10下容易解析失败,导致icacls等待无效输入进入挂起状态。
- 遍历参数异常:
/T参数会递归遍历目标文件夹下所有子文件/子目录,如果目录内存在被进程独占锁定的文件(比如正在运行的IIS站点文件、被杀毒软件扫描的文件、重解析点/符号链接指向的无限循环路径),icacls会因等待资源释放直接卡住。Windows 10默认的Defender杀毒策略、文件锁定机制比Server系统更严格,更容易触发该问题。
修复方案
方案1:修复原icacls调用脚本
改用更稳妥的参数传递方式,避免转义问题,同时增加容错参数:
# 修复用户组匹配规则,用单引号避免变量解析 $folderPath = "C:\Program Files\Workspace" $usersRule = [System.Security.Principal.NTAccount]::new("BUILTIN\Users") $folderAcl = Get-Acl -Path $folderPath $hasUsersFullControl = $folderAcl.Access | Where-Object { $_.IdentityReference -eq $usersRule -and $_.FileSystemRights -match "FullControl" } | Measure-Object | Select-Object -ExpandProperty Count if ($hasUsersFullControl -gt 0) { Write-Host "Inside condition" # 用数组传递icacls参数,避免转义问题 $icaclsArgs = @($folderPath, "/Q", "/C", "/T", "/remove", "BUILTIN\Users") & icacls.exe $icaclsArgs } Write-Host "outside condition" $adminArgs = @($folderPath, "/Q", "/C", "/T", "/grant", "BUILTIN\Administrators:(OI)(CI)F") & icacls.exe $adminArgs $iisArgs = @($folderPath, "/Q", "/C", "/T", "/grant", "BUILTIN\IIS_IUSRS:(OI)(CI)F") & icacls.exe $iisArgs
新增的/C参数会让icacls遇到权限错误时继续执行,不会卡住等待
方案2:纯PowerShell .NET API实现(更稳定,无外部依赖)
直接用.NET的安全类修改权限,不需要调用icacls,兼容性更好:
$folderPath = "C:\Program Files\Workspace" $acl = Get-Acl -Path $folderPath # 移除BUILTIN\Users的完全控制权限 $usersIdentity = [System.Security.Principal.NTAccount]::new("BUILTIN\Users") foreach ($rule in $acl.Access) { if ($rule.IdentityReference -eq $usersIdentity -and $rule.FileSystemRights -eq "FullControl") { $acl.RemoveAccessRule($rule) | Out-Null } } # 新增管理员组权限 $adminRule = [System.Security.AccessControl.FileSystemAccessRule]::new( "BUILTIN\Administrators", [System.Security.AccessControl.FileSystemRights]::FullControl, [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow ) $acl.AddAccessRule($adminRule) # 新增IIS用户组权限 $iisRule = [System.Security.AccessControl.FileSystemAccessRule]::new( "BUILTIN\IIS_IUSRS", [System.Security.AccessControl.FileSystemRights]::FullControl, [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow ) $acl.AddAccessRule($iisRule) # 应用权限设置 Set-Acl -Path $folderPath -AclObject $acl
内容的提问来源于stack exchange,提问作者saravana
相关产品推荐
相关产品推荐

