Virtually everything is poshable
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.
| Print article | This entry was posted by LucD on June 15, 2009 at 11:00, 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 1 year 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 1 year 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 10 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 10 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 10 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 10 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 10 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 10 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 10 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 10 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 7 months 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 5 months 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 5 months 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!
about 4 months ago
Thanks a lot. Have been looking for something like this for our environment.
about 4 months ago
Can someone post the new modified script? I’m getting the same error as everyone else. It looks like Mitchum posted a fix:
**************************
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
**************************
Can someone correct that and re-post?
Thanks for the help VMware peeps!!
about 4 months ago
Is there an update version of the script that works? I too am getting the same result as everyone else..
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)
Guess I just need to learn how to script..
Thanks!
about 4 months ago
Here’s the only part I changed to get it to work, as mentioned by Mitchum:
——-
function Get-XmlNode{
param($path)
$vInventory.SelectNodes($path)
}
[XML]$vInventory = “”
# Roles
———
about 3 months ago
I’m getting the same form of errors as other users.
The script runs okay, but I get continual errors along the lines of:
“You cannot call a method on a null-valued expression.
At C:\tmp\ExportRoles.ps1:85 char:22
$node.AppendChild( <<<< $tmp)”
“You cannot call a method on a null-valued expression.
At C:\tmp\ExportRoles.ps1:85 char:23
$node.SetAttribute( <<<< $name, $value)”
“You cannot call a method on a null-valued expression.
At C:\tmp\ExportRoles.ps1:85 char:44
$tmp = $global:vInventory.CreateElement( <<<< $nodeName)”
That loops for a while then I get errors like:
“Exception calling “AppendChild” with “1″ argument(s): “Object reference not set to an instance of an object.”
At C:\tmp\ExportRoles.ps1:81 char:22
$node.AppendChild( <<<< $tmp)
When carrying out the fix as mentioned by Mitchum, i get the same erros but with a new one thrown in:
“Exception calling “CreateElement” with “1″ argument(s): “The local name for elements or attributes cannot be null or an empty string.”
At C:\tmp\ExportRoles.ps1:80 char:37
$tmp = $vInventory.CreateElement( <<<< $nodeName)
The script is creating the xml file populated with the descriptors, it’s just not populating it with any of my roles or permissions.
I’m using vCenter 4.0U1 build 208111 and the PowerCli 4.0.1-208462
Any ideas?
“Exception calling “CreateElement” with “1″