Virtually everything is poshable
vSphere permissions: export & import – Part 2
In Part1 of this article we had all the roles and permissions exported to an XML file. It’s now time to import the roles and permissions into a Virtual Center.
The script does in fact the reverse of what the script in Part 1 did.
But there were a few “gotchas“ that had to be solved before arriving at a working solution.
Duplicate Names
The script does not take into account that you can have different objects in your vSphere environment with the same name! Which imho is not a good practice in any case.
Should someone have the need for this functionality let me know and I will try to adapt the scripts.
Principals
The script does not create the principals that are mentioned in the XML file. If these principals do not exists in the environment where you want to import the roles and permissions the script will show errors.
Speed of execution
The permissions are set with an API called SetEntityPermissions.
As can be seen in the API Reference Guide this method requires a Managed Object Reference (MoRef) to a ManagedEntity. A ManagedEntity object is the parent object of most of the managed objects in vSphere.
This way of working avoids that there would have to be a separate method for each of the derived managed objects.
In the XML we have the name of the vSphere entity in property $_.Entity. We could get at the required ManagedEntity MoRef like this:
|
001
|
(Get-Inventory -Name $_.Entity | Get-View).MoRef
|
But if you run this you will notice that this is in fact quite slow. If you need to import hundreds of permissions the script would run for hours.
After some trial and error the following turned out to be the fastest method (see line 62 in the script below).
- Use the Get-View cmdlet. It’s a lot faster. See also PowerCLPowerCLI on steroids – Custom attributes.
- The Get-View cmdlet, in this format, requires the type of object (-ViewType) to be passed. We can solve this requirement by adding the EntityType attribute to the Permission node.
- We use the -Filter parameter of the Get-View cmdlet to get only the object we want. But watch out with this filter! See the next section for more details.
Get-View filter and regular expressions
As it turns out the –Filter parameter interprets the “value” as a regular expression!
That means that if you have vSphere objects whose name accidently contains one or more [regex] meta-character, the –Filter won’t return the object.
As an example, suppose you have a VirtualMachine with a name of “MyPC (v1)”, which is by the way a valid guest name. When you do the following:
|
001
|
$pc = Get-View -ViewType VirtualMachine -Filter @{“Name”=“MyPC (v1)”}
|
The Get-View cmdlet will not return the VirtualMachine object as you would expect.
The solution is to “escape” all the regex meta-characters in the value. Something like this
|
001
|
$pc = Get-View -ViewType VirtualMachine -Filter @{“Name”=“MyPC \(v1\)”}
|
To solve the occurrence of regex meta-characters in the script the lines 58..60 were added.
Note: these aren’t all the regex meta-characters! Depending on your environment and the object names you used you will have to update these lines!
“True” is not $true
In the Permission nodes there are two attributes that represent a Boolean value. But when you access these attribute values you will notice that they are text representations (strings) of the actual Boolean values.
In the Permission object we need to pass two Boolean values.
So we have to convert the node attribute values from strings to Booleans.
This can be done like this:
|
001
|
$perm.Group = &{if($_.Group -eq “true”) {$true} else {$false}}
|
The import script
Below the actual script that will recreate all custom roles and set all permissions as defined in the XML file.
|
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 |
function New-Role
{ param($name, $privIds) Begin{} Process{ $roleId = $authMgr.AddAuthorizationRole($name,$privIds) } End{ return $roleId } } function Set-Permission { param( [VMware.Vim.ManagedEntity]$object, [VMware.Vim.Permission]$permission ) Begin{} Process{ $perms = $authMgr.SetEntityPermissions($object.MoRef,@($permission)) } End{ return } } # Create hash table with the current roles $authMgr = Get-View AuthorizationManager $roleHash = @{} $authMgr.RoleList | % { $roleHash[$_.Name] = $_.RoleId } # Read XML file $XMLfile = “C:\vInventory.xml” $vInventory = “<dummy/>” $vInventory.Load($XMLfile) # Define Xpaths for the roles and the permissions $XpathRoles = “Inventory/Roles/Role” $XpathPermissions = “Inventory/Permissions/Permission” # Create custom roles $vInventory.SelectNodes($XpathRoles) | % { if(-not $roleHash.ContainsKey($_.Name)){ $privArray = @() $_.Privilege | % { $privArray += $_.Name } $roleHash[$_.Name] = (New-Role $_.Name $privArray) } } # Set permissions $vInventory.SelectNodes($XpathPermissions) | % { $perm = New-Object VMware.Vim.Permission $perm.group = &{if ($_.Group -eq “true”) {$true} else {$false}} $perm.principal = $_.Principal $perm.propagate = &{if($_.Propagate -eq “true”) {$true} else {$false}} $perm.roleId = $roleHash[$_.Role] $EntityName = $_.Entity.Replace(“(“,“\(“).Replace(“)”,“\)”) $entity = Get-View -ViewType $_.EntityType -Filter @{“Name”=$EntityName} Set-Permission $entity $perm |
Since it was impractical (and even impossible) to test the script in all possible environments I would strongly advise to test the script thoroughly before using it in your production environment !
| Print article | This entry was posted by LucD on June 14, 2009 at 12:34, and is filed under powershell, vmware. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |







(3)
(13)
(0)
about 4 months ago
Iam getting the following error on inport. Any ideas?
[vSphere PowerCLI] C:\Program Files\VMware\Infrastructure\vSphere PowerCLI> $vIn
ventory.Load($XMLfile)
Method invocation failed because [System.String] doesn’t contain a method named
‘Load’.
At line:1 char:17
+ $vInventory.Load <<<< ($XMLfile)
+ CategoryInfo : InvalidOperation: (Load:String) [], RuntimeExcep
tion
+ FullyQualifiedErrorId : MethodNotFound
about 3 months ago
Hi Rutch, Change line 35 to this:
[XML]$vInventory = “”
Regards
Simon
about 3 months ago
Hi Alan, I’m trying to run this import script and I am getting the following error:
Exception calling “AddAuthorizationRole” with “2″ argument(s): “A specified parameter was not correct.
privIds”
At :line:8 char:39
+ $roleId = $authMgr.AddAuthorizationRole <<<< ($name,$privIds)
Any idea?
Simon
about 3 months ago
Simon, in PS v2 line 35 should be
$vInventory = [/xml]“”
Can you give that a try ?
about 3 months ago
Hi Luc, I now get this error:
Cannot convert value “[/xml]” to type “System.Xml.XmlDocument”. Error: “Data at the root level is invalid. Line 1, position 1.”
At :line:36 char:11
+ $vInventory <<<< = "[/xml]"