VMware Cloud Community
Chrigoli
Enthusiast
Enthusiast

Sample script to modify vApp (Network, Firewall Rules, Start/Stop Order, GuestCustomization)

Hi all

I would like to share a script I developed the last few days.

What the script does:

- Add an internal network called "Internal" with NAT/Firewall to a vApp

- Add Firewall rules (f.e. RDP)

- Set the default stop action for every VM within this vApp to "Shutdown" instead of PowerOff

- Enable GuestCustomization for each VM (Enable and SID change, disable all other options like Admin Password)

- Upgrade HW Version to latest (HW9)

---------------------------------------------------------------------------------------------------------------------------------------------

# 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

}

#Connect to vCloud Cell and vCenter

Connect-CIServer -Server vcloudcell1

Connect-VIServer -Server vcenter1

$myOrgInput = Read-Host "Please enter the Organization name:"

$myvAppInput = Read-Host "Please enter the vApp name:"

try {

    $myOrg = Get-Org -Name $myOrgInput

} catch {

    [System.Windows.Forms.MessageBox]::Show(“Organization ” + $myOrgInput + " does not exist.",”Org not found.”,0,[System.Windows.Forms.MessageBoxIcon]::Exclamation)

    Exit

}

try {

    $vApps = Get-CIVApp -Name $myvAppInput -Org $myOrg

} catch {

    [System.Windows.Forms.MessageBox]::Show(“vApp ” + $myvAppInput + " does not exist.",”vApp not found”,0,[System.Windows.Forms.MessageBoxIcon]::Exclamation)

    Exit

}

foreach ($vApp in $vApps) {

    #Get org network

    $NATOrgNetwork = Get-OrgNetwork "My External Org Network" -Org $myOrg

    #Add internal network

    New-CIVAppNetwork -ParentOrgNetwork $NATOrgNetwork -VApp $vApp -Routed -DnsSuffix "lab.local" -Gateway "172.20.20.1" -Name "Internal" -Netmask "255.255.255.0" -PrimaryDns "10.1.10.250" -StaticIPPool "172.20.20.100-172.20.20.199"

   

    #Create Firewall Rules

   

    $networkConfigSection = $vApp.ExtensionData.GetNetworkConfigSection()

    $vAppNetwork = $networkConfigSection.NetworkConfig | where {$_.networkName -eq "Internal"}

   

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

    $fwService.DefaultAction = "drop"

    $fwService.LogDefaultAction = $false

    $fwService.IsEnabled = $true

    $fwService.FirewallRule = New-Object vmware.vimautomation.cloud.views.firewallrule

    $fwService.FirewallRule += New-Object vmware.vimautomation.cloud.views.firewallrule

    $fwService.FirewallRule += New-Object vmware.vimautomation.cloud.views.firewallrule

    $fwService.FirewallRule += New-Object vmware.vimautomation.cloud.views.firewallrule

   

    #First Rule - Allow outgoing

    $fwService.FirewallRule[0].isenabled = $true

    $fwService.FirewallRule[0].description = "Outgoing Traffic"

    $fwService.FirewallRule[0].protocols = New-Object vmware.vimautomation.cloud.views.firewallRuleTypeProtocols

    $fwService.FirewallRule[0].protocols.ANY = $true

    $fwService.FirewallRule[0].policy = "allow"

    $fwService.FirewallRule[0].destinationIp = "external"

    $fwService.FirewallRule[0].sourceip = "internal"

   

    #Second Rule - RDP

    $fwService.FirewallRule[1].isenabled = $true

    $fwService.FirewallRule[1].description = "RDP"

    $fwService.FirewallRule[1].protocols = New-Object vmware.vimautomation.cloud.views.firewallRuleTypeProtocols

    $fwService.FirewallRule[1].protocols.Tcp = $true

    $fwService.FirewallRule[1].policy = "allow"

    $fwService.FirewallRule[1].port = "3389"

    $fwService.FirewallRule[1].destinationIp = "internal"

    $fwService.FirewallRule[1].sourceip = "external"

    #Third Rule - Ping ICMP

    $fwService.FirewallRule[2].isenabled = $true

    $fwService.FirewallRule[2].description = "PING"

    $fwService.FirewallRule[2].protocols = New-Object vmware.vimautomation.cloud.views.firewallRuleTypeProtocols

    $fwService.FirewallRule[2].protocols.Icmp = $true

    $fwService.FirewallRule[2].policy = "allow"

    $fwService.FirewallRule[2].destinationIp = "internal"

    $fwService.FirewallRule[2].sourceip = "external"

   

    $vAppNetwork.Configuration.Features = $vAppNetwork.Configuration.Features | where {!($_ -is [vmware.vimautomation.cloud.views.firewallservice])}

    $vAppNetwork.configuration.features += $fwService

    $networkConfigSection.UpdateServerData()

   

    #For each VM in the vApp

    $vms = Get-CIVM -VApp $vApp

    foreach ($vm in $vms) {

        #Enable guest customization

        $GuestCustomization = $vm.ExtensionData.GetGuestCustomizationSection()

        $GuestCustomization.Enabled = $true

        $GuestCustomization.ChangeSid = $true

        $GuestCustomization.ResetPasswordRequired = $false

        $GuestCustomization.AdminPasswordEnabled = $false

        $GuestCustomization.UpdateServerData()

       

        #Stop Rule -> set to Shutdown

        $myVM2StartRule = Get-CIVAppStartRule -VApp $vApp -VM $vm

        Set-CIVAppStartRule -StartRule $myVM2StartRule -StopAction ShutDown

       

        #Upgrade HW version to latest

        $vsphereVMView = Get-View –RelatedObject $vm.ExtensionData

        $vivm = Get-VIObjectByVIView $vsphereVMView

        $vmview = Get-View -id $vivm.Id

        $param = @($null)

        $vmview.gettype().GetMethod("UpgradeVM_Task").Invoke($vmview,$param)

        }

}

