Last time I wrote a blog about the CPA script.
We had so much spare time to do other things instead of creating all the applications (in 2 POD's) manually.

But sometimes it is good to know what can be done manually and what you can add with a script within Vmware Horizon.

With a script you can import everything in Vmware Horizon. After you imported a set of application pools and entitlements, you will go back to the administrator console to see what you created, you get the following error:

You broke the application pools tab.
To fix this, you need to delete your just added applications again.
Or a selection of it... Maybe you added a letter within the version field, or you added a blank space in an application ID. Maybe a duplicate ID.
Vmware has some rules, you get an error when you try to add them manually but you won't get it when you import it via a script.

So now we will delete the applications...
Because you can't open the application pools tab, you need to open adsi edit on the Vmware horizon connection server locally. In the KB you can see how to connect to the local Adsi Edit.

https://kb.vmware.com/s/article/2012377

Here you can delete the applications.

After this, your application pools tab works again.

With Global entitlements you can also brake the list, because there is a limitation. After x global entitlements, they are not shown anymore.


https://kb.vmware.com/s/article/52548?lang=en_US

You also need to fix this with Adsi Edit. The KB shows how to connect to the global entitlements Adsi Edit.

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.

crossmenu
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram