我想列出涉及某些端口的所有防火墙规则并列出它们的显示名称,但我目前找到的唯一方法仅显示端口部分,并且不知道显示名称是什么。
如果我们不带参数调用
Show-NetFirewallRule
,它会列出所有规则,并且每个规则的格式如下(注意 DisplayName
位于“root”上,LocalPort
位于 Get-NetFirewallPortFilter
下):
Name : {96022E5F-666B-4E9E-8BD4-040498CEF1F5}
DisplayName : Google Chrome (mDNS-In)
Description : Inbound rule for Google Chrome to allow mDNS traffic.
DisplayGroup : Google Chrome
Group : Google Chrome
Enabled : True
Profile : Any
Platform :
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : The rule was parsed successfully from the store. (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local
RemoteDynamicKeywordAddresses :
$_ | Get-NetFirewallAddressFilter
LocalAddress : Any
RemoteAddress : Any
$_ | Get-NetFirewallServiceFilter
Service : Any
$_ | Get-NetFirewallApplicationFilter
Program : C:\Program Files\Google\Chrome\Application\chrome.exe
Package :
$_ | Get-NetFirewallInterfaceFilter
InterfaceAlias : Any
$_ | Get-NetFirewallInterfaceTypeFilter
InterfaceType : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallSecurityFilter
Authentication : NotRequired
Encryption : NotRequired
OverrideBlockRules : False
LocalUser : Any
RemoteUser : Any
RemoteMachine : Any
Show-NetFirewallRule | where {$_.LocalPort -eq "5353" -or $_.LocalPort -eq "5354"}
但是它只返回上面所说的
Get-NetFirewallPortFilter
部分:
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
在相同的基础上我尝试过:
Get-NetFirewallRule | where { $_.Get-NetFirewallPortFilter.LocalPort -Eq "5353" }
显示解析错误,以及所有
Get-NetFirewallRule | where { $_.NetFirewallPortFilter.LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).$_.LocalPort -Eq "5353" }
这没有结果。
Get-NetFirewallRule |
Format-Table -Property Name,
DisplayName,
DisplayGroup,
@{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},
@{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}},
@{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},
@{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}} | where {$PSItem.LocalPort -eq "5353"}
但它似乎什么也没做,当我在没有
| where ...
的情况下调用它时,它非常慢,大约每秒显示 1 行。请注意,我还尝试了 $_.LocalPort -eq "5353"
和 $_ -like "5353"
在哪里。
Get-NetFirewallRule | Get-NetFirewallPortFilter | Where-Object -Property { $_.LocalPort -Eq "5353" }
但是什么也没有返回(而且也很慢)。
现在我使用一个肮脏的“解决方法”,我调用
Show-NetFirewallRule > NetFirewallRule.txt
并在文件中手动搜索,但我希望有一个脚本可以自动为我执行此操作(而且这不是很慢,因为有些命令看起来很接近)得到答案非常慢)。
有人知道我是否/如何才能实现这一目标? 谢谢!
我相信您想用 Get-NetFirewallPortFIlter
start,过滤结果,然后将它们传递给
Get-NetFirewallRule
。 这应该比循环 Get-NetFirewallRule
的所有结果并自己测试每个结果要快得多。
示例(为了可读性而缩进,但当然可以是一行):
Get-NetFirewallPortFilter |
Where-Object { $_.LocalPort -eq 5353 } |
Get-NetFirewallRule
在 1.2 秒内搜索了 717 个规则和等效的 717 个端口过滤器,有 6 个结果。
如果您想在每条规则旁边显示端口信息,例如(这可能是也可能不是最佳的,但是......):
Get-NetFirewallPortFilter |
Where-Object { $_.LocalPort -eq 5353 } |
ForEach-Object {
"----"
"Rule"
"----"
$_ | Get-NetFirewallRule
"-----------"
"Port Filter"
"-----------"
$_
}
通过上述操作,您仍然会循环遍历“过滤后的结果”,而不是整个规则集。
Get-NetFirewallRule |Select-Object -First 20 -PipelineVariable Rule |
Get-NetFirewallPortFilter |Where-Object LocalPort -in 'RPCEPMap', 'Any' |
ForEach-Object { [pscustomobject]@{ name = $Rule.DisplayName; port = $_.LocalPort } }
但是这里有两个棘手的事情需要处理:
-PipelineVariable
是有限的(请参阅描述中的信息以及注意和警告),我认为这涵盖了您无法删除
|Select-Object -First 20
部分并放置-PipelineVariable Rule
直接在 Get-NetFirewallRule
cmdlet 上(但我自己并不完全理解其含义)Get-NetFirewallPortFilter
cmdlet 需要CimInstance 而不是例如平常的(PS)
Object
。这大概解释了为什么你不能用 |Select-Object -First 20
替换 |Select-Object *
知道前一个命令实际上通过 Get-NetFirewallRule
放置了对对象输出的引用。请参阅:Select-Object -First 影响管道中先前的 cmdlet
” 这可能是因为 CimInstances 异步运行,并且
-PipelineVariable
中的引用可能被覆盖(即使使用
NetFirewallRule -ThrottleLimit 1 -OutBuffer 1
)。这意味着这可能无法正确传输。无论如何,这(对每个特定规则实例进行过滤)似乎也对我有用:
Get-NetFirewallRule |ForEach-Object {
$Ports = $_ |Get-NetFirewallPortFilter |Where-Object LocalPort -in 'RPCEPMap', 'Any'
if ($Ports) { $_ |Select-Object DisplayName, @{n='LocalPort';e={$Ports.LocalPort} } }
}
$target = 8555
get-netfirewallportfilter |
? { $_.localport -match '-' } |
? { $_.localport | foreach { if ($_ -match '-') { $beg,$end = $_ -split '-';
[int]$beg -le $target -and [int]$end -ge $target }}} |
select instanceid,@{n='localport';e={"$($_.localport)"}}
instanceid localport
---------- ---------
NVS-FrameServer-In-TCP-NoScope 554 8554-8558
{E7D045E7-643F-4A91-94FF-63518836FA72} 5353 7200-17210 8889
{9823D038-1960-4767-9290-B36AA995FBB3} 5000 7000 7100 50000 7200-17210 8888
{123BF547-E50B-4A9D-A9E7-0FAE15D9C665} 7200-17210
IIS-WebServerRole-FTP-Passive-In-TCP 1024-65535
{25931D39-0705-4E63-A10C-E5F16BD17E0A} 7200-17210
{D6E50A26-B3A7-4683-A9FC-8485ED2B38BA} 5000 7000 7100 50000 7200-17210 8888
{B88115EB-F6B6-48D2-B194-723414C249B5} 5353 7200-17210 8889
function Get-FWRulesOnPort
{
<#
Get Firewall Rules associated to a specific Port
Ranges parameter includes results with Port matches in Ranges
Get-FWRulesOnPort -Port 5500
Get-FWRulesOnPort -Port 5001 -Ranges
#>
param(
[int]$Port,
[switch]$Ranges
)
#Rule Match Counter
$i = 0
#Get Firewall Port Filters that match Specific Port
# or contain a Range of Ports
Get-NetFirewallPortFilter |
Where-Object { ($_.LocalPort -eq $Port) -or ($_.localport -match '-') } |
Sort-Object -Property DisplayName |
#Loop Port Filter Objects
ForEach-Object {
#Clear Match Variables each iteration
$RangeMatch = $false
$matches = $null
# if Ranges parameter used and LocalPort contains a Range: 123-456
if ($Ranges -and $_.LocalPort -match '-')
{
# if LocalPort is an Array: -match returns the matched range array value
$match = $_.LocalPort -match "(.*-.*)"
# if Local Port is a string value containing a range: -match returns true
if($_.localport.count -eq 1)
{
# Get matched range from regex capture $matches[0]
$match = $matches[0]
}
#Split matched Range Values into Start and End values
$Start,$End = $match -split '-'
#If Port is in the current range: Set RangeMatch
if ($Port -in $Start..$End) { $RangeMatch = $true }
}#if Range
# if Range or Port Match: Show Result
if ($RangeMatch -or $_.LocalPort -eq $Port)
{
"--------------------------------------------------------------------------------------------------------------"
" Rule $((++$i))"
"--------------------------------------------------------------------------------------------------------------"
$_ | Get-NetFirewallRule | Format-Table -AutoSize
"Port Filter"
"--------------"
$_ | Format-Table -AutoSize
}#if match
}#foreach
}#funtion