vSphere permissions: export & import – Part 1
Short security principles intro
One aspect of your vSphere environment that shouldn’t be ignored is the built-in security feature that allows you to control who can do what with which vSphere entity.
Internally this is controlled from the AuthorizationManager. This object contains all the properties and methods you need to configure and manage the built-in security system.
The principle how vSphere entities are protected is quite straightforward.
At the basis are the so-called privileges. Each privilege describes a basic action that can be performed on one or more of the vSphere entities.
The vSphere environment doesn’t allow you to assign privileges directly to users or groups. You have to bundle a number of these privileges together in a role.
There are a number of pre-defined roles , such as “No Access” or “Read-Only”. But you can easily create your own roles.
With these roles you can now assign permissions on vSphere entities. You need to select an entity, a principal and a role.
All the above can be done from with the VIC.
Exporting permissions
Last year I added some functions to the VI Toolkit for Windows Community Extensions that revolved around roles and permissions. See the vSphere PowerCLI blog for a short overview of these functions.
In a recent thread on the VMTN PowerCLI community there was a request for a Script to export VC Roles/Permissions/Objects.
Last night there were some tweets from @clinek and @jasonboche that raised the question how these exported permissions could be imported into a new vSphere environment.
An intriguing problem. Let’s tackle it.
First let’s have a look how the script in Script to export VC Roles/Permissions/Objects exported the permissions to a CSV file.
This is an extract of such a CSV file.
| roleName | objName | principalName |
| VirtualMachinePowerUser | Datacenters\DIV\Linux\RH5srv01 | myDomain\user1 |
| Admin | Datacenters | Administrators |
| Admin | Datacenters | myDomain\group91 |
| VirtualMachinePowerUser | Datacenters\DIV\Linux\RH5srv04_64bit | myDomain\user21 |
| VirtualMachineUser | Datacenters\DIV\Windows\PCs\XPPC05 | myDomain\user08 |
| myDomain Network Admins | Datacenters\DIV | myDomain\group62 |
Looks like a regular CSV file, the properties in the first row and the data in the following rows.
In the last row there is a problem. The role “myDomain Network Admins” is not one of the predefined roles.
If we need to import the permission described in the last row into a new vSphere, we will first need to import the customised roles.
In the VI Toolkit for Windows Community Extensions there is a function called Get-TkeRoles that we can use to list all the roles and the privileges they hold.
Luckily the Get-TkeRoles function doesn’t use any PowerShell v2 features, except for the auto-help. That will make it easy to reuse that code in a PowerShell v1 script.
The sole reason for using PowerShell v1 is that we aren’t allowed to run a CTP version in our production environment.
Next problem.
The custom object that represents a permission and the custom object that represents a role do not have the same properties. That makes it difficult to export both objects to the same CSV.
There are a few solutions we can use here:
- We can use separate CSV files. One for the roles and one for the permissions
- We can define a new custom object that contains all the properties (both of roles and permissions)
- We can use a file format, like XML for example, that has no problem with this
- After some consideration the XML format looks the most flexible solution.
Putting all the preceding together our export script becomes:
|
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 |
function Get-Roles
{ Begin{ $authMgr = Get-View AuthorizationManager $report = @() } Process{ foreach($role in $authMgr.roleList){ $ret = New-Object PSObject $ret | Add-Member -Type noteproperty -Name “Name” -Value $role.name $ret | Add-Member -Type noteproperty -Name “Label” -Value $role.info.label $ret | Add-Member -Type noteproperty -Name “Summary” -Value $role.info.summary $ret | Add-Member -Type noteproperty -Name “RoleId” -Value $role.roleId $ret | Add-Member -Type noteproperty -Name “System” -Value $role.system $ret | Add-Member -Type noteproperty -Name “Privilege” -Value $role.privilege $report += $ret } } End{ return $report } } function Get-Permissions { Begin{ $report = @() $authMgr = Get-View AuthorizationManager $roleHash = @{} $authMgr.RoleList | %{ $roleHash[$_.RoleId] = $_.Name } } Process{ $perms = $authMgr.RetrieveAllPermissions() foreach($perm in $perms){ $ret = New-Object PSObject $entity = Get-View $perm.Entity $ret | Add-Member -Type noteproperty -Name “Entity” -Value $entity.Name $ret | Add-Member -Type noteproperty -Name “EntityType” -Value $entity.gettype().Name $ret | Add-Member -Type noteproperty -Name “Group” -Value $perm.Group $ret | Add-Member -Type noteproperty -Name “Principal” -Value $perm.Principal $ret | Add-Member -Type noteproperty -Name “Propagate” -Value $perm.Propagate $ret | Add-Member -Type noteproperty -Name “Role” -Value $roleHash[$perm.RoleId] $report += $ret } } End{ return $report } } function New-XmlNode{ param($node, $nodeName) $tmp = $global:vInventory.CreateElement($nodeName) $node.AppendChild($tmp) } function Set-XmlAttribute{ param($node, $name, $value) $node.SetAttribute($name, $value) } function Get-XmlNode{ param($path) $global:vInventory.SelectNodes($path) } $vInventory = “<Inventory><Roles/><Permissions/></Inventory>” # Roles $XMLRoles = Get-XmlNode “Inventory/Roles” Get-Roles | where {-not $_.System} | % { $XMLRole = New-XmlNode $XMLRoles “Role” Set-XmlAttribute $XMLRole “Name” $_.Name Set-XmlAttribute $XMLRole “Label” $_.Label Set-XmlAttribute $XMLRole “Summary” $_.Summary $_.Privilege | % { $XMLPrivilege = New-XmlNode $XMLRole “Privilege” Set-XmlAttribute $XMLPrivilege “Name” $_ } } # Permissions $XMLPermissions = Get-XmlNode “Inventory/Permissions” Get-Permissions | % { $XMLPerm = New-XmlNode $XMLPermissions “Permission” Set-XmlAttribute $XMLPerm “Entity” $_.Entity Set-XmlAttribute $XMLPerm “EntityType” $_.EntityType Set-XmlAttribute $XMLPerm “Group” $_.Group Set-XmlAttribute $XMLPerm “Principal” $_.Principal Set-XmlAttribute $XMLPerm “Propagate” $_.Propagate Set-XmlAttribute $XMLPerm “Role” $_.Role } $vInventory.Save(“C:\vInventory.xml”) |
The XML file that comes out of this looks like this.
The Roles branch
And the Permissions branch.
This concludes part 1 in which we have shown how to export all the required information so that we can later import these permissions in another vSphere environment.







about 8 months ago
This is a great post about some little features which I just don’t see anyone talking about, and which really shows how mature of product VMware has created. Any chance this exporter would work for 3.5, is all of this new to 4.0? Also may I ask what product you used to view the xml at the end of your post?
about 8 months ago
Thanks.
The export script will work in a VC2.5/ESX 3.5 environment. In fact I wrote the script in such an environment.
I used the Table View from WMHelp XMLPad v3.0.2, which is a great freeware product.
about 4 months ago
Hi Al,
great Script and (not only this one) a lot for great posts on your site.
When i run the export-script is get this error messages:
You cannot call a method on a null-valued expression.
At \\tsclient\N\Allgemein\VMWare\Scripting\security.ps1:61 char:33
+ $global:vInventory.SelectNodes( <<<< "Inventory/Roles")
You cannot call a method on a null-valued expression.
At \\tsclient\N\Allgemein\VMWare\Scripting\security.ps1:53 char:42
+ $tmp = $global:vInventory.CreateElement( <<<< $nodeName)
You cannot call a method on a null-valued expression.
At \\tsclient\N\Allgemein\VMWare\Scripting\security.ps1:54 char:20
+ $node.AppendChild( <<<< $tmp)
You cannot call a method on a null-valued expression.
At \\tsclient\N\Allgemein\VMWare\Scripting\security.ps1:58 char:21
+ $node.SetAttribute( <<<< $name, $value)
Do I have to do anything "around" the script ?
Thanks a lot for you help and thanks a lot for all your other posts !!!!
Chris
about 4 months ago
Once again you have written a script that will be great use to me in my environment and saved me the trouble. However, we I run the script I get only the Node headers in the XML and no errors in the PowerCli interface. Is there something that I could be missing when it comes to running the import script?
about 4 months ago
Strange that you get no error messages whatsoever.
Some thing I could think of:
- the account with which you run the script has sufficient authority in the VC
- you are connected to the VC
- there is no trap active that captures the possible error messages
You could include some Write-Host cmdlets at some points in the script to check if the values are actually retrieved.
about 4 months ago
@LucD I copied the script again and this is the error that I am getting now:
You cannot call a method on a null-valued expression.
At C:\documents\scripts\POWERCLI\XML_INV.ps1:62 char:33
+ $global:vInventory.SelectNodes <<<< ($path)
+ CategoryInfo : InvalidOperation: (SelectNodes:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
about 4 months ago
@twistedf8
There must be something wrong with the XMLpath.
But I’m afraid I can’t reproduce the problem.
Could you change the Get-XmlNode function like this and send me the output ?
function Get-XmlNode{
param($path)
Write-Host $path
$global:vInventory.GetEnumerator()
$global:vInventory.SelectNodes($path)
}
about 4 months ago
@Christian
You sure you have the following line copied into the script ?
$vInventory = “< Inventory >< Roles/ >< Permissions/ >< /Inventory >”
It looks as if that variable is not initialised.
PS: remove the blanks before and after the < and > characters.
about 4 months ago
@LucD
This is what I get now. When I run it in the vSphere PowerCLI and when I run it in the powershell v2 CTP3
Inventory/Roles
You cannot call a method on a null-valued expression.
At C:\documents\scripts\POWERCLI\XML_INV.ps1:68 char:33
+ $global:vInventory.SelectNodes <<<< ($path)
+ CategoryInfo : InvalidOperation: (SelectNodes:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
When I run it in the debugger in PowerGUI Script it runs to completion. It is the weirdest thing.
about 4 months ago
Sie können keine Methode für einen Ausdruck mit dem Wert NULL aufrufen.
Bei D:\permissions\roles.ps1:54 Zeichen:20
+ $node.AppendChild <<<< ($tmp)
+ CategoryInfo : InvalidOperation: (AppendChild:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I had the same problem. I fixed it by replacing the $global: variables by normal one.
$vInventory.SelectNodes($path) instead of $global:vInventory.SelectNodes($path)
And this with all global variables.
about 1 month ago
There are 2 things to have the script working:
- Remove the global type for vInventory variable
- Define the vInventory variable to be a XML object:
[XML] $vInventory = “”
Should be ok then
about 1 day ago
i am running the script with this command – .\EXPORT_vc_roles.ps1 –server vcservername –username username –password “*****”
and I too get numerous errors regarding calling a method on a null-valued expression.
just a sample of the numerous errors.
You cannot call a method on a null-valued expression.
At S:\SCRIPTS\FID_EXPORT_vc_roles.ps1:58 char:21
+ $node.SetAttribute <<<< ($name, $value)
+ CategoryInfo : InvalidOperation: (SetAttribute:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At S:\SCRIPTS\FID_EXPORT_vc_roles.ps1:58 char:21
+ $node.SetAttribute <<<< ($name, $value)
+ CategoryInfo : InvalidOperation: (SetAttribute:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At S:\SCRIPTS\FID_EXPORT_vc_roles.ps1:58 char:21
+ $node.SetAttribute <<<< ($name, $value)
+ CategoryInfo : InvalidOperation: (SetAttribute:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At S:\SCRIPTS\FID_EXPORT_vc_roles.ps1:58 char:21
+ $node.SetAttribute <<<< ($name, $value)
+ CategoryInfo : InvalidOperation: (SetAttribute:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Method invocation failed because [System.String] doesn't contain a method named 'Save'.
At S:\SCRIPTS\FID_EXPORT_vc_roles.ps1:88 char:17
+ $vInventory.Save <<<< ("S:\SCRIPTS\vInventory.xml")
+ CategoryInfo : InvalidOperation: (Save:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
about 16 hours ago
Thanks, Al, for another great script. And thanks Mitchum, that fix worked great.
One quick question from a newbie, is there any particular application, other than IE, that works well for viewing XML docs? Thanks!