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

基于AsBuiltReport框架优化PowerShell GPO端口查询脚本

优化后的防火墙入站允许端口查询脚本

针对需求优化后的脚本,解决了LocalPort去重、精准过滤指定端口的问题,同时减少重复调用Get-NetFirewallPortFilter的性能损耗:

# 定义需要保留的固定端口和动态端口范围
$targetFixedPorts = '80','135','139','445','5985','5986'
$targetPortRangeStart = 49152
$targetPortRangeEnd = 65535

Get-NetFirewallRule -Action Allow -Enabled True -Direction Inbound | ForEach-Object {
    # 一次性获取端口过滤器,避免重复调用
    $portFilter = $_ | Get-NetFirewallPortFilter
    # 提取并筛选符合条件的LocalPort,同时去重
    $validLocalPorts = $portFilter.LocalPort | Where-Object {
        $_ -in $targetFixedPorts -or ($_ -ge $targetPortRangeStart -and $_ -le $targetPortRangeEnd)
    } | Select-Object -Unique

    # 仅保留有有效端口的规则
    if ($validLocalPorts) {
        [PSCustomObject]@{
            Name          = $_.Name
            Profile       = $_.Profile
            Enabled       = $_.Enabled
            Direction     = $_.Direction
            Action        = $_.Action
            Protocol      = $portFilter.Protocol
            LocalPort     = $validLocalPorts -join ','
            RemotePort    = $portFilter.RemotePort
        }
    }
} | Format-Table -AutoSize

额外问题解答

1. 如何在查询结果中添加机器IP?

有两种常用实现方式:

  • 获取当前网络连接的IPv4地址:在生成自定义对象时添加计算属性,优先取活跃网络接口的IP:
    MachineIP = (Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias (Get-NetConnectionProfile).InterfaceAlias).IPAddress
    
  • 获取所有绑定的IPv4地址:如果需要列出机器所有IPv4地址,可改用:
    MachineIP = ([System.Net.Dns]::GetHostAddresses($env:COMPUTERNAME) | Where-Object {$_.AddressFamily -eq 'InterNetwork'}).IPAddressToString -join ','
    
    远程执行时,上述代码会自动获取目标机器的IP,无需额外处理。

2. 如何使用AsBuiltReport发布查询结果?

AsBuiltReport用于生成标准化架构报告,整合防火墙端口数据的步骤如下:

  1. 先安装依赖模块:
    Install-Module -Name AsBuiltReport -Force
    Install-Module -Name AsBuiltReport.Core -Force
    
  2. 保存查询结果为对象数组:
    $firewallData = Get-NetFirewallRule -Action Allow -Enabled True -Direction Inbound | ForEach-Object {
        # 复用优化后的脚本逻辑生成数据对象
        $portFilter = $_ | Get-NetFirewallPortFilter
        $validLocalPorts = $portFilter.LocalPort | Where-Object {
            $_ -in $targetFixedPorts -or ($_ -ge $targetPortRangeStart -and $_ -le $targetPortRangeEnd)
        } | Select-Object -Unique
        if ($validLocalPorts) {
            [PSCustomObject]@{
                Name          = $_.Name
                Profile       = $_.Profile
                Enabled       = $_.Enabled
                Direction     = $_.Direction
                Action        = $_.Action
                Protocol      = $portFilter.Protocol
                LocalPort     = $validLocalPorts -join ','
                RemotePort    = $portFilter.RemotePort
                MachineIP     = (Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias (Get-NetConnectionProfile).InterfaceAlias).IPAddress
            }
        }
    }
    
  3. 配置并生成报告:
    $reportConfig = @{
        ReportName = 'Windows Firewall Audit Report'
        OutputPath = 'C:\AuditReports'
        Format     = 'HTML','Word'
        CustomContent = @{
            'Allowed Inbound Firewall Ports' = $firewallData
        }
    }
    New-AsBuiltReport -InputObject $env:COMPUTERNAME -ReportConfig $reportConfig -EnableHealthCheck
    
    生成的报告会自动将防火墙端口数据整合到指定章节,支持多格式输出。

3. Invoke-Command远程触发脚本的最佳实践

  • 会话复用:用New-PSSession建立持久会话,避免每次调用重新创建连接:
    $session = New-PSSession -ComputerName 'RemotePC01'
    Invoke-Command -Session $session -ScriptBlock { # 脚本内容 }
    Remove-PSSession $session
    
  • 最小权限原则:使用具备必要权限的域账户执行操作,避免用管理员账户;通过组策略限制WinRM允许访问的用户。
  • 加密通信:配置WinRM使用HTTPS,防止明文传输:
    winrm quickconfig -transport:https
    
  • 规范参数传递:用-ArgumentList或$using:作用域传递本地变量,避免硬编码:
    $targetPorts = '80','445'
    Invoke-Command -ComputerName 'RemotePC01' -ScriptBlock { param($ports) Write-Host $ports } -ArgumentList $targetPorts
    # 或使用$using:
    Invoke-Command -ComputerName 'RemotePC01' -ScriptBlock { Write-Host $using:targetPorts }
    
  • 错误与日志处理:结合try/catch捕获异常,记录操作日志:
    try {
        Invoke-Command -ComputerName 'RemotePC01' -ScriptBlock { # 脚本 } -ErrorAction Stop
    } catch {
        Write-Error "远程执行失败:$_"
        Add-Content -Path 'C:\Logs\RemoteAudit.log' -Value "$(Get-Date) - 错误:$_"
    }
    
  • 批量执行优化:针对多台机器,用-ComputerName传入数组,结合-ThrottleLimit控制并发数,避免资源耗尽。

4. 如何仅保留指定端口(固定端口+动态端口范围)

优化后的脚本已实现该逻辑,核心步骤:

  1. 预先定义目标固定端口数组和动态端口范围的起止值;
  2. 对每个防火墙规则的LocalPort进行筛选:判断端口是否在固定列表内,或处于指定动态端口范围;
  3. 用Select-Object -Unique对筛选后的端口去重;
  4. 仅保留存在有效端口的规则,确保结果只包含符合要求的端口数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:01:12