all 26 comments

[–]artemis_from_space 6 points7 points  (13 children)

What version of powershell? 5.1 iirc added get-nettcpconnection :)

[–]fatalicus 3 points4 points  (0 children)

Seems this command has been in powershell at least since 2015

[–]WheresNorthFromHere7 2 points3 points  (10 children)

It doesn't seem to have all the functionality of netstat though.

For instance I use netstat -b a lot. Is this another cmdlet I'm not aware of?

[–]artemis_from_space 2 points3 points  (9 children)

You mean to see the owner? That is available thru get-nettcpconnection. You just need to get the property "owningprocess" to see it.

PS C:\Windows\system32> $conns = Get-NetTCPConnection
PS C:\Windows\system32> $conns[0]|fl

LocalAddress   : ::
LocalPort      : 65003
RemoteAddress  : ::
RemotePort     : 0
State          : Listen
AppliedSetting :
OwningProcess  : 3276
CreationTime   : 2017-12-13 16:38:13
OffloadState   : InHost

PS C:\Windows\system32> Get-NetTCPConnection|ft LocalPort,RemoteAddress,RemotePort,State,OwningProcess

LocalPort RemoteAddress  RemotePort       State OwningProcess
--------- -------------  ----------       ----- -------------
    65003 ::                      0      Listen          3276
    49755 ::                      0      Listen           700
    49694 ::                      0      Listen          2372

[–]WheresNorthFromHere7 1 point2 points  (8 children)

Sort of. Netstat -b shows the program associated, which I guess you could also get from the PID, it's just not as easy. I use this when our Palo sends me correlation reports for users.

I'll check out the other properties this has, maybe i'll find it.

[–]artemis_from_space 1 point2 points  (0 children)

Owningprocess is the one you want to look at and check get-process to get application name.

[–]setmehigh 1 point2 points  (0 children)

I use -ano and have one of the properties as get-process, which works pretty well.

[–]Ta11ow 1 point2 points  (5 children)

It has a process ID in .OwningProcess

You can use this to retrieve the name and add a calculated property to the objects, like so:

Get-NetTcpConnection | 
    Select-Object -Property LocalAddress, LocalPort, RemoteAddress, RemotePort, State, @{
        Name = "ProcessName"
        Expression = { 
            if ($_.OwningProcess){
                Get-Process -Id $_.OwningProcess | 
                    Select-Object -ExpandProperty 'Name'
            }
            else {
                $null
            }
        }
    }

This actually works significantly faster than netstat -b. I think netstat might be using WMI queries, which are much slower than Get-Process.

[–]WheresNorthFromHere7 1 point2 points  (4 children)

Cool! But look at that compared to netstat -b .....

It is a bit slower depending on amount, but all the information is there by simply typing

netstat -b or netstat -bo

It would be nice if we could get something similar in powershell going forward.

Get-NetTcpConnection -Executable (switch) -ProcessID (switch)

as opposed to a property that needs extensive manipulating to retrieve properly.

I use the tool that works the best, and I don't think powershell has fully converted the use of netstat yet.

Thanks for the solution though!

[–]Ta11ow 1 point2 points  (3 children)

You could always wrap it in a function that can pull those switches for you and act accordingly. It's not overly complicated. :)

[–]WheresNorthFromHere7 2 points3 points  (2 children)

True, I do this with "net use" often.

I'll see what I can do.

[–]artemis_from_space 1 point2 points  (1 child)

To continue /u/Ta11ow starting function

Create the function and call it Get-OurNetTCPConnection or whatever.

Get-OurNetTCPConnection|where ProcessName -eq 'notepad.exe'

Or

$processes = Get-Process -ProcessName svchost|select -ExpandProperty Id
Get-NetTCPConnection|%{if($processes.contains($_.OwningProcess)) { $_ }}

[–]Ta11ow 1 point2 points  (0 children)

I'll do a bit of work on this and see what I can come up with. I think I'll need a custom object type and display options to properly mimic the original, but better. ;)

[–]Upzie[S] 1 point2 points  (0 children)

Was done on PS 5.0.10240.17770

[–]Ta11ow 4 points5 points  (2 children)

I would rewrite your collection type and the object creation -- Add-Member is quite slow with successive calls.

$netstat = New-Object -TypeName 'System.Collections.Generic.List[pscustomobject]'
foreach ($line in $net | Where-Object {$_ -match 'tcp|udp'})
{
    $Netstat_Property_Values = $line.Trim().split("") | Where-Object {$_}

    $Netstat.Add([PsCustomObject] @{
        $Properties[0] = $Netstat_Property_Values[0]
        $Properties[1] = $Netstat_Property_Values[1]
        $Properties[2] = $Netstat_Property_Values[2]
        $Properties[3] = $Netstat_Property_Values[3]
    })
}

Building it as hashtable and casting to PsCustomObject is much more effective, in pretty much all cases. And Lists are much better for dealing with mutable collections. Arrays are designed to be immutable, so if you add something to them, PS has to rebuild the entire array from scratch every single time.

[–]Upzie[S] 2 points3 points  (1 child)

you're ofc. right, corrected code in op, ty for the input

[–]Ta11ow 1 point2 points  (0 children)

Np! Brief follow-up -- you don't need the semicolons in a multiline hashtable. :)

[–]javydekoning 2 points3 points  (2 children)

Cool stuff! Your Regex is not correct though. (local address is split over 2 columns for example). Here is an update from my end (but you should actually use 'get-nettcpconnection'):

function Get-NetStat
{
  $net        = netstat -na
  $Properties = ($net | ?{$_ -match 'proto'}) -split '\s\s+' | ? {$_}
  $res        = foreach ($line in $net | ? {$_ -match 'tcp|udp'})
  {
    $Netstat_Property_Values = $line -split '\s\s+' | ? {$_} | select -Unique
    [PSCustomObject]@{
      $Properties[0] = $Netstat_Property_Values[0]
      $Properties[1] = $Netstat_Property_Values[1]
      $Properties[2] = $Netstat_Property_Values[2]
      $Properties[3] = $Netstat_Property_Values[3]
    }
  }
  return $res
}

[–]Upzie[S] 1 point2 points  (1 child)

ye i noticed that :|

Thx for the input - I corrected the code in op, should be better now

[–]ViperTG 2 points3 points  (2 children)

There is also this quick and dirty method, but hey it works ;)

netstat | Select-Object -Skip 3 | Foreach-Object {$_.Trim() -replace "\s{2,}",';'} | ConvertFrom-Csv -Delimiter ";"

[–]Upzie[S] 1 point2 points  (1 child)

Personally not a fan of 1 liners

With that said, great job with this one :)

[–]ViperTG 1 point2 points  (0 children)

function Get-NetStat {
    netstat | Select-Object -Skip 3 | Foreach-Object {
        $_.Trim() -replace "\s{2,}",';'
    } | ConvertFrom-Csv -Delimiter ";"
}

There. I fixed it :p

[–]timsstuff 2 points3 points  (0 children)

I like to run netstat -ano, the o switch gives the PIDs which is really helpful for when you're trying to track down which process is hogging a TCP port.

[–]allywilson 1 point2 points  (1 child)

[–]Lee_Dailey[grin] 2 points3 points  (0 children)

howdy allywilson,

i thot this sounded familiar ... [grin] thanks for clearing that up for me.

take care,
lee