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.

image

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:

  1. We can use separate CSV files. One for the roles and one for the permissions
  2. We can define a new custom object that contains all the properties (both of roles and permissions)
  3. 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

roles

And the Permissions branch.

permissions

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.