Cloud Pod Architecture, double administration?

RhofmanZ - februari 13th, 2019

It was the first time I implemented a Cloud Pod Architecture (#CPA) at a customer. They wanted an active-active environment over 2 datacenters.
So we made two Pod’s within Horizon 7.5.1 and joined each other via CPA.
Great thing, we even got extra features – Global entitlements.
Because we have two Pod’s, we also have two view administrator consoles. In both view administrator console we can see that we are a CPA, because in the dashboard we have a Local Pod and a remote Pod.

This is the only thing we can see though.
That we can’t see more made it difficult for engineers to manage.
Also a down side of this is that we need to create the same application pools and/or farms in both POD’s. After that we needed to connect both pools seperatly to the global entitlement. A lot of work and a lot of maintenance.

At the time of writing I even learned that when you use CPA, the use of local entitlements is not considered to be a good option. Local entitlements would not work properly.
So it is recommended to use global entitlements.

We needed to thinkof something to make it easier for colleagues to work with an active-active Horizon environment. To not create double entries.
So we created an automation script.

With this script you can use an excel document to import applications in both POD’s. What do you need?

Application name and farm
Application information and you can add multiple entitlements

The script

You can use this script if you like.
I changed a lot within the script to make it anonymous. It should work with the right adjustments.

Also you must install a Vmware powercli module.
– Vmware.HV.Helper

cls

$vCenterServerAccount = "<domain>\srv-horizon7"
$Key = Get-Content "\\<location>\AES_KEY_FILE.key"
$DatabaseCredentials = New-Object System.Management.Automation.PSCredential($vCenterServerAccount,(Get-Content "\\<location>\AES_PASSWORD_FILE.txt" | ConvertTo-SecureString -Key $Key))
$POD1 = <enter your POD1 horizon server>

Connect-HVserver -server $POD1 -Credential $DatabaseCredentials

$hzServices = $Global:DefaultHVServers.ExtensionData
$application = New-Object VMware.Hv.ApplicationService

$appSpec = $application.getApplicationSpecHelper()
$AppPoolSpec = $appSpec.getDataObject()

$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $false

$WorkBook = $objExcel.Workbooks.Open('\\<location of excel>\Apps.xlsx')
$worksheet = $workbook.sheets.item("Apps")
$intRowMax =  ($worksheet.UsedRange.Rows).count


Write-host "*********************************************************************"
Write-Host "Automatically provision apps within Horizon, input from an excel"
Write-Host "Processing: " $intRowMax " rows"
Write-Host ""

# Read excel, ignore first line
for ($intRow = 2 ; $intRow -le $intRowMax ; $intRow++) {

    
    
    Write-Host "Nummer:  "$intRow

    $App_ID = $worksheet.cells.item($intRow, 1).text
    $App_ID
    $AppPoolSpec.Data.Name = $App_ID

    $APP_DisplayName = $worksheet.cells.item($intRow, 2).text
    
    $APP_DisplayName
    $appPoolSpec.Data.DisplayName = $APP_DisplayName
    $AppPoolSpec.Data.Enabled = $true

    $App_Farm = $worksheet.cells.item($intRow, 3).text
    $Farm = Get-HVFarm $App_Farm

    $AppPoolSpec.ExecutionData.Farm = $Farm.Id

    $App_Version = $worksheet.cells.item($intRow, 4).text
    $App_Version
    $AppPoolSpec.ExecutionData.Version = $App_Version

    $App_Publisher = $worksheet.cells.item($intRow, 5).text
    $App_Publisher
    $AppPoolSpec.ExecutionData.Publisher = $App_Publisher

    $App_StartFolder = $worksheet.cells.item($intRow, 7).text
    $App_StartFolder
    $AppPoolSpec.ExecutionData.Startfolder = $App_StartFolder

    $App_Parameters = $worksheet.cells.item($intRow, 8).text
    $App_Parameters
    $AppPoolSpec.ExecutionData.Args = $App_Parameters

    $App_Path = $worksheet.cells.item($intRow, 9).text
    $App_Path
    $AppPoolSpec.ExecutionData.ExecutablePath = $App_Path

    $AppPoolSpec.Data.Description
    $application.Application_Create($hzServices,$AppPoolSpec)

        Start-Sleep -s 10
 
# if you want to you local entitlements in a non CPA environment
    
#    $App_Entitlement1 = $worksheet.cells.item($intRow, 10).text        
#    $App_Entitlement2 = $worksheet.cells.item($intRow, 11).text        
#    $App_Entitlement3 = $worksheet.cells.item($intRow, 12).text        
#    $App_Entitlement4 = $worksheet.cells.item($intRow, 13).text        
#    $App_Entitlement5 = $worksheet.cells.item($intRow, 14).text        
#    $App_Entitlement6 = $worksheet.cells.item($intRow, 15).text        
#    $App_Entitlement7 = $worksheet.cells.item($intRow, 16).text      


    ## Add entitlement for the new application pool 
#    If ($App_Entitlement1) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement1 -ResourceType Application -Type User}
#    If ($App_Entitlement1) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement1 -ResourceType Application -Type Group}
#    If ($App_Entitlement2) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement2 -ResourceType Application -Type User}
#    If ($App_Entitlement2) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement2 -ResourceType Application -Type Group}
#    If ($App_Entitlement3) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement3 -ResourceType Application -Type User}
#    If ($App_Entitlement3) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement3 -ResourceType Application -Type Group}
#    If ($App_Entitlement4) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement4 -ResourceType Application -Type User}
#    If ($App_Entitlement4) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement4 -ResourceType Application -Type Group}
#    If ($App_Entitlement5) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement5 -ResourceType Application -Type User}
#    If ($App_Entitlement5) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement5 -ResourceType Application -Type Group}
#    If ($App_Entitlement6) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement6 -ResourceType Application -Type User}
#    If ($App_Entitlement6) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement6 -ResourceType Application -Type Group}
#    If ($App_Entitlement7) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement7 -ResourceType Application -Type User}
#    If ($App_Entitlement7) {$entitle = New-HVEntitlement -ResourceName $AppPoolSpec.Data.Name -User $App_Entitlement7 -ResourceType Application -Type Group}
        
#}

#$objexcel.quit() 


Disconnect-HVserver -server $POD1 -Force


# If you want to use global entitlements:

Write-Host "ADD global entitlements within POD1"
Write-Host "************************************************************"

$s = New-PSSession -computername $POD1 -Credential $DatabaseCredentials

$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $false

$WorkBook = $objExcel.Workbooks.Open('\\<location of excel>\Apps.xlsx')
$worksheet = $workbook.sheets.item("Apps")
$intRowMax =  ($worksheet.UsedRange.Rows).count

for ($intRow = 2 ; $intRow -le $intRowMax ; $intRow++) {

  Write-Host "Nummer:  "$intRow
    
  $App_ID = $worksheet.cells.item($intRow, 1).text
  $APP_DisplayName = $worksheet.cells.item($intRow, 2).text
    
  $App_Entitlement1 = $worksheet.cells.item($intRow, 10).text        
  $App_Entitlement2 = $worksheet.cells.item($intRow, 11).text        
  $App_Entitlement3 = $worksheet.cells.item($intRow, 12).text        
  $App_Entitlement4 = $worksheet.cells.item($intRow, 13).text        
  $App_Entitlement5 = $worksheet.cells.item($intRow, 14).text        
  $App_Entitlement6 = $worksheet.cells.item($intRow, 15).text        
  $App_Entitlement7 = $worksheet.cells.item($intRow, 16).text        

Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --createGlobalApplicationEntitlement --entitlementName $Using:APP_DisplayName --scope ANY --defaultProtocol BLAST --htmlAccess --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}

    # Because If ($App_Entitlement1) {... Will only be used if the line has a value
    If ($App_Entitlement1) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement1 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}} 
    If ($App_Entitlement2) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement2 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}}
    If ($App_Entitlement3) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement3 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}}
    If ($App_Entitlement4) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement4 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}}
    If ($App_Entitlement5) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement5 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}}
    If ($App_Entitlement6) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement6 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}}
    If ($App_Entitlement7) {Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addGroupEntitlement --groupName $Using:App_Entitlement7 --entitlementName $Using:APP_DisplayName --authDomain <domain> --authAs $vCenterServerAccount --authPassword $DatabaseCredentials}}

Invoke-Command -session $s -scriptblock {cmd.exe /c lmvutil.cmd --addPoolAssociation --entitlementName $Using:APP_DisplayName --poolId $Using:App_ID --authDomain <domain> --authAs $vCenterServerAccount --authPassword <password>}

}

$objexcel.quit() 

 
Remove-PSSession $s

Have fun.