Earlier this week I added several methods to the VMware Horizon Python Module that are centered about application pools and I promised a blog post so here it is 🙂 In the module we have the following methods in the Inventory about Application Pools:
Preparation
In order to use the methods I am using this as standard configuration in my script
import requests, getpass, urllib, json, operator
import vmware_horizon
requests.packages.urllib3.disable_warnings()
url="https://loftcbr01.loft.lab"
username = "m_wouter"
domain = "loft.lab"
pw = getpass.getpass()
hvconnectionobj = vmware_horizon.Connection(username = username,domain = domain,password = pw,url = url)
hvconnectionobj.hv_connect()
print("connected")
monitor = obj=vmware_horizon.Monitor(url=hvconnectionobj.url, access_token=hvconnectionobj.access_token)
external=vmware_horizon.External(url=hvconnectionobj.url, access_token=hvconnectionobj.access_token)
inventory=vmware_horizon.Inventory(url=hvconnectionobj.url, access_token=hvconnectionobj.access_token)
entitlements=vmware_horizon.Entitlements(url=hvconnectionobj.url, access_token=hvconnectionobj.access_token)
All of the connects at the bottom is so I don’t need to think to do those if I need them when testing.
I end with
end=hvconnectionobj.hv_disconnect()
print(end)
Both the connected and end prints aren’t required at all but give me feedback about the status of the connection.
[sta_anchor id=”get_application_pools” /]
get_application_pools
This is the easiest method to use as it doesn’t require anything. It does allow for setting page sizes and filtering if needed. See this article if you want to know more about filtering: https://retouw.eu/2021/02/14/filtering-searching-and-pagination-with-the-python-module-for-vmware-horizon/ The method will return a list of dicts, for the first example I will show only the names of the items.
ap = inventory.get_application_pools(maxpagesize=100)
for i in ap:
print(i["name"])
Or just with the entire list returned
ap = inventory.get_application_pools(maxpagesize=100)
print(ap)
[sta_anchor id=”get_application_pool” /]
get_application_pool
To get a single application pool you can use get_application_pool and it requires an application_pool_id, I will use the first one of the list of application to show it.
ap = inventory.get_application_pools(maxpagesize=100)
firstap=ap[0]
print(inventory.get_application_pool(application_pool_id=firstap["id"]))
[sta_anchor id=”delete_application_pool” /]
delete_application_pool
To delete an application pool we again only need the application_pool_id I will combine both the get methods to show all application pools before and after the deletion. (with some prints not relevant for the code so I won’t show them below)
ap = inventory.get_application_pools(maxpagesize=100)
for i in ap:
print(i["name"])
firstap=ap[0]
print(inventory.get_application_pool(application_pool_id=firstap["id"]))
inventory.delete_application_pool(application_pool_id=firstap["id"])
ap = inventory.get_application_pools(maxpagesize=100)
for i in ap:
print(i["name"])
[sta_anchor id=”new_application_pool” /]
new_application_pool
Since I just deleted my firefox pool I will need to recreate it. The new_application_pool method requires a dict with quite a lof of values. This is the standard list that the swagger-ui gives you
{
"anti_affinity_data": {
"anti_affinity_count": 10,
"anti_affinity_patterns": [
"*pad.exe",
"*notepad.???"
]
},
"category_folder_name": "dir1\\dir2\\dir3\\dir4",
"cs_restriction_tags": [
"Internal",
"External"
],
"description": "string",
"desktop_pool_id": "0103796c-102b-4ed3-953f-3dfe3d23e0fe",
"display_name": "Firefox",
"enable_client_restrictions": false,
"enable_pre_launch": false,
"enabled": true,
"executable_path": "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Firefox.lnk",
"farm_id": "855ea6c5-720a-41e1-96f4-958c90e6e424",
"max_multi_sessions": 5,
"multi_session_mode": "DISABLED",
"name": "Firefox",
"parameters": "-p myprofile",
"publisher": "Mozilla Corporation",
"shortcut_locations": [
"START_MENU"
],
"start_folder": "string",
"supported_file_types_data": {
"enable_auto_update_file_types": true,
"enable_auto_update_other_file_types": true,
"file_types": [
{
"description": "Firefox Document",
"type": ".html"
}
],
"other_file_types": [
{
"description": "Firefox URL",
"name": "https",
"type": "URL"
}
]
},
"version": "72.0.2"
}
This does not say that all of these are required, what I have found to be an easy way to find what the minimums are is to create an application pool with a single key value pair. display_name is always required so I will use that one. Experience has learned that this might require several tries so let’s go.
new_app_pool = {}
new_app_pool["display_name"] = "Firefox"
inventory.new_application_pool(application_pool_data=new_app_pool)
So the first hard requirements are display_name, executable_path and name, let’s add these and see what happens
new_app_pool = {}
new_app_pool["display_name"] = "Firefox"
new_app_pool["name"] = "Firefox"
new_app_pool["executable_path"] = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Firefox.lnk"
inventory.new_application_pool(application_pool_data=new_app_pool)
It looks like we actually need some more: at least desktop_pool_id or farm_id since I am doing this against a connection server with no farms I’ll use a desktop pool.
desktop_pools = inventory.get_desktop_pools()
firstpool = desktop_pools[0]
new_app_pool = {}
new_app_pool["display_name"] = "Firefox"
new_app_pool["name"] = "Firefox"
new_app_pool["executable_path"] = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Firefox.lnk"
new_app_pool["desktop_pool_id"] = firstpool["id"]
inventory.new_application_pool(application_pool_data=new_app_pool)
No errors and a peak in the admin console shows me that I again have a firefox application
[sta_anchor id=”update_application_pool” /]
update_application_pool
To update the pools we need the application_pool_id and again a dict, this time the dict needs things we want to update. Experience again learned me there are a few required key value pairs while the example in the swagger-ui shows lots, so let’s find those. I am going to use my new firefox app as the source for this. What I actually am going to try to change is the display_name so I will use that as the first key value pair.
filter = {}
filter["type"] = "And"
filter["filters"] = []
filter1={}
filter1["type"] = "Equals"
filter1["name"] = "name"
filter1["value"] = "Firefox"
filter["filters"].append(filter1)
ap = (inventory.get_application_pools(filter=filter))[0]
appid = ap["id"]
update_app = {}
update_app["display_name"] = "FF2"
inventory.update_application_pool(application_pool_id=appid, application_pool_data=update_app)
So here different key value pairs are required than when creating a new application pool, strange but there is nothing I can do about it! I will add these from the ap object I retrieve earlier in the script.
aps = inventory.get_application_pools(maxpagesize=100)
for i in aps:
print(i["display_name"])
filter = {}
filter["type"] = "And"
filter["filters"] = []
filter1={}
filter1["type"] = "Equals"
filter1["name"] = "name"
filter1["value"] = "Firefox"
filter["filters"].append(filter1)
ap = (inventory.get_application_pools(filter=filter))[0]
appid = ap["id"]
update_app = {}
update_app["display_name"] = "FF2"
update_app["executable_path"] = ap["executable_path"]
update_app["multi_session_mode"] = ap["multi_session_mode"]
update_app["enable_pre_launch"] = ap["enable_pre_launch"]
inventory.update_application_pool(application_pool_id=appid, application_pool_data=update_app)
aps = inventory.get_application_pools(maxpagesize=100)
for i in aps:
print(i["display_name"])
So with that you have the basics to retrieve, create, update and delete application pools using python