Current Iteration:
Here is a quick snippet to enable Network Engineers and Systems dudes to gather connection info on local or remote Windows.
# Sample Output
# Checking connections on port(s) 80 443 8080 8443...
# Checking connections on for process name(s): chrome...
# Process names have not been defined. Program now scans 7 processes...
# ProcessName PID Protocol SourceEndPoint DestinationEndpoint ConnectionStatus processOwner
# ----------- --- -------- -------------- ------------------- ---------------- ------------
# chrome 5896 TCP 10.10.10.500:51788 10.10.10.500:8080 ESTABLISHED KIMCONNECT\rambo
# chrome 5896 TCP 10.10.10.500:51789 10.10.10.500:8080 ESTABLISHED KIMCONNECT\rambo
# chrome 5896 TCP 10.10.10.500:51793 10.25.1.1800:443 ESTABLISHED KIMCONNECT\rambo
# chrome 5896 TCP 10.10.10.500:51794 10.25.1.1800:443 ESTABLISHED KIMCONNECT\rambo
# getProcessConnections.ps1
# version 0.0.3
#
# Description:
# This script will connect to a list of Windows machines to collect processes and their ports utilizations
# This iteration includes information on the process owner(s)
# Program has been slightly optimized
#
# Requirements:
# WinRM connectivity is expected toward the list of computer names
$computerNames="$env:computername"
$processNames='chrome'
$portNumbers=@()
function invokeGetProcessPorts{
[cmdletbinding()]
Param(
[string[]]$computerNames=$env:computername,
[string[]]$processNames=$null,
[string[]]$portNumbers=$null
)
function getProcessConnections{
[cmdletbinding()]
Param(
[parameter(ValueFromPipeLine=$True)][AllowEmptyCollection()][string[]]$processNames=$null,
[parameter(ValueFromPipeLine=$True)][AllowEmptyCollection()][string[]]$portNumbers=$null
)
# Initialize variables
$results=@()
$psVersionFeasible=$PSVersionTable.PSVersion.Major -ge 4
$processes=if($processNames){
write-host "Checking connections on for process name(s): $processNames..."
if($psVersionFeasible){
try{
get-process $processNames -IncludeUserName # This is only available in PoSh 4.0+
}catch{
write-warning $_
}
}else{
get-process $processNames
}
}else{
if($psVersionFeasible){
get-process -IncludeUserName
}else{
get-process
}
}
if($processes){
write-host "Checking $($processes.count) processes..." -ForegroundColor Yellow
# Collecting wmiobjects to be able to invoke .getowner() method
$processObjects=if(!$psVersionFeasible){Get-WmiObject Win32_Process}else{$null}
$netStat=if($portNumbers){
write-host "Checking connections on port(s) $portNumbers..."
netstat -ano|?{$_ -match "\:($($portNumbers -join '|'))\s"}
}else{
write-host 'Port numbers were not defined. Scanning all ports...' -ForegroundColor Yellow
Netstat -ano|?{$_ -match "\d$"}
}
$previousPid=$previousOwner=$null
write-verbose "Process ID:"
foreach($process in $processes){
$processId=$process.ID
write-verbose "$processId"
$processName=$process.ProcessName
$processOwner=if($processId -ne $previousPid){
$previousOwner=if($processObjects){
$processObjects|?{$_.ProcessId -eq $processId}|%{if($_.GetOwner().User){$_.GetOwner().Domain+"\"+$_.GetOwner().User}else{'unknown'}}|select -unique
}else{
$process.UserName
}
$previousOwner
}else{
$previousOwner
}
$matchedLines = $netStat|findstr $processId
write-host "Process Id $processId matched $($matchedLines.count) lines"
foreach($matchedLine in $matchedLines){
$line = $matchedLine.Split('') | where{$_ -ne ""} # remove empty lines
$leftCount = $line[1].LastIndexOf(':')
$rightCount = $line[2].LastIndexOf(':')
$sourceEndpoint=$line[1].SubString(0,$leftCount)+':'+$line[1].SubString($leftCount+1,($line[1].Length-$leftCount-1))
$destinationEndpoint=$line[2].SubString(0,$rightCount)+':'+$line[2].SubString($rightCount+1,($line[2].Length-$rightCount-1))
$results += [PSCustomObject]@{
ComputerName = $env:computername
ProcessName = $processName
PID = $processId
Protocol = $line[0]
SourceEndPoint = $sourceEndpoint
DestinationEndpoint = $destinationEndpoint
#LocalAddress = $line[1].SubString(0,$leftCount)
#LocalPort = $line[1].SubString($leftCount+1,($line[1].Length-$leftCount-1))
#RemoteAddress = $line[2].SubString(0,$rightCount)
#RemotePort = $line[2].SubString($rightCount+1,($line[2].Length-$rightCount-1))
ConnectionStatus = $(if(!($line[3] -match '\d')){$line[3]}) # Checking if the connection contains any empty string.
processOwner=$processOwner
}
}
$previousPid=$processId
}
if($results){
return $results
}elseif($processNames -and $portNumbers){
write-host "$processNames not found on $portNumbers" -ForegroundColor Yellow
return $null
}else{
write-host "No processes matched." -ForegroundColor Yellow
return $null
}
}else{
write-host "No processes matched." -ForegroundColor Yellow
return $null
}
}
$results=@()
foreach ($computerName in $computerNames){
$session=New-PSSession -ComputerName $computerName
if($session.state -eq 'Opened'){
$result=invoke-command -ComputerName $computerName -scriptblock{
param($importFunc,$x,$y)
write-host "Executing function on $env:computername"
[scriptblock]::create($importFunc).invoke($x,$y)
} -args ${function:getProcessConnections},$processNames,$portNumbers
if($result){
$results+=$result
}else{
write-host "No matches on $computerName"
}
Remove-PSSession $session
}else{
write-warning "Unable to connect to $computername"
}
}
return $results
}
$resultArray=invokeGetProcessPorts $computerNames $processNames $portNumbers
$resultArray|ft
Previous Iterations:
# getProcessConnections.ps1
# version 0.0.2
#
# Description:
# This script will connect to a list of Windows machines to collect processes and their ports utilizations
# This iteration includes information on the process owner(s)
# Program needs to be further optimized
#
# Requirements:
# WinRM connectivity is expected toward the list of computer names
$computerNames=$env:computername
$processNames='chrome'
$portNumbers=@(80,443,8080,8443)
function getProcessConnections{
[cmdletbinding()]
Param(
[parameter(ValueFromPipeLine=$True)][AllowEmptyCollection()][string[]]$processNames=$null,
[parameter(ValueFromPipeLine=$True)][AllowEmptyCollection()][string[]]$portNumbers=$null
)
# Initialize variables
$results = @()
$netStat = if(!$portNumbers){
write-host 'Port numbers were not defined. Program now scans all ports...' -ForegroundColor Yellow
Netstat -ano
}else{
write-host "Checking connections on port(s) $portNumbers..."
netstat -ano|?{$_ -match "\:($($portNumbers -join '|'))\s"}
}
$processes=if($processNames){
write-host "Checking connections on for process name(s): $processNames..."
Get-Process $processNames
}else{
get-process
}
if($processes){
write-host "Process names have not been defined. Program now scans $($processes.count) processes..." -ForegroundColor Yellow
foreach($process in $processes){
$processOwner=Get-WmiObject Win32_Process -Filter "ProcessId='$($process.ID)'"|%{if($_.GetOwner().User){$_.GetOwner().Domain+"\"+$_.GetOwner().User}else{'unknown'}}|select -unique
$matchedLines = $netStat|findstr $process.ID
foreach($matchedLine in $matchedLines){
$line = $matchedLine.Split('') | where{$_ -ne ""} # remove empty lines
$leftCount = $line[1].LastIndexOf(':')
$rightCount = $line[2].LastIndexOf(':')
$sourceEndpoint=$line[1].SubString(0,$leftCount)+':'+$line[1].SubString($leftCount+1,($line[1].Length-$leftCount-1))
$destinationEndpoint=$line[2].SubString(0,$rightCount)+':'+$line[2].SubString($rightCount+1,($line[2].Length-$rightCount-1))
$results += [PSCustomObject]@{
ProcessName = $process.Name
PID = $process.ID
Protocol = $line[0]
SourceEndPoint = $sourceEndpoint
DestinationEndpoint = $destinationEndpoint
#LocalAddress = $line[1].SubString(0,$leftCount)
#LocalPort = $line[1].SubString($leftCount+1,($line[1].Length-$leftCount-1))
#RemoteAddress = $line[2].SubString(0,$rightCount)
#RemotePort = $line[2].SubString($rightCount+1,($line[2].Length-$rightCount-1))
ConnectionStatus = $(if(!($line[3] -match '\d')){$line[3]}) # Checking if the connection contains any empty string.
processOwner=$processOwner
}
}
}
if($results){
return $results|ft -AutoSize
}elseif($processNames -and $portNumbers){
write-host "$processNames not found on $portNumbers" -ForegroundColor Yellow
}else{
write-host "No processes matched." -ForegroundColor Yellow
}
}else{
write-host "No processes matched." -ForegroundColor Yellow
return $null
}
}
foreach ($computerName in $computerNames){
invoke-command -ComputerName $computerName -scriptblock{
param($importFunc,$x,$y)
[scriptblock]::create($importFunc).invoke($x,$y)
} -args ${function:getProcessConnections},$processNames,$portNumbers
}
# getProcessConnections.ps1
# version 0.0.1
# This function is expected to run on a Windows localhost session
function getProcessConnections{
[cmdletbinding()]
Param(
[parameter(Mandatory=$False, ValueFromPipeLine=$True)][AllowEmptyCollection()]
[string[]]$processNames=$null,
[string[]]$portNumbers=$null
)
Begin{
$results = @()
$netStat = if(!$portNumbers){
write-host 'Port numbers were not defined. Program now scans all ports...' -ForegroundColor Yellow
Netstat -ano
}else{
write-host "Checking connections on port(s) $portNumbers..."
netstat -ano|?{$_ -match "\:($($portNumbers -join '|'))\s"}
}
$processes=if($processNames){
write-host "Checking connections on for process name(s): $processNames..."
Get-Process $processNames
}else{
write-host 'A process name has not been defined. Program now scans all processes...' -ForegroundColor Yellow
get-process
}
}Process{
if($processes){
foreach($process in $processes){
$matchedPorts = $netStat | findstr $process.ID
foreach($matchedPort in $matchedPorts){
$line = $matchedPort.Split('') | where{$_ -ne ""} # remove empty lines
$leftCount = $line[1].LastIndexOf(':')
$rightCount = $line[2].LastIndexOf(':')
$sourceEndpoint=$line[1].SubString(0,$leftCount)+':'+$line[1].SubString($leftCount+1,($line[1].Length-$leftCount-1))
$destinationEndpoint=$line[2].SubString(0,$rightCount)+':'+$line[2].SubString($rightCount+1,($line[2].Length-$rightCount-1))
$results += [PSCustomObject]@{
ProcessName = $process.Name
PID = $process.ID
Protocol = $line[0]
SourceEndPoint = $sourceEndpoint
DestinationEndpoint = $destinationEndpoint
#LocalAddress = $line[1].SubString(0,$leftCount)
#LocalPort = $line[1].SubString($leftCount+1,($line[1].Length-$leftCount-1))
#RemoteAddress = $line[2].SubString(0,$rightCount)
#RemotePort = $line[2].SubString($rightCount+1,($line[2].Length-$rightCount-1))
ConnectionStatus = $(if(!($line[3] -match '\d')){$line[3]}) # Checking if the connection contains any empty string.
}
}
}
return $results|ft -AutoSize
}else{
write-host "No processes matched." -ForegroundColor Yellow
return $null
}
}
}
getProcessConnections -portNumbers 80,443
getProcessConnections -processNames chrome
Categories: