当目标文件与结构不匹配时,无法使用 Export-Csv 附加数据。
在您的情况下,Export-Csv
尝试从不存在的 $policy 列中附加值。因此它添加了 $null。
对于有效的 CSV 文件,您必须在使用 Export-Csv 之前将所有内容合并到一个对象中。
试试下面的方法,它应该工作得更快,因为它不会Get-NetFirewallAddressFilter
对同一个项目使用多次,但每个 GPO-Session 只使用一次。
不幸的是,我无法使用 GPO-Session 对其进行测试,但由于 Parameter也-GPOSession
存在Get-NetFirewallPortFilter
,Get-NetFirewallAddressFilter
因此它可能会起作用。如果你只想在本地测试它,你只需要移除外部的 foreach-loop 和所有 GPOSession 相关的命令和参数。Open-NetGPO
和-GPOSession
在为本地防火墙规则构建报告时,我的方法与分别为每个规则检索端口和地址过滤器(即使每个规则只有一次)之间的比较:
我的方法:< 2 秒
其他:> 3 分钟 (对每个规则使用一次 Get-NetFirwall*Filter)
该代码需要一个提升的控制台!
#requires -RunAsAdministrator
$ruleReport = [System.Collections.Generic.List[psobject]]::new()
foreach ($policy in $PolicyObjects) {
<#
if you want to append to file after each policy, place the list here instead of above
$ruleReport = [System.Collections.Generic.List[psobject]]::new()
#>
$GPO = Open-NetGPO -PolicyStore "contoso.com\$policy"
$rules = Get-NetFirewallRule -GPOSession $GPO
# retrieving filters once in advance speeds up the execution extremely! (Requires elevated session to get all filters)
# local execution time with that approach reduces the execution time from >3 minutes TO <2 seconds
$portFilters = Get-NetFirewallPortFilter -All -GPOSession $GPO
$addressFilters = Get-NetFirewallAddressFilter -All -GPOSession $GPO
# build dictionary for port filters for rule lookups
$portFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($portFilter in $portFilters) {
$portFilterDict.Add($portFilter.InstanceID, $portFilter)
}
# build dictionary for addresss filters for rule lookups
$addressFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($addressFilter in $addressFilters) {
$addressFilterDict.Add($addressFilter.InstanceID, $addressFilter)
}
foreach ($rule in $rules) {
$ruleInstanceId = $rule.InstanceID
$rulePortFilter = $portFilterDict[$ruleInstanceId]
$ruleAddressFilter = $addressFilterDict[$ruleInstanceId]
# build combined object
$ruleReportItem = [pscustomobject][ordered]@{
Policy = $policy
Name = $rule.Name
DisplayName = $rule.DisplayName
DisplayGroup = $rule.DisplayGroup
Protocol = $rulePortFilter.Protocol
LocalPort = $rulePortFilter.LocalPort
RemotePort = $rulePortFilter.RemotePort
RemoteAddress = $ruleAddressFilter.RemoteAddress
Enabled = $rule.Enabled
Profile = $rule.Profiles
Direction = $rule.Direction
Action = $rule.Action
}
# append to list
$ruleReport.Add($ruleReportItem)
}
<#
if you want to append to file after each policy, place the export here instead of below
$ruleReport | Export-Csv $env:temp\gpos.csv -Append
#>
}
$ruleReport | Export-Csv $env:temp\gpos.csv
更新
要仅针对本地防火墙规则测试该方法,请使用此脚本。
该代码需要一个提升的控制台!
#requires -RunAsAdministrator
$ruleReport = [System.Collections.Generic.List[psobject]]::new()
$rules = Get-NetFirewallRule
# retrieving filters once in advance speeds up the execution extremely! (Requires elevated session to get all filters)
# local execution time with that approach reduces the execution time from >3 minutes TO <2 seconds
$portFilters = Get-NetFirewallPortFilter -All
$addressFilters = Get-NetFirewallAddressFilter -All
# build dictionary for port filters for rule lookups
$portFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($portFilter in $portFilters) {
$portFilterDict.Add($portFilter.InstanceID, $portFilter)
}
# build dictionary for addresss filters for rule lookups
$addressFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($addressFilter in $addressFilters) {
$addressFilterDict.Add($addressFilter.InstanceID, $addressFilter)
}
foreach ($rule in $rules) {
$ruleInstanceId = $rule.InstanceID
$rulePortFilter = $portFilterDict[$ruleInstanceId ]
$ruleAddressFilter = $addressFilterDict[$ruleInstanceId ]
# build combined object
$ruleReportItem = [pscustomobject][ordered]@{
Name = $rule.Name
DisplayName = $rule.DisplayName
DisplayGroup = $rule.DisplayGroup
Protocol = $rulePortFilter.Protocol
LocalPort = $rulePortFilter.LocalPort
RemotePort = $rulePortFilter.RemotePort
RemoteAddress = $ruleAddressFilter.RemoteAddress
Enabled = $rule.Enabled
Profile = $rule.Profiles
Direction = $rule.Direction
Action = $rule.Action
}
# append to list
$ruleReport.Add($ruleReportItem)
}
$ruleReport | Export-Csv $env:temp\gpos.csv -NoTypeInformation
write-host "Exported to $($env:temp)"