Link to home
Start Free TrialLog in
Avatar of David Sankovsky
David SankovskyFlag for Israel

asked on

Powershell script not populating an array

Hey experts, I'm at the end of my rope here.


I have the following script:

#region Global Parameters
$inputFile = 'subnets.csv'
$folder = $PSScriptRoot
$addrconfFile = 'addrfortiready.txt'
$addrgrpconfFile = 'addrgrpfortiready.txt'
$groups = @()
$csv = import-csv -Path $folder\$inputFile
#endregion


Function Get-NetworkIPv4
{
   [CmdletBinding()]
   Param(
      [Parameter(Position=0, Mandatory=$true, ParameterSetName='IPAndLength')]
      [String]$IPAddress,
      [Parameter(Position=1, Mandatory=$true, ParameterSetName='IPAndLength')]
      [ValidateRange(0, 32)]
      [Int]$Cidr,
      [Parameter(Position=0, Mandatory=$true, ParameterSetName='SubnetCidr')]
      [String]$SubnetCidr
   )
   If ($SubnetCidr) {
      $IPAddress, $Cidr = $SubnetCidr.Split('/')
   }
   
   $parsedIpAddress = [System.Net.IPAddress]::Parse($IPAddress)
   $shift = 64 - $Cidr
   
   [System.Net.IPAddress]$subnet = 0
   If ($Cidr -ne 0) {
      $subnet = [System.Net.IPAddress]::HostToNetworkOrder([int64]::MaxValue -shl $shift)
   }


   [System.Net.IPAddress]$network = $parsedIpAddress.Address -band $subnet.Address


   Return [PSCustomObject]@{
      Network = $network
      SubnetMask = $subnet
   }
}


function BuildGroups
{
    foreach ($line in $csv)
    {
        if ($groups -notcontains $line.Group)
        {
            $groups += $line.Group
        }
    }
}


Function CreateAddrFile
{
    $(
       'config firewall address'
       Import-Csv -Path $folder\$inputFile | ForEach-Object {
          $subnet = Get-NetworkIPv4 -SubnetCidr $_.Subnet -ErrorAction Stop
          "    edit `"$($_.Name)`""
          "        set subnet $($subnet.Network) $($subnet.SubnetMask)"
          '    next'
       }
       'end'
    ) | Set-Content -Path $folder\$addrconfFile
}


Function CreateAddrgrpFile
{
    $(
       'config firewall addrgrp'
        foreach ($grp in $groups)
        {
            $grpmmbrs = @()
           "    edit `"$grp`""
            foreach ($line in $csv)
            {
              if ($line.group -eq $grp)
                {
                    $grpmmbrs += "`"$($line.Name)`""
                }
           }
        "        set member $($grpmmbrs -join ' ')"
        '    next'
        }
           'end'
    ) | Set-Content -Path $folder\$addrgrpconfFile
}


Function CheckCSVColumnsExist
{
    $headerstocheck = 'Name','Subnet','Group'
    $headers = $csv.psobject.Properties |Select-Object -ExpandProperty Name
    $headers
    foreach ($header in $headerstocheck)
    {
        if ($headers -notcontains $header)
        {
            return $false
        }
    }
    return $true       
}


Function Assert-FolderStructure
{
    if (!(Test-Path $PSScriptRoot\$addrconfFile))
    {
        New-Item -path $folder -name $addrconfFile -type "file"
    }
    if (!(Test-Path $PSScriptRoot\$addrgrpconfFile))
    {
        New-Item -path $folder -name $addrgrpconfFile -type "file"
    }
}


Function SanityChecks
{
    #Make Sure that the invocation folder contains the initial source file
    if (!(Test-Path $PSScriptRoot\$inputFile))
    {
        Write-Host "Fatal Error - No CSV File"
        exit (1)
    }
    #Make sure that the CSV file has the required headers
    if (!(CheckCSVColumnsExist))
    {
        Write-Host "Fatal Error - Wrong Headers"
        exit (2)
    }
    Assert-FolderStructure
}


SanityChecks
BuildGroups
Write-Host "I have these groups:"
$groups
CreateAddrFile
CreateAddrgrpFile

Open in new window

The function that creates the address files (CreateAddrFile) Works great

But the function that later allows me to build groups based on the last column in the CSV doesn't, And it seems that the problem lies in the function that populates the array of Groups with unique group names from the CSV.

and I can't for the life of me understand why, especially since when I take it out of  this big chunk of code and run only the relevant parts alone, it works great:


$inputFile = 'subnets.csv'
$addrgrpconfFile = 'addrgrpfortiready.txt'
$folder = $PSScriptRoot
$groups = @()
$csv = import-csv -Path $folder\$inputFile
foreach ($line in $csv)
{
    if (!($groups -contains $line.Group))
    {
        $groups += $line.Group
    }
}


Function CreateAddrgrpFile
{
    $csv = import-csv -Path $folder\$inputFile
    $(
       'config firewall addrgrp'
        foreach ($grp in $groups)
        {
            $grpmmbrs = @()
           "    edit `"$grp`""
            foreach ($line in $csv)
            {
              if ($line.group -eq $grp)
                {
                    $grpmmbrs += "`"$($line.Name)`""
                }
           }
        "        set member $($grpmmbrs -join ' ')"
        '    next'
        }
           'end'
    ) | Set-Content -Path $addrgrpconfFile
}
CreateAddrgrpFile

Open in new window


I'm attaching a base file to run examples off:subnets.csv

ASKER CERTIFIED SOLUTION
Avatar of oBdA
oBdA

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial