I woke up this morning to an email pointing me to this: https://www.vmware.com/security/advisories/VMSA-2021-0002.html My boss - Can LM tell us which ones need attention? We’d like to notify our customers proactively. Me - Sure! Oh wait, I only have version info for the ESX servers. I’ll have to build out something to grab the vCenter versions. So, I built a custom property source. AppliesTo: system.virtualization =~ "VMware ESX vcenter"<br/>&& (vcsa.user || esx.user)<br/>&& (vcsa.pass || esx.pass) Then the script looks like this: /*******************************************************************************<br/> * © 2023 Aqueduct Technologies Inc.<br/> *<br/> * External Resources:<br/> * - https://developer.vmware.com/apis/vsphere-automation/v7.0U1/appliance/rest/appliance/system/version/get/<br/> *<br/> ******************************************************************************/<br/><br/>import groovy.json.JsonSlurper<br/><br/>user = hostProps.get("vcsa.user")?: hostProps.get("esx.user")<br/>pass = hostProps.get("vcsa.pass")?: hostProps.get("esx.pass")<br/>host = hostProps.get("system.hostname")<br/>session_endpoint = "/rest/com/vmware/cis/session" //endpoint for establishing an ssl session<br/>vsphere_version_endpoint = "/rest/appliance/system/version" //endpoint for determining vsphere version<br/>jSlurp = new JsonSlurper()<br/>globalHeaders = [:]<br/>genSessionId()//get session ID for future API requests<br/>try{<br/> def resp = httpRequest(vsphere_version_endpoint)<br/> if (!resp) {return 1}<br/> println("auto.vcenter.version=${resp.version}")<br/>}<br/>finally{deleteSessionId()}<br/>return 0<br/><br/>def genSessionId(){<br/> String auth = "Basic " + "$user:$pass".getBytes().encodeBase64().toString()<br/> def headers = ["Authorization": (auth)]<br/> def resp = httpRequest(session_endpoint, headers, 'POST')<br/> globalHeaders.put('Cookie', "vmware-api-session-id=${resp as String}")<br/>}<br/><br/>def deleteSessionId(){<br/> httpRequest(session_endpoint, [:], 'DELETE')<br/>}<br/><br/>def httpRequest(def endpoint, Map<String, String> headers = [:], def method = 'GET', String query = null){<br/> URI _uri = new URI('https', null, host, 443, endpoint, query, null)<br/> def _session = _uri.toURL().openConnection()<br/> _session.setRequestMethod(method)<br/> (headers + globalHeaders).each { k, v -><br/> _session.setRequestProperty(k, v)<br/> }<br/> def response = _session.getInputStream().getText()<br/> _session.disconnect()<br/> return (response) ? jSlurp.parseText(response).value : null<br/>} If you don’t have one under /Devices by Type, create a dynamic group for ESX hosts and another dynamic group for vCenter. We called ours “VMware Hosts” (AppliesTo system.virtualization =~ "VMware ESX host") and “VMware vCenters” (AppliesTo system.virtualization =~ "VMware ESX vcenter") respectively. Then create a Resource Inventory report where the Resource Group is “Devices by Type/VMware*”. Add the system.virtualization, auto.vcenter.version, and system.version properties and run it. Voila, you now know the version numbers of your ESX and vCenter resources and you can compare that to the versions in the VMware Advisory.