Use PowerShell to Determine What Your System is Talking to

Recently, while troubleshooting a problem with a newly installed application, I wanted to see what it was communicating with. My only requirement was that I wanted to use PowerShell if at all possible. I couldn’t remember if there was a PowerShell command for accomplishing this task or not, but I remembered seeing something about it in Patrick Gruenauer’s chapter (PowerShell as an Enterprise Network Tool) in The PowerShell Conference Book.

Note: This blog article is written using Windows 10 version 1803 and Windows PowerShell version 5.1. Your mileage may vary with different operating systems and/or different versions of PowerShell.

A quick look at his chapter and I found what I was looking for. The Get-NetTCPConnection function. The code in Patrick’s chapter that I remembered seeing is similar to the following.

I decided to take it a step further from what I read in Patrick’s chapter and grab the actual name of the owning process along with a few other properties.

That was too easy. I can see what my test VM that’s used in this scenario is communicating with along with the names of the processes and the creation times. You could write a powerful tool using this command as the basis to scan remote servers to make sure they aren’t communicating with anything out of the ordinary.

Reading seems to be a dying art in our society, but it’s well worth your time to read. To be completely honest, you’ll never master PowerShell without reading. After all, it’s a text based scripting language with no graphics or pictures to point and click and all of the help for it is text-based which means you have to read. While something you’ve read may not solve the exact problem you’re experiencing, it can spark ideas to create those light-bulb moments. Never underestimate the power of reading. Now, go forth and read!

µ

13 Comments

  1. John

    Very Nice! Please elaborate on how you would use this to scan remote systems. Since get-nettcpconnection does not how a “ComputerName” property unless you were to use remote connectivity.

    Reply
    • Patrick Gruenauer

      Hi John, if you mean port scanning then have a look at my chapter in “The PowerShell Conference Book”. There’s a function Test-OpenPort that allows you to scan multiple hosts and multiple ports simultaneously. Or use the built-in Test-NetConnection cmdlet. (only one host and port is possible)

      All the best,
      P

      Reply
    • Michael B. Smith

      As you said – using remote connectivity. Get-NetTCPConnection takes a CimSession parameter, so that’s where I would start (New-CimSession). Invoke-Command would be my next try. If neither of those worked, I’d fall back to psexec before I gave up. 🙂

      Reply
      • Mike F Robbins

        While not widely known or documented, all PowerShell commands that have a CimSession parameter can accept an actual computer name as the value instead of a CIM session. The one caveat is that you would need to be running your PowerShell session as a user who has the necessary privileges on the remote system.

        Reply
    • jkavanagh58

      As mentioned you could just past the computername in CIMSession but why not just use CIMSession if you need to use different creds… adding the new-cimsession … code … remove-cimsession helps. For example I could run this on my non admin logged in desktop and since I assign a variable to a credential object in my profile, and using the code this post eloquently formed I will put a function in the same profile so I will be able to call it and just pass the computer name… the function will pass that to the new-cimsession and using my $admcreds variable create the cimsession get the tcp connections and report back… and if I write my function correctly I could call that function and pass a comma separated list of servers, an array object of server names… ruins the beauty of the one-liners in this post… but just taking it one step further.. sorry Mike

      Reply
  2. jkavanagh58

    Sir this is great, I can pass this to some colleagues who are still using the DOS commands 😉 I also think this really helps when I pass the “time to let go of your blankie” post Ashley McGlone (which I can never seem to find when I need it)

    Reply
  3. Jerry Hess

    You could also grab the full path to the processes as well. Even better is getting it going to remote machines (using this command or netstat for older versions of powershell) but that requires invoking which could be trickier in some environments

    Reply
  4. jkdba

    Awesome, cool idea. If you want to Resolve the RemoteAddress you can add this to your select statement if you don’t mind it being a bit slow for un-resolveable addresses.

    @{l=’RemoteHostName’;e={[system.net.dns]::GetHostEntry($_.RemoteAddress).HostName}

    Note L= and e= are just shorthand for the @{Label=”;Expression={}} syntax.

    Reply
  5. Rob J.

    Mike,

    Thanks for the post. This is a great example and super useful.
    Big fan of you and Patrick…you both are huge mentors. Keep up the good work.

    Rob

    Reply
  6. John

    Thanks for the great post – just the information I was looking for.

    Reply
  7. skatterbrainzz

    Thank you for posting this (and all the great replies too)! I’d like to get the “commandline” property of each process, which I can get via Get-WmiObject, but I don’t see that via Get-Process. Is this covered in the PSConf book as well?

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: