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

PowerShell如何对属性不统一的防火墙规则对象按所有属性分组

Windows重复防火墙规则清理实现

背景

计划清理Windows系统中的重复防火墙规则。已知存在Get-NetFirewallRule这类防火墙专用cmdlet,但传递规则获取附加信息时,例如执行Get-NetFirewallRule -DisplayName xxx | Get-NetFirewallApplicationFilter运行速度过慢,因此采用传统的netsh advfirewall firewall命令集实现需求。

现有解析代码

已经完成netsh命令输出的解析,得到规则对象数组,代码如下:

$output = netsh advfirewall firewall show rule name=all verbose | Out-String
$output = [regex]::split($output.trim(), "\r?\n\s*\r?\n");

$objects = @(foreach($section in $output) {
    $obj = [PSCustomObject]@{}

    foreach($line in $($section -split '\r?\n')) {
        if($line -match '^\-+$') {
            continue
        }
        $name, $value = $line -split ':\s*', 2
        $name = $name -replace " " , ""
        
        $obj | Add-Member -MemberType NoteProperty -Name $name -Value $value
    }

    $obj
})

遇到的问题

  • 数组中的对象属性不统一:部分通过端口+程序定义的规则包含Program、Service属性,仅通过端口定义的规则没有这两个属性
  • 无法直接调用Group-Object传入属性列表分组查找重复项,不同对象的属性集不一致会导致分组逻辑异常

补充说明:这些重复防火墙规则由之前编写的不完善脚本生成。

解决方案

核心思路是先统一所有对象的属性集,补全缺失属性后再进行分组筛选。

步骤1:收集全量属性名

遍历所有规则对象,收集所有出现过的属性名,生成统一的属性全集:

$allProperties = $objects | ForEach-Object { $_.PSObject.Properties.Name } | Select-Object -Unique

步骤2:补全所有对象的缺失属性

给每个对象补全不存在的属性,属性值统一设为空字符串,保证所有对象的属性结构完全一致:

$uniformObjects = foreach ($obj in $objects) {
    foreach ($prop in $allProperties) {
        if (-not $obj.PSObject.Properties[$prop]) {
            $obj | Add-Member -MemberType NoteProperty -Name $prop -Value '' -Force
        }
    }
    $obj
}

步骤3:分组筛选重复规则

根据实际判定重复的维度选择属性列表,调用Group-Object分组,筛选出计数大于1的重复规则组:

# 示例按规则名、启用状态、规则方向、操作、协议、本地端口、关联程序维度判定重复,可按需增删属性
$duplicateGroups = $uniformObjects | Group-Object -Property RuleName, Enabled, Direction, Action, Protocol, LocalPort, Program | Where-Object Count -gt 1

步骤4:删除重复规则示例

注意:执行删除操作前建议先打印$rulesToDelete的内容确认要删除的规则是否正确,避免误删系统默认规则
遍历重复规则组,每组保留1条有效规则,删除剩余重复项:

foreach ($group in $duplicateGroups) {
    # 跳过每组第一条,删除其余重复规则
    $rulesToDelete = $group.Group | Select-Object -Skip 1
    # 先确认待删除规则可取消注释下行
    # $rulesToDelete | Select-Object RuleName, Program, LocalPort, Protocol | Format-Table
    foreach ($rule in $rulesToDelete) {
        # 根据规则核心属性匹配删除,避免误删同名不同配置的规则
        netsh advfirewall firewall delete rule name="$($rule.RuleName)" program="$($rule.Program)" protocol=$($rule.Protocol) localport=$($rule.LocalPort)
    }
}

内容的提问来源于stack exchange,提问作者Just a learner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:27:03