title: Flatten netstat command output in powershell
body: <p>I am attempting to use <code>netstat -bano</code> and collect the output in PowerShell for some very specific reporting requirements.</p>
  
  <p>I have working regex that should be able to parse this output no problem, but since the output appears on multiple lines, the regex isn't being processed correctly</p>
  
  <p><strong>here's a screenshot of how it comes out of netstat</strong></p>
  
  <p><a href="https://i.stack.imgur.com/EVDTi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EVDTi.png" alt="sample output"></a></p>
  
  <p>desired output is something like this (all on one line):</p>
  
  <pre>
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       1092  RpcSs [svchost.exe]
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4     Can not obtain ownership information
  TCP    0.0.0.0:623            0.0.0.0:0              LISTENING       7404  [LMS.exe]
  TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING       1224  TermService [svchost.exe]
  </pre>
  
  <p>the use of tools outside of Windows isn't possible, so I'm confined to common tools.</p>
  
  <p>Using <code>Get-Process</code> matching on PID also won't work, as it hides sub process information under svchost and lsass.  <code>netstat</code> with a <code>-b</code> is perfect because it shows both <code>svchost.exe</code> and the process that utilizes the port</p>
  
  <p>I've scoured the internet to find a viable solution but most end in a different resolution</p>
  
  <p>EDIT**here is my final script using input from you guys</p>
  
  <pre><code>$data = (netstat -bano |select -skip 4 | Out-String) -replace '(?m)^  (TCP|UDP)', '$1' -replace '\r?\n\s+([^\[])', "`t`$1" -replace '\r?\n\s+\[', "`t[" -split "`n"
  
  [regex]$regex = '(?&lt;protocol&gt;TCP|UDP)\s+(?&lt;address&gt;\d+.\d+.\d+.\d+|\[::\]|\[::1\]):(?&lt;port&gt;\d+).+(?&lt;state&gt;LISTENING|\*:\*)\s+(?&lt;pid&gt;\d+)\s+(?&lt;service&gt;Can not obtain ownership information|\[\w+.exe\]|\w+\s+\[\w+.exe\])'
  
  $output = @()
  
  $data | foreach {
      $_ -match $regex
  
      $outputobj = @{
          protocol = [string]$matches.protocol
          address = [string]$matches.address -replace '\[::\]','[..]' -replace '\[::1\]','[..1]'
          port = [int]$matches.port
          state = [string]$matches.state -replace "\*:\*",'NA'
          pid = [int]$matches.pid
          service = ([string]$matches.service -replace 'Can not obtain ownership information','[System' -split '.*\[')[1] -replace '\]',''
          subservice = ([string]$matches.service  -replace 'Can not obtain ownership information','' -split '\[.*\]')[0]
      }
      $output += New-Object -TypeName PSobject -Property $outputobj
  }
  $output |select address,port,protocol,pid,state,service,subservice
  </code></pre>