Writing a script that will list all listening ports on all servers on the networ

Ok, so I am about to start writing my first script and am basically looking for advice and help on creating this. I am hoping this script will save several 100 man hrs of work at my company. So here is an example of what I need this was done in Unix:

Port Report for csaMay1
Report Generated Thu Mar 10 10:17:54 CST 2016

Identifying known listening ports

Port OK! 22 ssh listening
Port OK! 1363 NDM listening
Port OK! 1364 NDM listening
Port OK! 1556 NetBackup listening
Port OK! 4118 TrendMicro listening
Port OK! 13724 NetBackup listening
Port OK! 13782 NetBackup listening

List of Ports not listed as CSA documented ports

End of Report…

Now I have been able to find all the listening ports but it does not give the name that is associated with the port and that seems to be my biggest problem. Any help or any ideas anyone could offer on this would be a big help.

I suspect your Unix list actually just used a static database of well-known ports. A port itself doesn’t identify who or what is listening. In other words, if you hit a server and see that it’s listening on port 1143, there’s no way to ask the port, “hey, what application are you?” because the port doesn’t “know.”

IANA has a partial list of registered ports at Service Name and Transport Protocol Port Number Registry, but it’s obviously not comprehensive.

Another option would be to somehow log into the server itself, perhaps via PowerShell remoting, and ask the server for a list of ports. For example, the Netstat command can do that, as described as http://www.howtogeek.com/howto/28609/how-can-i-tell-what-is-listening-on-a-tcpip-port-in-windows/. You can absolutely run that remotely if something like PowerShell Remoting is enabled (use Invoke-Command, for example), but the output of these commands is usually text, so you’ll have to parse that text. And all it’ll do is give you, at most, a process name - which might be something like “Dns.exe.” You’d still have to have your own list to know that Dns.exe is the Windows DNS Service.

Don lol I am actually watching a video of yours on YouTube “Windows PowerShell Best Practices and patterns: Time to get serious” right now. Thanks for the reply.

I was actually sitting here thinking to myself I wish I knew this guy so he could help me with this.

One other question can I take a list of ports and attach names to them say in notepad and have PowerShell associate any port # listed also display the name. I am guessing I can also put all the windows servers I need to run this on in a list in notepad so the script knows which servers to run this on.

Forgive me if any of these questions seem dumb, I am a SUPER NEWBIE! :slight_smile:
Just now really starting to dive into this and work is definitely forcing me to do so which is absolutely not a bad thing.

Thanks for any help you may be able to provide. I will defiantly take a look at the links you provided in your last reply.

I’d probably define the port=application as a hash table. That way it’s easy to “look up” the port number to get the application name. Yes, that could be done in a text file, although it’d technically be a kind of script.

You’re starting with something that’s a bit on the more complex side… running before you can walk, so to speak. That’s going to make this a little frustrating, because there are a bunch of more advanced techniques you’ll need to master, without a grounding underneath you to begin with. Not the most enjoyable way to learn, for some people.

Have you finished “Learn PowerShell in a Month of Lunches?”

You could build a simple port-to-name table based on a CSV file. The file would look like …

port,name
21,FTP
23,Telnet
25,SMTP
80,HTTP
443,HTTPS

To build your data dictionary you would code it like …

# Create dictionary
$list = Import-CSV -Path .\portlist.csv
$lookup = $list | Group-Object -AsHashTable -AsString -Property port

Then to do the lookup you would code along the lines of …

[string]$port = 25 # whatever port you found or where looking for
$name = $lookup[$port].name

Don,
I just started it about 20min ago and am going to go through it all. Looks like there is a lot of valuable info in these videos of yours that will help me understand all this a lot better. My dad is going to help me out and give me some pointers in the evenings. he is a Microsoft instructor and Systems Administrator himself with tons of knowledge on all this stuff. he already said he was not writing it for me through. lol, which is fine I defiantly want to learn this stuff so I can start automating things more in the company. As far as learning to run before I can walk I did the same thing when I started to learn guitar, I just kind of go to the deep end of life and jump right in, sink or swim right… :slight_smile:

Bob,
yeah I have been looking into CSV files and importing modules that others have created and am going to look at maybe trying to do that. Good suggestion though, will absolutely look at going that route. Once I get done with this thing I will post it and see what you guys think of my very first script. You guys might have a better way of doing it or some good adjustments I could make to it.

Thanks again for the reply’s I super appreciate it big time.

Don,
One other thing this video of yours is it ok that I am using PS 5 and it looks like you were on 2 when you did these? I am guessing other then maybe some small changes here and there it is basically the same thing…?

For the entry level stuff, v5 isn’t any different.

Not clear if you’re just looking to do this as a project or if you’re after a solution for your company. If it’s the latter, then rather than rolling your own I’d look at something like nmap to do the port scanning. Use its XML output facility and then parse that with PowerShell for your reports.

Matt,
Basically I work for a company that does Government health care. The company is about to go through an Audit this June and this is information that they need to know for the Audit. Instead of having to mainly go to each server to do this which would take a LONG time I am wanting to write a script that will go out to all our windows servers, pull this information and then export it all into an xml spreadsheet or something.

Since I have never written any scripts before and this is all new to me you can see how complicated of a task I have in front of me with really ZERO scripting experience. The nice thing is after going through a crash course here and hopefully getting this figured out I can pass this along to the other companies that fall under our scope of operations that will also be able to use it. they are doing all this manually when it needs to be done, but I like to work smarter and not harder so…

I have never looked into nmap but will go check it out. Thanks for the tip.

Ok I think I got it somewhat figured out. The problem I am running into is my text file of the list of systems I want to run this on is working but it is replacing the data before it with the last one. So it keeps over writing the information of the next server. here is the script so far let me know of any changes I might need to make here. The Get-networkstatistics is a function I found out on the Net for doing netstat from PowerShell.

$datastore = “\csav\Server_Data\ports.csv”
$servers = Get-Content -path C:\PS-Scripts\ServerList.txt
foreach ($server in $servers)
{
$results = Get-NetworkStatistics -computername $server -State LISTENING
$results | export-csv -Path c:\Server_Data\ports.csv -NoTypeInformation
}

Try this out

$datastore = “\csav\Server_Data\ports.csv”
$servers = Get-Content -path C:\PS-Scripts\ServerList.txt
$out = @()
foreach ($server in $servers)
{
$results = Get-NetworkStatistics -computername $server -State LISTENING
$out += $results
}
$out | export-csv -Path c:\Server_Data\ports.csv -NoTypeInformation -Encoding UTF8

When I run this it is giving me this error at the end and is not creating the ports.csv file with all the information now.

$datastore = “\csav\Server_Data\ports.csv”
$servers = Get-Content -path C:\PS-Scripts\ServerList.txt
$out = @()
foreach ($server in $servers)
{
$results = Get-NetworkStatistics -computername $server -State LISTENING
$out += $results
}
$out | export-csv -Path c:\Server_Data\ports.csv -NoTypeInformation -Encoding UTF8

PS C:> C:\Temp\PowerShell Script\PortScanTest.ps1
WARNING: Could not run Get-Process -computername . Verify permissions and connectivity. Defaulting to no ShowProcessNames
WARNING: Could not invoke create win32_process on to delete C:\netstat.txt
Invoke-WmiMethod : Cannot validate argument on parameter ‘ComputerName’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Temp\PowerShell Script\PortScanTest.ps1:179 char:127

  • … -ComputerName $Computer -ErrorAction stop).processid
  •                ~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:slight_smile: [Invoke-WmiMethod], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeWmiMethod

PS C:>

I was able to get it to stop overwriting the data by putting the -append at the end of the original script.

$datastore = “\csav\Server_Data\ports.csv”
$servers = Get-Content -path C:\PS-Scripts\ServerList.txt
foreach ($server in $servers)
{
$results = Get-NetworkStatistics -computername $server -State LISTENING
$results | export-csv -Path c:\Server_Data\ports.csv -NoTypeInformation -append
}

The error indicates that something isn’t passing the computer name. Without seeing Get-NetworkStatistics, it’s impossible to say what.

Here is the function for Get-Networkstatistics

http://gallery.technet.microsoft.com/scriptcenter/Get-NetworkStatistics-66057d71

Ok so here is what I got so far. After getting it to work with the .txt file the company wanted me to get the list of servers from the OU in AD and all the subfolders in that OU that servers are in. This works but if it fails to run on a server it can ping it errors out and stops the script. How can I get it to go past any errors and move on to the next server?

$datastore = “\csawork\Server_Data\ports.csv”
$servers = Get-ADComputer -Filter {OperatingSystem -Like “Windows Server”} -SearchBase “DC=CSA, DC=bcbsal, DC=org”
foreach ($server in $servers)
{
Write-Host $server
$server = $server.ToString()
$server = $server.Substring($server.IndexOf(“CN=”) + 3)
$server = $server.Substring(0, $server.IndexOf(“,OU”))
Write-Host “Formatted $server”
$con_status = Test-Connection $server -count 1 -Quiet
if ($con_status -eq “True”)
{
Write-Host "processing… " $server
$results = Get-NetworkStatistics -computername $server -State LISTENING
$results | export-csv -Path c:\Server_Data\ports.csv -NoTypeInformation -Append
}
else
{
Write-Host “server " $server " is offline or unreachable”
}
}
Write-Host “”
Write-Host “Processing is complete”