Powershell 中的多个输出到同一个 csv 文件
Multiple outputs to same csv file in Powershell
我正在尝试导出在多个组策略对象中指定的防火墙规则,并希望在导出的文件中包含 GPO 的名称。因此,每次解析新的 gpo 时,我都尝试获取我的字符串变量 $Policy
并将其插入 csv 文件,但我得到的只是 gpo 名称,而不是来自 Get-NetFirewallRule
的字段。当然,如果我删除 $policy | Out-File $env:temp\gpos.csv -Append -Force
行,那么我会从 Get-NetFirewallRule
中获取所有字段 - 但它们都在一个大的 csv 文件中,我无法确定它们的源 GPO。
foreach ($policy in $PolicyObjects) {
$GPO = Open-NetGPO -PolicyStore "contoso.com$policy"
$policy | Out-File $env:temp\gpos.csv -Append -Force
Get-NetFirewallRule -GPOSession $GPO |
Select 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}},
Enabled,
Profile,
Direction,
Action | Export-CSV $env:temp\gpos.csv -Append -Force
}
Start-Process notepad $env:temp\gpos.csv
这有什么不同吗?
$csv=foreach ($policy in $PolicyObjects) {
$GPO = Open-NetGPO -PolicyStore "contoso.com$policy"
$policy | Out-File $env:temp\gpos.csv -Append -Force
Get-NetFirewallRule -GPOSession $GPO |
Select 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}},
Enabled,
Profile,
Direction,
Action
}
$csv | Export-CSV $env:temp\gpos.csv -Append -Force
Start-Process notepad $env:temp\gpos.csv
您的 $PolicyObjects
似乎是您的组策略显示名称的列表。我会通过以下方式之一收紧您的代码。
$PolicyObjects | ForEach-Object {
$GPO = Open-NetGPO -PolicyStore "contoso.com$_"
foreach($rule in Get-NetFirewallRule -GPOSession $GPO)
{
$portfilter = $rule | Get-NetFirewallPortFilter
$addressfilter = $rule | Get-NetFirewallAddressFilter
[PSCustomObject]@{
GPOName = $_
RuleName = $rule.name
DisplayName = $rule.displayname
DisplayGroup = $rule.displaygroup
Protocol = $portfilter.Protocol
LocalPort = $portfilter.LocalPort
RemotePort = $portfilter.RemotePort
RemoteAddress = $addressfilter.RemoteAddress
Enabled = $rule.enabled
Profile = $rule.profile
Direction = $rule.direction
Action = $rule.action
}
}
} | Export-CSV $env:temp\gpos.csv -Force
Start-Process notepad $env:temp\gpos.csv
或
$csvdata = foreach($policy in $PolicyObjects)
{
$GPO = Open-NetGPO -PolicyStore "contoso.com$policy"
foreach($rule in Get-NetFirewallRule -GPOSession $GPO)
{
$portfilter = $rule | Get-NetFirewallPortFilter
$addressfilter = $rule | Get-NetFirewallAddressFilter
[PSCustomObject]@{
GPOName = $policy
RuleName = $rule.name
DisplayName = $rule.displayname
DisplayGroup = $rule.displaygroup
Protocol = $portfilter.Protocol
LocalPort = $portfilter.LocalPort
RemotePort = $portfilter.RemotePort
RemoteAddress = $addressfilter.RemoteAddress
Enabled = $rule.enabled
Profile = $rule.profile
Direction = $rule.direction
Action = $rule.action
}
}
}
$csvdata | Export-CSV $env:temp\gpos.csv -Force
Start-Process notepad $env:temp\gpos.csv
在第一个中,我们将外循环更改为 Foreach-Object
以利用管道和直接通往 Export-Csv
的管道。
第二个我们捕获所有输出然后导出。
在两者中,我们通过将 opening/writing 文件限制为一次来限制执行时间,将 portfilter 调用限制为每条规则一次而不是 3 次,并且我们使用 [PSCustomObject]
类型加速器来构造我们的最终对象,而不是使用计算表达式管道到 Select-Object
。如果我理解正确的话,两者应该都能达到你想要的结果。
当目标文件与结构不匹配时,无法使用 Export-Csv 附加数据。
在您的例子中,Export-Csv
试图从不存在的 $policy 列中附加值。因此它添加了 $null.
对于有效的 CSV 文件,您必须在使用 Export-Csv 之前将所有内容合并到一个对象中。
试试下面的方法,应该工作得更快,因为它不会对同一个项目多次使用 Get-NetFirewallAddressFilter
,而只是 每个 GPO 会话一次.
Unfortunately I can't test it with a GPO-Session, but since the Parameter -GPOSession
exists for Get-NetFirewallPortFilter
and Get-NetFirewallAddressFilter
as well, it may work.
If you want to test it just locally, you just need to remove the outer foreach-loop and all GPOSession related commands and parameters. Open-NetGPO
and -GPOSession
我的方法与分别检索每个规则的端口和地址过滤器之间的比较(即使每个规则只有一次) 在为本地防火墙规则构建报告时:
My approach: < 2 seconds
Other : > 3 minutes (using Get-NetFirwall*Filter for each rule once)
代码需要提升的控制台!
#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
$portFilters = Get-NetFirewallPortFilter -All
$addressFilters = Get-NetFirewallAddressFilter -All
$applicationFilters = Get-NetFirewallApplicationFilter -All
$interfaceFilters = Get-NetFirewallInterfaceFilter -All
$interfaceTypeFilters = Get-NetFirewallInterfaceTypeFilter -All
$securityFilters = Get-NetFirewallSecurityFilter -All
$serviceFilters = Get-NetFirewallServiceFilter -All
$portFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $portFilters) {
$portFilterDict.Add($filter.InstanceID, $filter)
}
$addressFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $addressFilters) {
$addressFilterDict.Add($filter.InstanceID, $filter)
}
$applicationFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $applicationFilters) {
$applicationFiltersDict.Add($filter.InstanceID, $filter)
}
$interfaceFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $interfaceFilters) {
$interfaceFiltersDict.Add($filter.InstanceID, $filter)
}
$interfaceTypeFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $interfaceTypeFilters) {
$interfaceTypeFiltersDict.Add($filter.InstanceID, $filter)
}
$securityFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $securityFilters) {
$securityFiltersDict.Add($filter.InstanceID, $filter)
}
$serviceFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $serviceFilters) {
$serviceFiltersDict.Add($filter.InstanceID, $filter)
}
$cimClassProperties = 'CimClass', 'CimInstanceProperties', 'CimSystemProperties'
$cimClassPropertiesLookup = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
foreach ($cimClassProperty in $cimClassProperties) {
[void] $cimClassPropertiesLookup.Add($cimClassProperty)
}
foreach ($rule in $rules) {
$ruleInstanceId = $rule.InstanceID
$portFilter = $portFilterDict[$ruleInstanceId]
$addressFilter = $addressFilterDict[$ruleInstanceId]
$applicationFilter = $applicationFiltersDict[$ruleInstanceId]
$interfaceFilter = $interfaceFiltersDict[$ruleInstanceId]
$interfaceTypeFilter = $interfaceTypeFiltersDict[$ruleInstanceId]
$securityFilter = $securityFiltersDict[$ruleInstanceId]
$serviceFilter = $serviceFiltersDict[$ruleInstanceId]
$ruleReportItemProps = [ordered]@{
RuleDisplayName = $rule.DisplayName
RuleDescription = $rule.Description
RuleEnabled = $rule.Enabled
RuleProfile = $rule.Profile
RuleAction = $rule.Action
RuleDirection = $rule.Direction
PortFilterProtocol = $rulePortFilter.Protocol
PortFilterLocalPort = $rulePortFilter.LocalPort
PortFilterRemotePort = $rulePortFilter.RemotePort
AddressFilterRemoteAddress = $ruleAddressFilter.RemoteAddress
ApplicationFilterProgram = $applicationFilter.Program
}
foreach ($prop in $rule.psobject.Properties) {
$propName = 'Rule' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName ) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName , $prop.Value)
}
}
foreach ($prop in $portFilter.psobject.Properties) {
$propName = 'PortFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $addressFilter.psobject.Properties) {
$propName = 'AddressFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $applicationFilter.psobject.Properties) {
$propName = 'ApplicationFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $interfaceFilter.psobject.Properties) {
$propName = 'InterfaceFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $interfaceTypeFilter.psobject.Properties) {
$propName = 'InterfaceTypeFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $securityFilter.psobject.Properties) {
$propName = 'SecurityFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $serviceFilter.psobject.Properties) {
$propName = 'ServiceFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
$ruleReport.Add([pscustomobject]$ruleReportItemProps)
}
$ruleReport | Sort-Object RuleEnabled, RuleDisplayName, RuleProfile | ogv
我正在尝试导出在多个组策略对象中指定的防火墙规则,并希望在导出的文件中包含 GPO 的名称。因此,每次解析新的 gpo 时,我都尝试获取我的字符串变量 $Policy
并将其插入 csv 文件,但我得到的只是 gpo 名称,而不是来自 Get-NetFirewallRule
的字段。当然,如果我删除 $policy | Out-File $env:temp\gpos.csv -Append -Force
行,那么我会从 Get-NetFirewallRule
中获取所有字段 - 但它们都在一个大的 csv 文件中,我无法确定它们的源 GPO。
foreach ($policy in $PolicyObjects) {
$GPO = Open-NetGPO -PolicyStore "contoso.com$policy"
$policy | Out-File $env:temp\gpos.csv -Append -Force
Get-NetFirewallRule -GPOSession $GPO |
Select 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}},
Enabled,
Profile,
Direction,
Action | Export-CSV $env:temp\gpos.csv -Append -Force
}
Start-Process notepad $env:temp\gpos.csv
这有什么不同吗?
$csv=foreach ($policy in $PolicyObjects) {
$GPO = Open-NetGPO -PolicyStore "contoso.com$policy"
$policy | Out-File $env:temp\gpos.csv -Append -Force
Get-NetFirewallRule -GPOSession $GPO |
Select 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}},
Enabled,
Profile,
Direction,
Action
}
$csv | Export-CSV $env:temp\gpos.csv -Append -Force
Start-Process notepad $env:temp\gpos.csv
您的 $PolicyObjects
似乎是您的组策略显示名称的列表。我会通过以下方式之一收紧您的代码。
$PolicyObjects | ForEach-Object {
$GPO = Open-NetGPO -PolicyStore "contoso.com$_"
foreach($rule in Get-NetFirewallRule -GPOSession $GPO)
{
$portfilter = $rule | Get-NetFirewallPortFilter
$addressfilter = $rule | Get-NetFirewallAddressFilter
[PSCustomObject]@{
GPOName = $_
RuleName = $rule.name
DisplayName = $rule.displayname
DisplayGroup = $rule.displaygroup
Protocol = $portfilter.Protocol
LocalPort = $portfilter.LocalPort
RemotePort = $portfilter.RemotePort
RemoteAddress = $addressfilter.RemoteAddress
Enabled = $rule.enabled
Profile = $rule.profile
Direction = $rule.direction
Action = $rule.action
}
}
} | Export-CSV $env:temp\gpos.csv -Force
Start-Process notepad $env:temp\gpos.csv
或
$csvdata = foreach($policy in $PolicyObjects)
{
$GPO = Open-NetGPO -PolicyStore "contoso.com$policy"
foreach($rule in Get-NetFirewallRule -GPOSession $GPO)
{
$portfilter = $rule | Get-NetFirewallPortFilter
$addressfilter = $rule | Get-NetFirewallAddressFilter
[PSCustomObject]@{
GPOName = $policy
RuleName = $rule.name
DisplayName = $rule.displayname
DisplayGroup = $rule.displaygroup
Protocol = $portfilter.Protocol
LocalPort = $portfilter.LocalPort
RemotePort = $portfilter.RemotePort
RemoteAddress = $addressfilter.RemoteAddress
Enabled = $rule.enabled
Profile = $rule.profile
Direction = $rule.direction
Action = $rule.action
}
}
}
$csvdata | Export-CSV $env:temp\gpos.csv -Force
Start-Process notepad $env:temp\gpos.csv
在第一个中,我们将外循环更改为 Foreach-Object
以利用管道和直接通往 Export-Csv
的管道。
第二个我们捕获所有输出然后导出。
在两者中,我们通过将 opening/writing 文件限制为一次来限制执行时间,将 portfilter 调用限制为每条规则一次而不是 3 次,并且我们使用 [PSCustomObject]
类型加速器来构造我们的最终对象,而不是使用计算表达式管道到 Select-Object
。如果我理解正确的话,两者应该都能达到你想要的结果。
当目标文件与结构不匹配时,无法使用 Export-Csv 附加数据。
在您的例子中,Export-Csv
试图从不存在的 $policy 列中附加值。因此它添加了 $null.
对于有效的 CSV 文件,您必须在使用 Export-Csv 之前将所有内容合并到一个对象中。
试试下面的方法,应该工作得更快,因为它不会对同一个项目多次使用 Get-NetFirewallAddressFilter
,而只是 每个 GPO 会话一次.
Unfortunately I can't test it with a GPO-Session, but since the Parameter
-GPOSession
exists forGet-NetFirewallPortFilter
andGet-NetFirewallAddressFilter
as well, it may work. If you want to test it just locally, you just need to remove the outer foreach-loop and all GPOSession related commands and parameters.Open-NetGPO
and-GPOSession
我的方法与分别检索每个规则的端口和地址过滤器之间的比较(即使每个规则只有一次) 在为本地防火墙规则构建报告时:
My approach: < 2 seconds
Other : > 3 minutes (using Get-NetFirwall*Filter for each rule once)
代码需要提升的控制台!
#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
$portFilters = Get-NetFirewallPortFilter -All
$addressFilters = Get-NetFirewallAddressFilter -All
$applicationFilters = Get-NetFirewallApplicationFilter -All
$interfaceFilters = Get-NetFirewallInterfaceFilter -All
$interfaceTypeFilters = Get-NetFirewallInterfaceTypeFilter -All
$securityFilters = Get-NetFirewallSecurityFilter -All
$serviceFilters = Get-NetFirewallServiceFilter -All
$portFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $portFilters) {
$portFilterDict.Add($filter.InstanceID, $filter)
}
$addressFilterDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $addressFilters) {
$addressFilterDict.Add($filter.InstanceID, $filter)
}
$applicationFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $applicationFilters) {
$applicationFiltersDict.Add($filter.InstanceID, $filter)
}
$interfaceFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $interfaceFilters) {
$interfaceFiltersDict.Add($filter.InstanceID, $filter)
}
$interfaceTypeFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $interfaceTypeFilters) {
$interfaceTypeFiltersDict.Add($filter.InstanceID, $filter)
}
$securityFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $securityFilters) {
$securityFiltersDict.Add($filter.InstanceID, $filter)
}
$serviceFiltersDict = [System.Collections.Generic.Dictionary[[string], [ciminstance]]]::new()
foreach ($filter in $serviceFilters) {
$serviceFiltersDict.Add($filter.InstanceID, $filter)
}
$cimClassProperties = 'CimClass', 'CimInstanceProperties', 'CimSystemProperties'
$cimClassPropertiesLookup = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
foreach ($cimClassProperty in $cimClassProperties) {
[void] $cimClassPropertiesLookup.Add($cimClassProperty)
}
foreach ($rule in $rules) {
$ruleInstanceId = $rule.InstanceID
$portFilter = $portFilterDict[$ruleInstanceId]
$addressFilter = $addressFilterDict[$ruleInstanceId]
$applicationFilter = $applicationFiltersDict[$ruleInstanceId]
$interfaceFilter = $interfaceFiltersDict[$ruleInstanceId]
$interfaceTypeFilter = $interfaceTypeFiltersDict[$ruleInstanceId]
$securityFilter = $securityFiltersDict[$ruleInstanceId]
$serviceFilter = $serviceFiltersDict[$ruleInstanceId]
$ruleReportItemProps = [ordered]@{
RuleDisplayName = $rule.DisplayName
RuleDescription = $rule.Description
RuleEnabled = $rule.Enabled
RuleProfile = $rule.Profile
RuleAction = $rule.Action
RuleDirection = $rule.Direction
PortFilterProtocol = $rulePortFilter.Protocol
PortFilterLocalPort = $rulePortFilter.LocalPort
PortFilterRemotePort = $rulePortFilter.RemotePort
AddressFilterRemoteAddress = $ruleAddressFilter.RemoteAddress
ApplicationFilterProgram = $applicationFilter.Program
}
foreach ($prop in $rule.psobject.Properties) {
$propName = 'Rule' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName ) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName , $prop.Value)
}
}
foreach ($prop in $portFilter.psobject.Properties) {
$propName = 'PortFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $addressFilter.psobject.Properties) {
$propName = 'AddressFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $applicationFilter.psobject.Properties) {
$propName = 'ApplicationFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $interfaceFilter.psobject.Properties) {
$propName = 'InterfaceFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $interfaceTypeFilter.psobject.Properties) {
$propName = 'InterfaceTypeFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $securityFilter.psobject.Properties) {
$propName = 'SecurityFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
foreach ($prop in $serviceFilter.psobject.Properties) {
$propName = 'ServiceFilter' + $prop.Name
if (-not $ruleReportItemProps.Contains($propName) -and -not $cimClassPropertiesLookup.Contains($prop.Name)) {
$ruleReportItemProps.Add($propName, $prop.Value)
}
}
$ruleReport.Add([pscustomobject]$ruleReportItemProps)
}
$ruleReport | Sort-Object RuleEnabled, RuleDisplayName, RuleProfile | ogv