Filtering Show-NetIPSec Rules based on IP Address
Get-NetIPSecRule seems a little half-baked. A coworker asked me to come up with a way to only return IPsec rules for a given address. I’m surprised Show-NetIPSecRule natively doesn’t have that, nor does each record have the RemoteAddress property, which would be against which I would filter. I’m not sure I understand the design decisions behind it, nor Get-NetFirewallAddressFilter. Either way, I had to caveman a solution.
function Get-NetIpSecRuleByIPAddress
{
<#
.synopsis
Extend Show-NetIPSecRule to allow filtering by IP address on the output of the corresponding Get-NetFirewallAddressFilter.
.parameter IPAddress
IP address on which to filter.
.parameter ShowRemoteAddress.
Return remote address(es) from Get-NetFilrewallAddressFilter, one per record.
.parameter AsObject
Return all IPSec rules and Get-NetFirewallAddressFilter output.
.notes
I'm surprised this isn't in the basic functionality.
This complicated by the fact that Show-NetIPSecRule returns objects of a few different base types, so not everything has the same schema.
#>
param (
[parameter(Mandatory=$true)]
[string]$IPAddress ,
[switch]$ShowRemoteAddress,
[switch]$AsObject
);
$local:ErrorActionPreference = 'stop';
# stop trying to search for the dang module path
$local:PSModuleAutoLoadingPreference = 'none';
Import-Module NetSecurity
Write-Progress -Activity (Get-Date) -Status "Retrieving NetIPSecRules";
$allRules = Show-NetIPSecRule -ErrorAction SilentlyContinue -ErrorVariable errorVariable -PolicyStore ActiveStore |
Select-Object -Property @{
n = 'IPSecRule'; e = { $_; }
}, @{
n = 'Filter'; e = { $_ | Get-NetFirewallAddressFilter }
} |
Where-Object { $_.Filter; }
if ($errorVariable)
{
$message = $errorVariable[0].Exception.Message;
if ($message -match 'Access is denied')
{
Write-Warning "You must be in a 'Run As Administrator'PowerShell session to execute this cmdlet.";
} # if ($message ...
else
{
Write-Warning $message;
} # if ($message ... else
return;
} # if ($errorVariable)
if (!$allRules)
{
Write-Warning "Show-NetIPSecRule returned no data";
return;
} # if (!$allRules
Write-Progress -Activity (Get-Date) -Status "Filtering for $IPAddress";
$rules = $allRules |
Where-Object {
$_.Filter.RemoteAddress -match $IPAddress;
} # $rules = $allRules ...
if (!$rules)
{
Write-Warning "no match for $IPAddress";
return;
} # if (!$rules)
if ($AsObject)
{
$rules;
return;
} # if ($AsObject
foreach ($rule in $rules)
{
$baseObject = $rule.IPSecRule |
Select-Object -Property IPAddress, DisplayName, Platform, Enabled, InboundSecurity, OutboundSecurity;
$baseObject.IpAddress = $IPAddress;
# $_.Platform is a string array!
foreach ($platform in $rule.IPSecRule.Platform)
{
$object = $baseObject;
$object.Platform = $platform;
if ($ShowRemoteAddress)
{
foreach ($remoteAddress in $rule.Filter.RemoteAddress)
{
$object |
Select-Object -Property IPAddress, DisplayName, Platform, Enabled, InboundSecurity, OutboundSecurity, @{
n = 'RemoteAddress';
e = { $remoteAddress }
} # $object | Select-Object ...
} # foreach ($remoteAddress ...
} # if ($ShowRemoteAddress)
} # foreach ($platform in $rule.IPSecRule.Platform)
} # foreach ($rule in $rules)
if ($object)
{
$object;
} # if ($object)
else
{
Write-Warning "somehow we didn't get any data. go bug a dev."
} # if ($object) ... else
} # function Get-NetIpSecRuleByIPAddress