Hi Kvprasoon, I am using Pester 5.0 and Powershell 7.1.
The function is in the same script as the test. Here is the full script with the rest of the tests and multiple entries to the arrays cut out:
# # Get data from Cloud
# Resource Groups we want to search relevant objects for.
$rg = "client_dev_main_01", "client_dev_orc_01"
# Function to take rule and create a dynamic object for easier comparison
function NSG_Rule_List ($rule) {
# Variables needed to create dynamic name for each rule.
# Naming convention: existing_NSG.name_Rule.name
$prefix = "existing_"
$nsg = $rule.id.Split("/")[8]
$rulename = $rule.name.Insert(0,'_')
$newname = "$prefix$nsg$rulename"
# Setting the values of the variable, we want to compare on all of these.
Set-Variable -name "$newname" -Value ($rule | Select-Object `
@{N="ResourceGroup" ;E={$_.id.Split("/")[4]}},
@{N="NSG" ;E={$_.id.Split("/")[8]}},
@{N="Name" ;E={$_.Name}},
@{N="Access" ;E={$_.Access}},
@{N="DestinationAddressPrefix" ;E={$_.DestinationAddressPrefix}},
@{N="DestinationPortRange" ;E={$_.DestinationPortRange}},
@{N="Direction" ;E={$_.Direction}},
@{N="Priority" ;E={$_.Priority}},
@{N="Protocol" ;E={$_.Protocol}},
@{N="SourceAddressPrefix" ;E={$_.SourceAddressPrefix}},
@{N="SourcePortRange" ;E={$_.SourcePortRange}}) -Scope 1
# Inform terminal of new variable created
Write-Host "New Variable created '`$$newname'"
}
# For each NSG within Resource Group, pass rule object to function above
$rg | ForEach-Object {
(Get-aznetworksecuritygroup -name * -ResourceGroupName $_ | Get-AzNetworkSecurityRuleConfig) | ForEach-object {
NSG_Rule_List -rule $_
}
}
# # Manually created objects for comparison with cloud objects
# Function to add a new index to an array. Array[index] will be used to compare expected config of an NSG rule with existing config of an NSG rule
function New_Rule {
Param(
[Parameter(Mandatory=$True)]
[String]
$ResourceGroup,
[Parameter(Mandatory=$True)]
[String]
$NSG,
[Parameter(Mandatory=$True)]
[String]
$Name,
[Parameter(Mandatory=$True)]
[ValidateSet("Allow", "Deny")]
[String]
$Access,
[Parameter(Mandatory=$True)]
[ValidateSet("Inbound", "Outbound")]
[String]
$Direction,
[Parameter(Mandatory=$True)]
[String]
$DestinationAddressPrefix,
[Parameter(Mandatory=$True)]
[String]
$DestinationPortRange,
[Parameter(Mandatory=$True)]
[ValidateRange(1, 4096)]
[Int]
$Priority,
[Parameter(Mandatory=$True)]
[ValidateSet("*", "Icmp", "Tcp", "Udp")]
[String]
$Protocol,
[Parameter(Mandatory=$True)]
[String]
$SourceAddressPrefix,
[Parameter(Mandatory=$True)]
[String]
$SourcePortRange
)
Process
{
[PSCustomObject]@{
"ResourceGroup" = $ResourceGroup
"NSG" = $NSG
"Name" = $Name
"Access" = $Access
"Direction" = $Direction
"DestinationAddressPrefix" = $DestinationAddressPrefix
"DestinationPortRange" = $DestinationPortRange
"Priority" = $Priority
"Protocol" = $Protocol
"SourceAddressPrefix" = $SourceAddressPrefix
"SourcePortRange" = $SourcePortRange
}
}
}
# New array, using function above to fill in manual variables
$expected_rules = @()
# client NSG 1
$expected_rules += New_Rule -ResourceGroup "client_dev_main_01" -NSG "client_nsg_01" -Name "allow_clientsubnet_outbound" -Access "Allow" -DestinationAddressPrefix "10.0.1.0/24" -DestinationPortRange "*" -Direction "Outbound" -Priority 200 -Protocol "*" -SourceAddressPrefix "10.0.1.0/24" -SourcePortRange "*"
# # Comparison Setup
# Function to match existing_NSG(?)_Rule_name on NSG then on name of rule to get unique index for testing
# Input is Cloud object (existing_NSG(?)_Rule_name), output is matching index on NSG and name from expected_rules array
function Rule_Match ($rule) {
# Before the Pipe, we just getting count of expected_rules then feeding 0-12 as an index and getting back only indexes where the NSG matches
$index = ((0..($expected_rules.nsg.Count-1)) | Where-Object {$expected_rules.nsg[$_] -eq $rule.NSG})
# Only on indexes where the NSG matches, we look for a match on rule name. Output in the index of array from expected_rules
$expected_rules[$index] | Where-Object {$_.name -eq $rule.name}
}
# All the properties we compare on for the compare object tests
$Properties = "ResourceGroup", "NSG", "Name", "Access", "DestinationAddressPrefix", "DestinationPortRange", "Direction", "Priority", "Protocol", "SourceAddressPrefix", "SourcePortRange"
# # Testing
# As mentioned earlier, function calls relevant index of expected_rules for comparison.
# We are not matching same object with itself but $existing_NSG(?)_Rule_name with expected[index] where NSG and name match.
Describe "Rule Comparison Tests" {
It "client NSG 1 outbound rule comparison test" {
(Compare-Object (Rule_Match $existing_client_nsg_01_allow_clientsubnet_outbound) $existing_client_nsg_01_allow_clientsubnet_outbound `
-Property $Properties -IncludeEqual).SideIndicator | Should -match "=="
}