<#
Create FW rules for TCP and UDP Listening Ports
netstat -an -p tcp | Select-String "Listening"
netstat -an -p udp | Select-String "Listening"
for each entry in netstat create firewall rule
name = -p tcp|udp port port #
description = automatic allow rule generated by powershell on get-date
Perhaps as part of this also create a dsc configuration document
#>
$netstat = NETSTAT.EXE -a -n -o -p TCP
$netstat += NETSTAT.EXE -a -n -o -p UDP
[regex]$regexTCP = '(?<Protocol>\S+)\s+((?<LAddress>(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?))|(?<LAddress>\[?[0-9a-fA-f]{0,4}(\:([0-9a-fA-f]{0,4})){1,7}\%?\d?\]))\:(?<Lport>\d+)\s+((?<Raddress>(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?))|(?<RAddress>\[?[0-9a-fA-f]{0,4}(\:([0-9a-fA-f]{0,4})){1,7}\%?\d?\]))\:(?<RPort>\d+)\s+(?<State>\w+)\s+(?<PID>\d+$)'
[regex]$regexUDP = '(?<Protocol>\S+)\s+((?<LAddress>(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?))|(?<LAddress>\[?[0-9a-fA-f]{0,4}(\:([0-9a-fA-f]{0,4})){1,7}\%?\d?\]))\:(?<Lport>\d+)\s+(?<RAddress>\*)\:(?<RPort>\*)\s+(?<PID>\d+)'
$Listening = @()
foreach ($Line in $netstat)
{
switch -regex ($Line.Trim())
{
$regexTCP
{
$MyProtocol = $Matches.Protocol
$MyLocalAddress = $Matches.LAddress
$MyLocalPort = $Matches.LPort
$MyRemoteAddress = $Matches.Raddress
$MyRemotePort = $Matches.RPort
$MyState = $Matches.State
$MyPID = $Matches.PID
$MyProcessName = (Get-Process -Id $Matches.PID -ErrorAction SilentlyContinue).ProcessName
$MyProcessPath = (Get-Process -Id $Matches.PID -ErrorAction SilentlyContinue).Path
$MyUser = (Get-WmiObject -Class Win32_Process -Filter ('ProcessId = '+$Matches.PID)).GetOwner().User
}
$regexUDP
{
$MyProtocol = $Matches.Protocol
$MyLocalAddress = $Matches.LAddress
$MyLocalPort = $Matches.LPort
$MyRemoteAddress = $Matches.Raddress
$MyRemotePort = $Matches.RPort
$MyState = $Matches.State
$MyPID = $Matches.PID
$MyProcessName = (Get-Process -Id $Matches.PID -ErrorAction SilentlyContinue).ProcessName
$MyProcessPath = (Get-Process -Id $Matches.PID -ErrorAction SilentlyContinue).Path
$MyUser = (Get-WmiObject -Class Win32_Process -Filter ('ProcessId = '+$Matches.PID)).GetOwner().User
}
}
$LineItem = New-Object -TypeName PSobject -Property @{
Protocol = $MyProtocol
LocalAddress = $MyLocalAddress
LocalPort = $MyLocalPort
RemoteAddress = $MyRemoteAddress
RemotePort = $MyRemotePort
State = $MyState
PID = $MyPID
ProcessName = $MyProcessName
ProcessPath = $MyProcessPath
User = $MyUser
}
if ($LineItem.LocalAddress = '0.0.0.0')
{
if (($LineItem.State) -and ($LineItem.State.ToUpper() -eq 'LISTENING'))
{
if ($LineItem.User)
{
$User = $LineItem.User.ToLower()
}
else
{
$User = 'system'
}
if (($User -ne 'system') -and ($User -ne 'updatususer') -and ($User -notlike 'network*') -and ($User -notlike 'local s*'))
{
if ($LineItem.ProcessName.ToLower() -ne 'system')
{
$Listening += $LineItem
}
}
}
}
}
#
# $Listening contains a list of services/applications listening on a given port + protocol
#
foreach ($Listener in $Listening)
{
$Protocol = $Listener.Protocol.ToUpper()
$Port = $Listener.LocalPort
New-NetFirewallRule `
-DisplayName "Allow $($Protocol) traffic over port $($Port)" `
-Name "AUTOGEN_$($Protocol)_$($Port)" `
-Action Allow `
-Description $Listener `
-Direction Inbound `
-Enabled True `
-LocalPort $Listener.LocalPort `
-Protocol $Listener.Protocol
}