Parsing complex HTML is definitely challenging, even with PowerShell. I had hoped to use the free tier of ChatGPT and their latest 4o model to help build a PowerShell function for HTML parsing, but I kept running into system limits and the AI often misunderstood what I was asking for.
I finally gave in and purchased the $20 subscription so that I could expand on my 2017 blog post about automating vSphere Global Permissions and add support for listing global permissions, which came at a request from a recent user.
It turns out calling the private vSphere Global Permissions API via the vSphere MOB to show all current vSphere Global Permissions is extremely difficult due to the complex HTML that is rendered by the vSphere MOB. In fact, it took 25 iterations before I finally arrived at the solution using ChatGPT's 4o model. In several of the iterations, it ended up going backwards in progress, so that was pretty annoying!
Not sure if this is the new fancy "vibe coding" trend that I had experienced ... 😅
Download the latest GlobalPermissions.ps1 file which contains a new function called Get-GlobalPermission which will retrieve all vSphere Global Permissions including the principal name and their assigned vSphere Role.
Below is an example of using the new function, which will require you to run the Connect-VIServer, as that is required to correlate between the vSphere Role ID provided by the function and the actual vSphere Role Name provided by the native PowerCLI cmdlet.
$vc_server = "vc03.williamlam.local" $vc_username = "*protected email*" $vc_password = "VMware1!" $server = Connect-VIServer -Server $vc_server -User $vc_username -Password $vc_password Get-GlobalPermission -vc_server $vc_server -vc_username $vc_username -vc_password $vc_password Disconnect-viserver $server -confirm:$false
Here is a screenshot of the output, which you can further process as the function returns an array of PowerShell objects.
I know many users have been asking for an easier way to automate vSphere Global Permissions, I can only say that we have heard you loud and clear and this will be addressed in the near future 🙂
William,
Thanks for looking into this so quickly. I hope this is something you were planning to look at anyway.
It seems to be working very well for what I want to do, with two very minor issues.
One, on line 29 where you have VSPHERE\.LOCAL hardcoded that is causing the loop not to match any of the groups that are based on our AD users instead of our local users. I can replace the VSPHERE\.LOCAL with our AD domain and it will instead pick up the AD groups and not the local groups, I'll try to work out a regex that will pickup both.
Two, In the rare case where a permission is defined for the same Principal on an object and globally, the script reports two lines with both Roles, but there is no way to see which is truly Global. This is part of what I am trying to audit, we have too many duplicate permissions with different roles for the same users.
Actually though, just being able to identify which principal has a duplicate role defined is a big win, so it may already be good enough.
```
$nameMatch = [regex]::Match($nested, 'name.*?([A-Z.]+\\[^<]+)', 'Singleline')
This seems to fix the first issue for me. I'm not great with github or maybe I could figure out how to pull request. Maybe given enough time I could still figure it out.