多服务器SMB共享权限检查脚本优化:如何减少嵌套for循环
优化思路
- 减少远程调用开销:原脚本每台服务器会多次发起
Invoke-Command请求,网络开销大,直接把共享查询、权限查询、是否包含Everyone权限的判断逻辑全部放到远程执行的脚本块内,每台服务器仅调用1次远程命令,直接返回存在风险的共享条目即可,不用把所有共享、权限数据都拉回本地再处理。 - 用管道和内置过滤代替显式嵌套循环:PowerShell原生支持管道操作和
Where-Object过滤,完全可以替代多层for循环的写法,代码更简洁。 - 批量并行执行:
Invoke-Command默认支持同时对多台服务器发起并行请求,不用自己写循环逐台调用,执行效率更高。
优化后代码示例
# 先筛选出目标服务器列表 $targetServers = (Get-ADComputer -Filter 'Name -like "Test-Server-*"' | Where-Object { $excludeList -notcontains $_.Name }).Name # 一次远程调用完成所有检测逻辑,直接返回存在Everyone权限的共享信息 $riskShares = Invoke-Command -ComputerName $targetServers -ScriptBlock { Get-SmbShare | ForEach-Object { $share = $_ Get-SmbShareAccess -Name $share.Name | Where-Object { $_.AccountName -eq 'Everyone' -and $_.AccessControlType -eq 'Allow' } | Select-Object @{n='ServerName';e={$env:COMPUTERNAME}}, @{n='ShareName';e={$share.Name}}, @{n='SharePath';e={$share.Path}}, AccountName,AccessRight,AccessControlType } } -ErrorAction SilentlyContinue # 可选:忽略离线、无权限的服务器报错 # 后续直接处理$riskShares即可,比如导出到CSV存档 $riskShares | Export-Csv -Path 'SMB_Everyone权限风险清单.csv' -NoTypeInformation -Encoding UTF8
补充优化提示
- 如果需要兼容Windows Server 2008及更低版本系统,
Get-SmbShare是Win8/2012及以上才支持的cmdlet,更低版本系统可以用Get-WmiObject -Class Win32_Share替代,权限查询对应调整为用Get-Acl读取共享路径的ACL即可。 - 可以给
Invoke-Command加-ThrottleLimit参数调整并行执行的服务器数量,避免同时请求太多导致网络或域控压力过高。
内容的提问来源于stack exchange,提问作者pyte
相关产品推荐
相关产品推荐

