6 Replies Latest reply on Apr 14, 2014 3:56 AM by MrBoogiee

    Automated rollout of vCloud Customer using PowerShell

    MrBoogiee Novice

      Hi all,

       

      I've been trying to rollout a vCloud 5.5 environment using PowerCLI, and so far I've got the following working code:

       

      #Code written by MrBoogiee for SLTN Cloud Services (www.sltncloud.nl)

      $snapins = @("VMware.VimAutomation.Core", "VMware.VimAutomation.Cloud")

      foreach ($snapin in $snapins){

        try {

        Write-Host "Trying to load snapin $snapin"

        Add-PSSnapin $snapin -ErrorAction Stop

        Write-Host "$Snapin loaded"

        }

        catch {

        Write-Host "$snapin was already loaded or cannot be loaded"

        }

      }

       

       

      #Variables

      $orgName = "PowerCLI"

      $orgFullName = "PowerCLI Test Rollout"

      $cpu = 2

      $vdcDescription = $orgName

      $memory = 2

      $storage = 2

      $providerVdc = "Production01"

      $networkPool = "Production01-VXLAN-NP"

      $firstExternalIP = "1.1.1.1"

      $lastExternalIP = "1.1.1.2"

      $internalGateway = "192.168.1.1"

      $internalNetmask= "255.255.255.0"

      $firstInternalIP = "192.168.1.2"

      $lastInternalIP = "192.168.1.5"

       

       

      #Connect to vCloud URL

      Connect-CIServer vcloud.provider.org

       

       

      $externalNetwork = Get-ExternalNetwork -ProviderVdc $providerVdc -Name "Internet"

       

       

      # Create Organization

      New-Org -Name $orgName -FullName $orgFullName -Description ""

      $org = get-org -name $orgName

      $VAppLeaseSettings = $org.ExtensionData.Settings.GetvAppLeaseSettings()

      $VAppLeaseSettings.DeploymentLeaseSeconds = "0"

      $VAppLeaseSettings.StorageLeaseSeconds = "0"

      $VAppLeaseSettings.UpdateServerData()

      $vAppTemplateLeaseSettings = $org.ExtensionData.Settings.GetVAppTemplateLeaseSettings()

      $vAppTemplateLeaseSettings.StorageLeaseSeconds = "0"

      $vAppTemplateLeaseSettings.UpdateServerData()

      $OrgOperationLimitsSettings = $org.ExtensionData.Settings.GetOperationLimitsSettings()

      $OrgOperationLimitsSettings.ConsolesPerVmLimit = "4"

      $OrgOperationLimitsSettings.OperationsPerUser = "5"

      $OrgOperationLimitsSettings.OperationsPerOrg = "10"

      $OrgOperationLimitsSettings.UpdateServerData()

       

       

       

       

      # TODO stop if organization alread exists

       

       

      # Create Organization Virtual Datacenter

      New-OrgVdc -Org $orgName -AllocationModelAllocationPool -CpuAllocationGHz $cpu -MemoryAllocationGB $memory -Description $vdcDescription -Name $orgName -ProviderVdc $providerVdc -StorageAllocationGB $storage -NetworkPool $networkPool

       

       

      $orgVdc = Get-OrgVdc -Org $orgName -Name $orgName

      Set-OrgVdc -OrgVdc $orgVdc -CpuGuaranteedPercent 10 -MemoryGuaranteedPercent 100 -NetworkMaxCount 1 -ThinProvisioned $false -UseFastProvisioning $true

       

       

       

       

       

       

      # Create Edge Firewall

      $firewall = New-Object VMware.VimAutomation.Cloud.Views.Gateway

      $firewall.Name = $orgName

      $firewall.Configuration = New-Object VMware.VimAutomation.Cloud.Views.GatewayConfiguration

      $firewall.Configuration.BackwardCompatibilityMode = $false

      $firewall.Configuration.GatewayBackingConfig = "compact"

      $firewall.Configuration.UseDefaultRouteForDnsRelay = $true

      $firewall.Configuration.HaEnabled = $false

      $firewall.Configuration.EdgeGatewayServiceConfiguration = New-Object VMware.VimAutomation.Cloud.Views.GatewayFeatures

      $firewall.Configuration.GatewayInterfaces = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterfaces

      $firewall.Configuration.GatewayInterfaces.GatewayInterface = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterface

      $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].DisplayName = "uplink1"

      $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].Network = $externalNetwork.Href

      $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].InterfaceType = "uplink"

      $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].UseForDefaultRoute = $true

      $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].ApplyRateLimit = $false

       

       

      $externalSubnet = New-Object VMware.VimAutomation.Cloud.Views.SubnetParticipation

      $externalSubnet.Gateway = $externalNetwork.Gateway

      $externalSubnet.Netmask = $externalNetwork.Netmask

      $externalSubnet.IpAddress = $firstExternalIP

      $externalSubnet.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges

      $externalSubnet.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange

      $externalSubnet.IpRanges.IpRange[0].StartAddress = $firstExternalIP

      $externalSubnet.IpRanges.IpRange[0].EndAddress = $lastExternalIP

       

       

      $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].SubnetParticipation = $externalSubnet

       

       

      $orgVdc.ExtensionData.CreateEdgeGateway($firewall)

      # TODO wait for creation of Edge to complete

       

       

      While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

          write-host "Please wait, we're currently rolling out the Edge Firewall..."

      }

       

       

      # Create an Internal network on the Edge gateway

      $edgeGateway = Search-Cloud -QueryType EdgeGateway -Name $orgName | Get-CIView | where {$_.name -like "$orgname*"}

      $network = New-Object VMware.VimAutomation.Cloud.Views.OrgVdcNetwork

      $network.EdgeGateway = $edgeGateway.Id

      $network.isShared = $false

      $network.Configuration = New-Object VMware.VimAutomation.Cloud.Views.NetworkConfiguration

      $network.Name = $orgName + " Internal"

      $network.Configuration.IpScopes = New-Object VMware.VimAutomation.Cloud.Views.IpScopes

      $network.Configuration.FenceMode = "natRouted"

       

       

      $IpScope = New-Object VMware.VimAutomation.Cloud.Views.IpScope

      $IpScope.Gateway = $internalGateway

      $IpScope.Netmask = $internalNetmask

      $IpScope.Dns1 = $internalGateway

      $IpScope.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges

      $IpScope.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange

      $IpScope.IpRanges.IpRange[0].StartAddress = $firstInternalIP

      $IpScope.IpRanges.IpRange[0].EndAddress = $lastInternalIP

       

       

      $network.Configuration.IpScopes.IpScope += $IpScope

       

       

      $orgVdc.ExtensionData.CreateNetwork($network)

       

       

      While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

          write-host "Please wait, we're currently rolling out the internal network..."

      }

       

       

      #Setup the firewall services for the network

      $firewallService = New-Object VMware.VimAutomation.Cloud.Views.FirewallService

      $firewallService.DefaultAction = "drop"

      $firewallService.FirewallRule = New-Object VMware.VimAutomation.Cloud.Views.FirewallRule

       

       

      $firewallRule = New-Object VMware.VimAutomation.Cloud.Views.FirewallRule

      $firewallRule.IsEnabled = $true

      $firewallRule.Description = "Default Outgoing Allowed"

      $firewallRule.Protocols = New-Object VMware.VimAutomation.Cloud.Views.FirewallRuleTypeProtocols

      $firewallRule.Protocols.any = $true

      $firewallRule.Policy = "allow"

      $firewallRule.SourceIp = "internal"

      $firewallRule.DestinationIp = "external"

      $firewallRule.Port = "-1"

      $firewallRule.SourcePort = "-1"

       

       

      $firewallRule.EnableLogging = $false

      $firewallService.FirewallRule = $firewallRule

       

       

      $firewallService.LogDefaultAction = $false

      $firewallService.IsEnabled = $true

       

       

      $edge = Search-Cloud -QueryType EdgeGateway | Get-CIView | where {$_.name -eq $orgName}

      $edge.ConfigureServices($firewallService)

       

       

      While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

          write-host "Please wait, we're currently rolling out the default firewall rule..."

      }

      Again, this part works. When I try to add a NAT rule however, I run into problems. The code for this is as follows:

      # Setup the NAT rules for the network

      $natService = New-Object VMware.VimAutomation.Cloud.Views.NatService

      $natService.NatType = "ipTranslation"

      $natService.Policy = "allowTraffic"

      $natService.ExternalIp = $firstExternalIP

      $natService.IsEnabled = $true

      $natService.NatRule = New-Object VMware.VimAutomation.Cloud.Views.NatRule

       

       

      $natRule = New-Object VMware.VimAutomation.Cloud.Views.NatRule

      $natRule.IsEnabled = $true

      $natRule.RuleType = "GatewayNatRule"

      $natRule.Id = 0

      $natService.NatRule = $natRule

       

       

      $edge.ConfigureServices($natService)

      When I execute the above code, I receive the following error:

       

      Exception calling "ConfigureServices" with "1" argument(s): "Bad request  - Unexpected JAXB Exception  - cvc-complex-type.2.4.b: The content of element 'q1:NatRule' is not complete. One of '

      {"http://www.vmware.com/vcloud/v1.5":GatewayNatRule, "http://www.vmware.com/vcloud/v1.5":OneToOneBasicRule, "http://www.vmware.com/vcloud/v1.5":OneToOneVmRule, "http://www.vmware.com/vcloud/

      v1.5":PortForwardingRule, "http://www.vmware.com/vcloud/v1.5":VmRule}' is expected."

      At line:14 char:1

      + $edge.ConfigureServices($natService)

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

          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

          + FullyQualifiedErrorId : CloudException

      When I now try to resolve this by adding the following line before the "$natService.NatRule = $natRule" line:

      $natRule.GatewayNatRule = $true

      I receive the following error:

      Property 'GatewayNatRule' cannot be found on this object; make sure it exists and is settable.

      At line:4 char:1

      + $natRule.GatewayNatRule = $true

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

          + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

          + FullyQualifiedErrorId : PropertyAssignmentException

      When I do a $natRule | get-Member, the GatewayNatRule property does not exist. Does anybody have a clue how to work around this? There are plenty posts on the internet explaining how to create NAT rules for vApps, but I can't seem to find any on create NAT rules for OrgVDC Edges (and they really don't work the same way...). I want to be able to automatically roll out an SNAT rule where the internal network is being NATed to $firstExternalIP on the internet interface.

       

      Regards,

       

      MrBoogiee

        • 1. Re: Automated rollout of vCloud Customer using PowerShell
          yonish Novice

          Hello,

           

          Great work !!

           

          Did you manage to resolve the nat problem ?

           

          I  notice there several net type.

           

          Best regards,

           

          Yoni Shperling

          • 2. Re: Automated rollout of vCloud Customer using PowerShell
            MrBoogiee Novice

            Unfortunately not yet, I have reported it as a bug with VMware, and they are aware of the bug. It is also present in the NAT definition of vApp firewalls, but in that case they have a workaround by forcing 5.1 compatibility. For the Org VDC Edge configuration I have yet to receive a solution.

            • 3. Re: Automated rollout of vCloud Customer using PowerShell
              yonish Novice

              I also didn't find a way to create snat.

               

              The "while" is working at your environment? I manage to make it run to it only with "wait"

               

              While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

                  write-host "Please wait, we're currently rolling out the Edge Firewall..."

              }

              • 4. Re: Automated rollout of vCloud Customer using PowerShell
                yonish Novice

                By the way I am using this like that with csv .. below

                 

                I will try to post it in powercli linkedin VMware vSphere PowerCLI | LinkedIn

                 

                 

                 

                 

                 

                $snapins = @("VMware.VimAutomation.Core", "VMware.VimAutomation.Cloud")

                foreach ($snapin in $snapins){

                  try {

                  Write-Host "Trying to load snapin $snapin"

                  Add-PSSnapin $snapin -ErrorAction Stop

                  Write-Host "$Snapin loaded"

                  }

                  catch {

                  Write-Host "$snapin was already loaded or cannot be loaded"

                  }

                }

                 

                 

                 

                 

                 

                # Create all the Urgent Orgs

                Import-Csv E:\vcd2.csv | Foreach {

                 

                $externalNetwork = Get-ExternalNetwork -ProviderVdc $providerVdc -Name "external_net"

                 

                 

                # Create Organization

                New-Org -Name $_.OrgName -FullName $_.OrgFullName -Description $_.OrgDesc

                $org = get-org -name $_.OrgName

                $VAppLeaseSettings = $org.ExtensionData.Settings.GetvAppLeaseSettings()

                $VAppLeaseSettings.DeploymentLeaseSeconds = "0"

                $VAppLeaseSettings.StorageLeaseSeconds = "0"

                $VAppLeaseSettings.UpdateServerData()

                $vAppTemplateLeaseSettings = $org.ExtensionData.Settings.GetVAppTemplateLeaseSettings()

                $vAppTemplateLeaseSettings.StorageLeaseSeconds = "0"

                $vAppTemplateLeaseSettings.UpdateServerData()

                $OrgOperationLimitsSettings = $org.ExtensionData.Settings.GetOperationLimitsSettings()

                $OrgOperationLimitsSettings.ConsolesPerVmLimit = "0"

                $OrgOperationLimitsSettings.OperationsPerUser = "0"

                $OrgOperationLimitsSettings.OperationsPerOrg = "0"

                $OrgOperationLimitsSettings.UpdateServerData()

                 

                 

                # org create administrator    

                New-CIUser -Enabled -Name $_org_admin -Pasword $_org_admin_password  -Org $_.OrgName -Role "Organization Administrator"

                 

                 

                 

                 

                ####

                 

                 

                 

                 

                #Variables

                $providerVdc = "pvdc1_cluster1"

                $networkPool = "pvdc1_cluster1-VXLAN-NP"

                $internalGateway = "172.17.100.254"

                $internalNetmask= "255.255.255.0"

                $firstInternalIP = "172.17.100.2"

                $lastInternalIP = "172.17.100.50"

                 

                 

                 

                 

                ###2

                 

                 

                # #New-OrgVdc -AllocationModelAllocationPool -CpuAllocationGHz 2 -Description $_.OrgDesc -MemoryAllocationGB 20 -Name $_.OrgvDCName -Org $_.OrgName -ProviderVdc "pvdc1_cluster1" -StorageAllocationGB "100" -NetworkPool pvdc1_cluster1-VXLAN-NP

                # TODO stop if organization alread exists

                 

                 

                # Create Organization Virtual Datacenter

                New-OrgVdc -Org $_.OrgvDCName -AllocationModelAllocationPool -CpuAllocationGHz $_.CPU_GHz -MemoryAllocationGB $_.Memory_GB -Description $_.OrgDesc -Name $_.OrgvDCName -ProviderVdc "pvdc1_cluster1" -StorageAllocationGB $_.Storage_GB -NetworkPool $networkPool

                 

                 

                $orgVdc = Get-OrgVdc -Org $_.OrgvDCName -Name $_.OrgName

                Set-OrgVdc -OrgVdc $orgVdc -CpuGuaranteedPercent 1 -MemoryGuaranteedPercent 20 -NetworkMaxCount $_.NetworkMaxCount -ThinProvisioned $true

                 

                # }

                 

                ####

                #edge

                 

                # Create Edge Firewall

                $firewall = New-Object VMware.VimAutomation.Cloud.Views.Gateway

                $firewall.Name = $orgName

                $firewall.Configuration = New-Object VMware.VimAutomation.Cloud.Views.GatewayConfiguration

                $firewall.Configuration.BackwardCompatibilityMode = $false

                $firewall.Configuration.GatewayBackingConfig = "compact"

                $firewall.Configuration.UseDefaultRouteForDnsRelay = $true

                $firewall.Configuration.HaEnabled = $false

                $firewall.Configuration.EdgeGatewayServiceConfiguration = New-Object VMware.VimAutomation.Cloud.Views.GatewayFeatures

                $firewall.Configuration.GatewayInterfaces = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterfaces

                $firewall.Configuration.GatewayInterfaces.GatewayInterface = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterface

                $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].DisplayName = "uplink1"

                $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].Network = $externalNetwork.Href

                $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].InterfaceType = "uplink"

                $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].UseForDefaultRoute = $true

                $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].ApplyRateLimit = $false

                 

                 

                $externalSubnet = New-Object VMware.VimAutomation.Cloud.Views.SubnetParticipation

                $externalSubnet.Gateway = $externalNetwork.Gateway

                $externalSubnet.Netmask = $externalNetwork.Netmask

                $externalSubnet.IpAddress = $_.firstExternalIP # $firstExternalIP

                $externalSubnet.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges

                $externalSubnet.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange

                $externalSubnet.IpRanges.IpRange[0].StartAddress = $_.firstExternalIP # ### $firstExternalIP

                $externalSubnet.IpRanges.IpRange[0].EndAddress =   $_.lastExternalIP  # ### $lastExternalIP

                 

                 

                $firewall.Configuration.GatewayInterfaces.GatewayInterface[0].SubnetParticipation = $externalSubnet

                 

                 

                $orgVdc.ExtensionData.CreateEdgeGateway($firewall)

                # TODO wait for creation of Edge to complete

                sleep 120

                 

                #While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

                #if ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

                #sleep 120

                #   write-host "Please wait, we're currently rolling out the Edge Firewall..."

                #}

                 

                 

                # Create an Internal network on the Edge gateway

                $edgeGateway = Search-Cloud -QueryType EdgeGateway -Name $orgName | Get-CIView | where {$_.name -like "$orgname*"}

                $network = New-Object VMware.VimAutomation.Cloud.Views.OrgVdcNetwork

                $network.EdgeGateway = $edgeGateway.Id

                $network.isShared = $false

                $network.Configuration = New-Object VMware.VimAutomation.Cloud.Views.NetworkConfiguration

                $network.Name = "$orgName-Internal"

                $network.Configuration.IpScopes = New-Object VMware.VimAutomation.Cloud.Views.IpScopes

                $network.Configuration.FenceMode = "natRouted"

                 

                 

                $IpScope = New-Object VMware.VimAutomation.Cloud.Views.IpScope

                $IpScope.Gateway = $internalGateway

                $IpScope.Netmask = $internalNetmask

                $IpScope.Dns1 = $internalGateway

                $IpScope.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges

                $IpScope.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange

                $IpScope.IpRanges.IpRange[0].StartAddress = $firstInternalIP

                $IpScope.IpRanges.IpRange[0].EndAddress = $lastInternalIP

                 

                 

                $network.Configuration.IpScopes.IpScope += $IpScope

                 

                 

                $orgVdc.ExtensionData.CreateNetwork($network)

                 

                sleep 20

                 

                While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

                    write-host "Please wait, we're currently rolling out the internal network..."

                }

                 

                 

                #Setup the firewall services for the network

                $firewallService = New-Object VMware.VimAutomation.Cloud.Views.FirewallService

                $firewallService.DefaultAction = "drop"

                $firewallService.FirewallRule = New-Object VMware.VimAutomation.Cloud.Views.FirewallRule

                 

                 

                $firewallRule = New-Object VMware.VimAutomation.Cloud.Views.FirewallRule

                $firewallRule.IsEnabled = $true

                $firewallRule.Description = "Default Outgoing Allowed"

                $firewallRule.Protocols = New-Object VMware.VimAutomation.Cloud.Views.FirewallRuleTypeProtocols

                $firewallRule.Protocols.any = $true

                $firewallRule.Policy = "allow"

                $firewallRule.SourceIp = "internal"

                $firewallRule.DestinationIp = "external"

                $firewallRule.Port = "-1"

                $firewallRule.SourcePort = "-1"

                 

                 

                $firewallRule.EnableLogging = $false

                $firewallService.FirewallRule = $firewallRule

                 

                 

                $firewallService.LogDefaultAction = $false

                $firewallService.IsEnabled = $true

                 

                 

                $edge = Search-Cloud -QueryType EdgeGateway | Get-CIView | where {$_.name -eq $orgName}

                $edge.ConfigureServices($firewallService)

                 

                 

                While ((Search-Cloud -QueryType EdgeGateway | get-ciview | where {$_.name -eq $orgName}).tasks.task.Status -eq "running") {

                    write-host "Please wait, we're currently rolling out the default firewall rule..."

                }

                #Again, this part works. When I try to add a NAT rule however, I run into problems. The code for this is as follows:

                # Setup the NAT rules for the network

                $natService = New-Object VMware.VimAutomation.Cloud.Views.NatService

                $natService.NatType = "ipTranslation"

                $natService.Policy = "allowTraffic"

                $natService.ExternalIp = $firstExternalIP

                $natService.IsEnabled = $true

                $natService.NatRule = New-Object VMware.VimAutomation.Cloud.Views.NatRule

                 

                 

                $natRule = New-Object VMware.VimAutomation.Cloud.Views.NatRule

                $natRule.IsEnabled = $true

                $natRule.RuleType = "GatewayNatRule"

                $natRule.Id = 3

                $natService.NatRule = $natRule

                 

                 

                $edge.ConfigureServices($natService)

                 

                 

                }

                • 5. Re: Automated rollout of vCloud Customer using PowerShell
                  MrBoogiee Novice

                  That works perfectly to be honest. Because I'm checking wether the status equals running, it only continues after the progress has finished.

                  • 6. Re: Automated rollout of vCloud Customer using PowerShell
                    MrBoogiee Novice

                    Please make reference to your sources in your scripts when you upload them to fe. LinkedIn (I fe. like that )