title: How to group by all properties in PowerShell?
body: <p>I'm planning to remove duplicate firewall rules on Windows. I know there are a set of firewall cmdlets like <code>get-netfirewallrule</code>, but it's too slow when I try to pass a firewall rule to get additional information like <code>Get-NetFirewallRule -displayname xxx | Get-NetFirewallApplicationFilter</code>. So I plan to use the old-school way, the <code>netsh advfirewall firewall</code> command set.</p>
  <p>Now I've parsed the output of <code>netsh advfirewall firewall</code> as an array of objects.</p>
  <pre><code>$output = netsh advfirewall firewall show rule name=all verbose | Out-String
  $output = [regex]::split($output.trim(), &quot;\r?\n\s*\r?\n&quot;);
  
  $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 &quot; &quot;, &quot;&quot;
          
          $obj | Add-Member -MemberType NoteProperty -Name $name -Value $value
      }
  
      $obj
  })
  </code></pre>
  <p>But the problem is that the objects in the array have different properties. For example, this is one object:</p>
  <pre><code>RuleName       : HNS Container Networking - ICS DNS (TCP-In) - B15BF139-F18D-471C-A18C-92DFD33350F1 - 0
  Description    : HNS Container Networking - ICS DNS (TCP-In) - B15BF139-F18D-471C-A18C-92DFD33350F1 - 0
  Enabled        : Yes
  Direction      : In
  Profiles       : Domain,Private,Public
  Grouping       :
  LocalIP        : Any
  RemoteIP       : Any
  Protocol       : TCP
  LocalPort      : 53
  RemotePort     : Any
  Edgetraversal  : No
  Program        : C:\WINDOWS\system32\svchost.exe
  Service        : sharedaccess
  InterfaceTypes : Any
  Security       : NotRequired
  Rulesource     : Local Setting
  Action         : Allow
  </code></pre>
  <p>This is another one:</p>
  <pre><code>RuleName       : HNS Container Networking - DNS (UDP-In) - 91EC1DEF-8CB8-4C2A-A6D4-91480448AE97 - 0
  Description    : HNS Container Networking - DNS (UDP-In) - 91EC1DEF-8CB8-4C2A-A6D4-91480448AE97 - 0
  Enabled        : Yes
  Direction      : In
  Profiles       : Domain,Private,Public
  Grouping       :
  LocalIP        : Any
  RemoteIP       : Any
  Protocol       : UDP
  LocalPort      : 53
  RemotePort     : Any
  Edgetraversal  : No
  InterfaceTypes : Any
  Security       : NotRequired
  Rulesource     : Local Setting
  Action         : Allow
  </code></pre>
  <p>As you can see, the first rule use ports as well as program to define the rule and the second only use ports. How can I group the objects and find duplicated items (so that I can remove corresponding firewall rules)? I can't simply use <code>$objects | Group-Object -Property rulename,enabled,.....</code>, because the properties are not the same for all objects.</p>
  <p>Btw, the duplicate firewall rules are created by some imperfect script I written in the past.</p>