Welcome!
This is a little trick some might find useful. I was working on decommissioning some servers and I needed a way to find out what was connecting to these machines. I decided to create a script to log connections. I have done this in the past in various ways which usually involved logging a bunch of data and then querying against it to find the unique connections.
This time it finally occurred to me, just filter the data as it is being collected. So I set out to write a PowerShell script that would keep a running list of client TCP connections to a given machine. This information would be stored in a text file.
The first step was to collect the information and put it into a PowerShell object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Create array to hold netstat data $allnetstatdata = @() # Get TCP connections from netstat $netstatResults = & netstat -p TCP foreach($line in $netstatResults){ # Create object data and add to object $netstatdata = "" | Select local,port,foreign if(-not (($line.Trim() -eq [String]::Empty) -or ($line.contains("Active Connections")) -or ($line.contains("Local Address")))){ if ($line -match 's*(TCP)s{1,}(DS{1,})s{1,}(DS{1,})s{1,}(DS{1,}$)'){ $localhost = $matches[2].Split(":") $netstatdata.local = $dchost[0] $netstatdata.port = $dchost[1] $foreignhost = $matches[3].Split(":") $netstatdata.foreign = $foreignhost[0] $allnetstatdata = $allnetstatdata + $netstatdata } } } |
Then the next step was to read the file with the previous information and add it to the PowerShell object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Define Log File $logfile = C:TCPConnections.txt # Get data from file and add to object $filedata = Get-Content $logfile if($filedata){ foreach($line in $filedata){ $netstatdata = "" | Select local,port,foreign $entry = $line.Split("`t") $netstatdata.port = $entry[0] $netstatdata.local = $entry[1] $netstatdata.foreign = $entry[2] $allnetstatdata = $allnetstatdata + $netstatdata } } |
We can now remove the duplicates from the combined information and save the updated file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Get unique rows $newnetstatdata = $allnetstatdata | Select-Object * -unique # Add combined data to string $tempcontent = New-Object System.Text.StringBuilder foreach($netstat in $newnetstatdata){ if($netstat.port){$tempcontent.Append($netstat.port.ToString()) | Out-Null} $tempcontent.Append("`t") | Out-Null if($netstat.local){$tempcontent.Append($netstat.local.ToString()) | Out-Null} $tempcontent.Append("`t") | Out-Null if($netstat.foreign){$tempcontent.Append($netstat.foreign.ToString()) | Out-Null} $tempcontent.Append("`n") | Out-Null } # Write to file Set-Content -path $logfile $tempcontent.ToString() |
We can run this script in a scheduled task at whatever interval is required. Now we have a log of unique inbound TCP connections.
Best Regards,
Dave
3 comments
Try the .NET way, it workd much faster than netstat and there is no need to parse text, it doesn’t do name/port resolution though:
[System.Net.NetworkInformation.IpGlobalProperties]::GetIPGlobalProperties().GetActiveTcpConnections()
Shay,
Thanks for the tip, I tend to forget about the framework on such common tasks.
Great script – saved me a load of time coding. One small change – I had to explicitly declare all the arrays as I was getting a cannot index into a null array error
# Create array to hold netstat data
$allnetstatdata = @()
$dchost = @()
$matches = @()
$foreignhost =@()
I now need to add to your script a lookup of the client machines and their owners in both active directory and the CMDB database.. Might take a little while but I think it should be quicker than doing it manually for 800 servers 😀