5 Replies
pwmiller
Enthusiast
Enthusiast

Thanks Chrigoli!

Excellent work here. I'd like to add for anybody curious, that this is appears to be the only way in vCD 5.5 to update the "RetainNetInfoAcrossDeployments" parameter on a network as well, since the cmdlet "Update-CIVAppNetwork" is missing this crucial parameter.

For those interested, updating this can be accomplished using Chrigoli's method and some additional configuration:

$vapp = Get-CIVApp "my_vapp"

$networkconfigsection = $vapp.ExtensionData.GetNetworkConfigSection()

$vappnetwork = $networkconfigsection | Where-Object {$_.networkName -match "name_of_your_network"}

$vappnetwork.configuration.RetainNetInfoAcrossDeployments = $true

$networkconfigsection.UpdateServerData()

This really helps in scripting the configuration of networks for new vApps as some parameters don't appear to be "easily" visible through the default set of setters/getters with PowerCLI. Historically, this parameter has had a bad reputation as well (not updating when making REST API calls in vCD less than 1.5.1). The method above, however, seems to work.

Reply
0 Kudos
AshleyBanks
Contributor
Contributor

Was hoping to use your script to simply add a firewall rule to an existing edge gateway I try running the following code :-

connect-ciserver xxxxxxxxx.xxx.xxxx.xxx.xxx -user xxxxxxxx -password xxxxxxxx

$myOrgInput = "orgname"
$myvAppInput = "vappname"
$myNetwork = "routed network name"

$myOrg = Get-Org -Name $myOrgInput


$vApps = Get-CIVApp -Name $myvAppInput -Org $myOrg

foreach ($vApp in $vApps) {

    $networkConfigSection = $vApp.ExtensionData.GetNetworkConfigSection()

    $vAppNetwork = $networkConfigSection.NetworkConfig | where {$_.networkName -eq $myNetwork}
    $fwService = New-Object vmware.vimautomation.cloud.views.firewallservice
    $fwService.DefaultAction = "allow"
    $fwService.LogDefaultAction = $true
    $fwService.IsEnabled = $true
    $fwService.FirewallRule = New-Object vmware.vimautomation.cloud.views.firewallrule
    $fwService.FirewallRule += New-Object vmware.vimautomation.cloud.views.firewallrule


#First Rule - Allow outgoing

    $fwService.FirewallRule[0].isenabled = $true
    $fwService.FirewallRule[0].description = "Outgoing Traffic"
    $fwService.FirewallRule[0].protocols = New-Object vmware.vimautomation.cloud.views.firewallRuleTypeProtocols
    $fwService.FirewallRule[0].protocols.ANY = $true
    $fwService.FirewallRule[0].policy = "allow"
    $fwService.FirewallRule[0].destinationIp = "external"
    $fwService.FirewallRule[0].sourceip = "internal"

#Second Rule - RDP

    $fwService.FirewallRule[1].isenabled = $true
    $fwService.FirewallRule[1].description = "RDP"
    $fwService.FirewallRule[1].protocols = New-Object vmware.vimautomation.cloud.views.firewallRuleTypeProtocols
    $fwService.FirewallRule[1].protocols.Tcp = $true
    $fwService.FirewallRule[1].policy = "allow"
    $fwService.FirewallRule[1].port = "3389"
    $fwService.FirewallRule[1].destinationIp = "internal"
    $fwService.FirewallRule[1].sourceip = "external"

    $vAppNetwork.Configuration.Features = $vAppNetwork.Configuration.Features | where {!($_ -is [vmware.vimautomation.cloud.views.firewallservice])}
    $vAppNetwork.configuration.features += $fwService
    $networkConfigSection.UpdateServerData()
}

but after running this although I don't recieve an error the firewall rules do not get added to the edge.

what am I doing wrong

Reply
0 Kudos
Chrigoli
Enthusiast
Enthusiast

I'm not sure if you also need a connection to the vCenter. Probably you could try this.

Reply
0 Kudos
AshleyBanks
Contributor
Contributor

Thanks for the reply added the line to connect to vcenter under the cloud connection line. Still same issue. It is odd that I don't get any error yet none of the details I have entered are changed.

Reply
0 Kudos
msmoritz
Contributor
Contributor


I'm trying to to a mass update for existing vApp/VMs to reflect changes across an entire organiztion, however, every method I try to use on my server generates an error (below).  


I've updated all of the network adapters in in the VMs to change their backing networks, but I need GuestCustomization to rerun so that the machines display their proper IP addresses on a pre-login screen, as well as forcing the NIC to reconfigure the next time the vApp is powered on.


        $GuestCustomization = $vm.ExtensionData.GetGuestCustomizationSection()


        $GuestCustomization.Required = $true


        $GuestCustomization.CustomizationScript=$GuestCustomization.CustomizationScript.replace('172.17','172.25')


        $GuestCustomization.UpdateServerData()


Exception calling "UpdateServerData" with "0" argument(s): "Bad request  - Unexpected JAXB Exception  - cvc-complex-type.2.4.a: 



Invalid content was found starting with element 'AdminAutoLogonEnabled'. One of '{"http://www.vmware.com/vcloud/v1.5":Link, 



WC[##other:"http://www.vmware.com/vcloud/v1.5"]}' is expected."



At line:1 char:1



+ $gcs.UpdateServerData()



+ ~~~~~~~~~~~~~~~~~~~~~~~


    + CategoryInfo          : NotSpecified: (Smiley Happy [], MethodInvocationException


    + FullyQualifiedErrorId : CloudException


Reply
0 Kudos