5 Replies Latest reply on Nov 3, 2014 7:59 AM by msmoritz

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

    Chrigoli Enthusiast

      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)

              }

      }

        • 1. Re: Sample script to modify vApp (Network, Firewall Rules, Start/Stop Order, GuestCustomization)
          pwmiller 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.

          • 2. Re: Sample script to modify vApp (Network, Firewall Rules, Start/Stop Order, GuestCustomization)
            AshleyBanks Novice

            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

            • 3. Re: Sample script to modify vApp (Network, Firewall Rules, Start/Stop Order, GuestCustomization)
              Chrigoli Enthusiast

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

              • 4. Re: Sample script to modify vApp (Network, Firewall Rules, Start/Stop Order, GuestCustomization)
                AshleyBanks Novice

                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.

                • 5. Re: Sample script to modify vApp (Network, Firewall Rules, Start/Stop Order, GuestCustomization)
                  msmoritz Novice


                  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: ( [], MethodInvocationException


                      + FullyQualifiedErrorId : CloudException