New-Object use in PowerCLI script wipes previous vCloud firewall rule upload

Hi,

I have a script to upload firewall rules to vCloud Director from csv and it’s overwriting the entire firewall config everytime due to the use of New-Object.

The Line that I think is causing the issue is this one:

$fwService = New-Object vmware.vimautomation.cloud.views.firewallservice

Without having to re-write the entire script (which was not authored by me - but was provided by a supplier and I think they got it off the internet!) can we keep the existing rules and use something like add-member instead?

Thanks!

Scott.

# Replaces all rules for a given vshield with the ones from a CSV file.
# CSV header is: Num,Descr,Proto,SrcIP,SrcPort,DstIP,DstPortRange,Policy,Direction,isEnabled,EnableLogging
# http://pubs.vmware.com/vcd-51/index.jsp?topic=%2Fcom.vmware.vcloud.api.reference.doc_51%2Fdoc%2Ftypes%2FFirewallRuleType.html
# Note: SrcPort can be -1 (for any), any or a port number. DstPortRange can be any or a port number range (ex: 22-26)
param (
[parameter(Mandatory = $true, HelpMessage="vCD Server")][alias("-server","s")][ValidateNotNullOrEmpty()][string[]]$CIServer,
[parameter(Mandatory = $true, HelpMessage="Org")][alias("-vOrg","o")][ValidateNotNullOrEmpty()][string[]]$orgName,
[parameter(Mandatory = $true, HelpMessage="OrgNet")][alias("-orgNet","n")][ValidateNotNullOrEmpty()][string[]]$orgNet,
[parameter(Mandatory = $true, HelpMessage="CSV Path")][alias("-file","f")][ValidateNotNullOrEmpty()][string[]]$csvFile
)
 
# Add in the VI Toolkit
if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null ) {
Add-PSsnapin VMware.VimAutomation.Core
}
if ( (Get-PSSnapin -Name VMware.VimAutomation.Cloud -ErrorAction SilentlyContinue) -eq $null ) {
Add-PSsnapin VMware.VimAutomation.Cloud
}
 
try {
Connect-CIServer -Server $CIServer 2>&1 | out-null
} catch {
Exit
}
 
#Search EdgeGW
try {
  $myOrgNet = Get-Org -Name $orgName | Get-OrgNetwork -Name $orgNet
  $edgeHREF = $myOrgNet.ExtensionData.EdgeGateway.Href
  $edgeView = Search-Cloud -QueryType EdgeGateway -ErrorAction Stop | Get-CIView | where {$_.href -eq $edgeHREF}
} catch {
[System.Windows.Forms.MessageBox]::Show("Exception: " + $_.Exception.Message + " - Failed item:" + $_.Exception.ItemName ,"Error.",0,[System.Windows.Forms.MessageBoxIcon]::Exclamation)
  Exit
}
 
#Item to Configure Services
$edgeView.Configuration.EdgeGatewayServiceConfiguration
$fwService = New-Object vmware.vimautomation.cloud.views.firewallservice
$fwService.DefaultAction = "drop"
$fwService.LogDefaultAction = $false
$fwService.IsEnabled = $true
$fwService.FirewallRule = @()
 
Import-CSV -path $csvFile |
foreach-object
{
$fwService.FirewallRule @() New-Object vmware.vimautomation.cloud.views.firewallrule
 
$rowNum = $_.Num -as [int]
 
$fwService.FirewallRule[$rowNum].description = $_.Descr
$fwService.FirewallRule[$rowNum].protocols = New-Object vmware.vimautomation.cloud.views.firewallRuleTypeProtocols
switch ($_.Proto)
{
"tcp" { $fwService.FirewallRule[$rowNum].protocols.tcp = $true }
"udp" { $fwService.FirewallRule[$rowNum].protocols.udp = $true }
"any" { $fwService.FirewallRule[$rowNum].protocols.any = $true }
default { $fwService.FirewallRule[$rowNum].protocols.any = $true }
}
$fwService.FirewallRule[$rowNum].sourceip = $_.SrcIP
 
if ($_.SrcPort -eq "any" ) { $srcPort = "-1" } else { $srcPort = $_.SrcPort }
$fwService.FirewallRule[$rowNum].sourceport = $srcPort
 
$fwService.FirewallRule[$rowNum].destinationip = $_.DstIP
$fwService.FirewallRule[$rowNum].destinationportrange = $_.DstPortRange
$fwService.FirewallRule[$rowNum].policy = $_.Policy
#$fwService.FirewallRule[$rowNum].direction = $_.Direction
#$fwService.FirewallRule[$rowNum].MatchOnTranslate = [System.Convert]::ToBoolean($_.MatchOnTranslate)
$fwService.FirewallRule[$rowNum].isenabled = [System.Convert]::ToBoolean($_.isEnabled)
$fwService.FirewallRule[$rowNum].enablelogging = [System.Convert]::ToBoolean($_.EnableLogging)
}
 
#configure Edge
$edgeView.ConfigureServices($fwService)

The only real way I can imagine you could accomplish this is by getting the current list of firewall rules, adding those to your additional rules. I unfortunately do not have a vCloud Director environment to see what options are available.

Add this as a parameter and do something like this:
[parameter(Mandatory = $true, HelpMessage=“Append”)][alias(“-append”,“a”)][ValidateNotNullOrEmpty()][boolean]$Append

Switch ($Append)
{
$True {
$fwService = New-Object vmware.vimautomation.cloud.views.firewallservice
$fwService.DefaultAction = “drop”
$fwService.LogDefaultAction = $false
$fwService.IsEnabled = $true
$fwService.FirewallRule = @()
$fwService.FirewallRule += $edgeView.GetServices.Firewall #<– If you can get the current list of rules, i just don't know what options you have to get the info. This is definitely not right as is, but may give a starting point.
}
$False {
$fwService = New-Object vmware.vimautomation.cloud.views.firewallservice
$fwService.DefaultAction = "drop"
$fwService.LogDefaultAction = $false
$fwService.IsEnabled = $true
$fwService.FirewallRule = @()
}
}