Assigning Permissions – PowerCLI

Have you ever been asked to assign permissions to a VM/Folder/Resource?

Come on, own up! Of course you have.

Ever done it with the GUI? I guess the answer is the same.

So GUI is pretty easy:

  1. Find Resource (for example VM)
  2. Right-Click
  3. Add Permission
  4. Choose Role
  5. Check Propagate (if needed)
  6. Add User/Group
  7. OK
  8. OK

In total 8 different actions that need to be performed for one action.

Enter PowerCLI. In the latest release there is a new cmdlet – New-VIPermission


  Creates new permissions on the specified inventory objects for the provided users and groups in the role.

  New-VIPermission [-Entity] <InventoryItem[]> [-Principal] <VIAccount[]> [-Role] <Role>
[-Propagate [<Boolean>]] [-Server <VIServer>] [-WhatIf] [-Confirm] [<CommonParameters>]


So if you would like to add a Domain (MAISHSK) User (User1) as an Administrator on a Folder (Folder1) you would

[vSphere PowerCLI] C:\> get-folder folder1 | New-VIPermission -Role 'Admin' -Principal 'MAISHSK\User1' 

New-VIPermission : 12/21/2009 5:48:29 AM    New-VIPermission        Could not find VIAccount with name 'MAISHSK\User1'.
At line:1 char:17
+ New-VIPermission <<<<  -Role 'Admin' -Principal 'MAISHSK\User1' -Entity (Get-folder folder1)
    + CategoryInfo          : ObjectNotFound: (MAISHSK\User1:String) [New-VIPermission], VimException
    + FullyQualifiedErrorId :  Core_ObnSelector_SelectObjectByNameCore_ObjectNotFound,

New-VIPermission : Value cannot be found for the mandatory parameter Principal
At line:1 char:17
+ New-VIPermission <<<<  -Role 'Admin' -Principal 'MAISHSK\User1' -Entity (Get-folder folder1)
    + CategoryInfo             : NotSpecified: (:) [New-VIPermission], ParameterBindingException
    + FullyQualifiedErrorId : RuntimeException,VMware.VimAutomation.Commands.

But Hey that did not work! Huh???!!

This led me to a post on the VMTN forums regarding this issue by Carter Shanklin.

In short:

The source of the bug is that PowerCLI cannot correctly convert this principal into the type of object it needs, which is a VIAccount object. The workaround is to create the VIAccount object yourself.

And how do you do that you may ask? With this Function

function New-VIAccount($principal) {
	$flags = `
		[System.Reflection.BindingFlags]::NonPublic    -bor
		[System.Reflection.BindingFlags]::Public       -bor
		[System.Reflection.BindingFlags]::DeclaredOnly -bor

	$method = $defaultviserver.GetType().GetMethods($flags) |
	where { $_.Name -eq "VMware.VimAutomation.Types.VIObjectCore.get_Client" }

	$client = $method.Invoke($global:DefaultVIServer, $null)
	Write-Output (New-Object  VMware.VimAutomation.Client20.PermissionManagement.VCUserAccountImpl  -ArgumentList $principal, "", $client)


vSphere PowerCLI] C:\> $account = New-VIAccount "MAISHSK\user1"
[vSphere PowerCLI] C:\> get-folder folder1 | New-VIPermission -Role 'Admin' -Principal $account -Propagate:$true

EntityId                        Role         Principal              IsGroup Propagate
--------                           ----            ---------                  -------      ---------
Folder-group-v241    Admin       MAISHSK\user1  False     True

How many clicks was that?