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

如何编写PowerShell脚本获取多台服务器仅文件夹的完整NTFS权限

改进后的PowerShell脚本(多服务器非系统盘文件夹NTFS权限采集)

原脚本存在几个核心问题:

  • 提前在本地获取D:\文件夹列表,所有远程服务器都复用本地路径,完全不符合需求
  • 未自动识别远程服务器的非系统盘,仅固定D盘
  • 无错误捕获机制,无法排查远程连接、权限不足等问题
  • 数组累加$Output +=性能低下,大文件夹场景会卡顿

以下是修复并优化后的脚本:

# 读取目标服务器列表
$Servers = Get-Content .\Servers.txt
# 使用泛型列表提升性能,替代数组累加
$Output = [System.Collections.Generic.List[PSObject]]::new()

foreach ($Server in $Servers) {
    Write-Host "正在处理服务器: $Server" -ForegroundColor Cyan
    $errorMessage = $null

    try {
        # 远程获取服务器的逻辑驱动器,排除系统盘
        $drives = Invoke-Command -ComputerName $Server -ScriptBlock {
            Get-Volume | Where-Object {
                $_.DriveType -eq 'Fixed' -and $_.DriveLetter -ne $null -and -not $_.SystemVolume
            } | Select-Object -ExpandProperty DriveLetter
        } -ErrorAction Stop

        if (-not $drives) {
            $errorMessage = "未找到非系统固定磁盘"
            throw $errorMessage
        }

        # 遍历每个非系统盘,递归获取文件夹及其NTFS权限
        foreach ($drive in $drives) {
            $drivePath = "\\$Server\$drive`$"
            Write-Host "  正在扫描磁盘: $drivePath" -ForegroundColor Gray

            $folders = Get-ChildItem -Path $drivePath -Recurse -Force -Directory -ErrorAction Stop
            foreach ($folder in $folders) {
                try {
                    $acl = Get-Acl -Path $folder.FullName -ErrorAction Stop
                    foreach ($access in $acl.Access) {
                        # 构造输出对象
                        $outputObj = [PSCustomObject]@{
                            '服务器'       = $Server
                            '文件夹路径'   = $folder.FullName
                            '用户/组'      = $access.IdentityReference
                            '权限'         = $access.FileSystemRights
                            '是否继承'     = $access.IsInherited
                            '错误信息'     = $null
                        }
                        $Output.Add($outputObj)
                    }
                }
                catch {
                    # 捕获单个文件夹的权限获取错误
                    $outputObj = [PSCustomObject]@{
                        '服务器'       = $Server
                        '文件夹路径'   = $folder.FullName
                        '用户/组'      = $null
                        '权限'         = $null
                        '是否继承'     = $null
                        '错误信息'     = $_.Exception.Message
                    }
                    $Output.Add($outputObj)
                    Write-Warning "    文件夹 $($folder.FullName) 处理失败: $($_.Exception.Message)"
                }
            }
        }
    }
    catch {
        # 捕获服务器级别的错误(如连接失败、无磁盘等)
        $outputObj = [PSCustomObject]@{
            '服务器'       = $Server
            '文件夹路径'   = $null
            '用户/组'      = $null
            '权限'         = $null
            '是否继承'     = $null
            '错误信息'     = $_.Exception.Message
        }
        $Output.Add($outputObj)
        Write-Warning "服务器 $Server 处理失败: $($_.Exception.Message)"
    }
}

# 导出结果到CSV
$Output | Export-Csv -Path .\NTFSPerm.csv -Encoding UTF8 -NoTypeInformation
Write-Host "处理完成,结果已导出到 .\NTFSPerm.csv" -ForegroundColor Green

关键改进说明

  • 远程磁盘识别:通过Invoke-Command在远程服务器上执行Get-Volume,筛选出非系统的固定磁盘,自动适配不同服务器的磁盘配置
  • 错误分层捕获:分为服务器连接错误、磁盘扫描错误、单个文件夹权限获取错误,每个错误都记录到输出CSV中,方便后续排查
  • 性能优化:使用[System.Collections.Generic.List[PSObject]]替代数组累加,避免频繁数组扩容带来的性能损耗
  • UNC路径访问:使用\\Server\Drive$的UNC路径访问远程磁盘,确保跨服务器路径有效性
  • 编码与格式:导出CSV时指定UTF8编码,避免中文乱码,同时移除类型信息头

使用注意事项

  1. 执行脚本的账号需要具备目标服务器的管理员权限,才能读取磁盘信息和NTFS权限
  2. 目标服务器需要启用PowerShell远程管理(默认已启用,若未启用可执行Enable-PSRemoting -Force开启)
  3. Servers.txt文件需每行填写一个服务器名称或IP地址

内容的提问来源于stack exchange,提问作者Puneet Tiwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:25:29