Create VMware Roles for Citrix via PowerCLI

Managing multiple projects at once means automation is key. If you’re like me, you’ve probably customized VMware roles for Citrix so many times…it feels like I’ve done it a hundred times. 

Repeating the same steps across projects can get old quickly, and all those small adjustments add up fast.

That’s why I updated my original script, incorporating a few new permissions (including the latest for VMware 8) to make setting up Citrix roles in VMware more efficient. 

This script has become a huge timesaver. I’m sharing it here because I know how valuable it can be for others in the EUC community. Give it a shot and let me know 🙂

BE AWARE THAT THESE CODE SNIPPETS WILL OVERWRITE YOUR EXISTING PERMISSIONS – I TAKE NO RESPONSIBILITY.

Workflow

				
					Install-Module VMware.PowerCLI -AllowClobber
				
			

Connect to vCenter

				
					
# Prompt for the VMware vSphere server address
$vCenterServer = Read-Host -Prompt "Enter the vCenter server address"
# Connect to the VMware vSphere server
Connect-VIServer -Server $vCenterServer
				
			

Create a new or modify an existing role

				
					# Check if the role "CitrixRole" already exists - adjust if needed
$RoleName = "CitrixRole"
$Role = Get-VIRole -Name $RoleName -ErrorAction SilentlyContinue
if (-not $Role) {
    Write-Verbose "Creating new role '$RoleName' on server '$vCenterServer'."
    try {
        $Role = New-VIRole -Name $RoleName -Verbose
    } catch {
        Write-Error "Failed to create role '$RoleName'. Error: $_"
        return
    }
} else {
    Write-Verbose "Role '$RoleName' already exists."
}
				
			

Arrays for the permissions. The documentation can be found here.

				
					# Define privilege sets
$Privileges = @{
    # Basic Connection and Resource Permissions
    "AddConnectionsAndResources" = @(
        "System.Anonymous",
        "System.Read",
        "System.View"
    )
    # VM Power Management Privileges
    "PowerManagement" = @(
        "VirtualMachine.Interact.PowerOff",
        "VirtualMachine.Interact.PowerOn",
        "VirtualMachine.Interact.Reset",
        "VirtualMachine.Interact.Suspend",
        "Datastore.Browse"
    )
    # Machine Creation Services Privileges
    "MachineCreationServices" = @(
        "Datastore.AllocateSpace",
        "Datastore.Browse",
        "Datastore.FileManagement",
        "Network.Assign",
        "Resource.AssignVMToPool",
        "VirtualMachine.Config.AddExistingDisk",
        "VirtualMachine.Config.AddNewDisk",
        "VirtualMachine.Config.AddRemoveDevice"
        "VirtualMachine.Config.AdvancedConfig",
        "VirtualMachine.Config.RemoveDisk",
        "VirtualMachine.Config.CPUCount",
        "VirtualMachine.Config.Memory",
        "VirtualMachine.Config.Settings",
        "VirtualMachine.Interact.PowerOff",
        "VirtualMachine.Interact.PowerOn",
        "VirtualMachine.Interact.Reset",
        "VirtualMachine.Interact.Suspend",
        "VirtualMachine.Inventory.CreateFromExisting",
        "VirtualMachine.Inventory.Create",
        "VirtualMachine.Inventory.Delete",
        "VirtualMachine.Provisioning.Clone",
        "VirtualMachine.State.CreateSnapshot"
    )
    # Image Update and Rollback Privileges
    "ImageUpdateAndRollback" = @(
        "Datastore.AllocateSpace",
        "Datastore.Browse",
        "Datastore.FileManagement",
        "Network.Assign",
        "Resource.AssignVMToPool",
        "VirtualMachine.Config.AddExistingDisk",
        "VirtualMachine.Config.AddNewDisk",
        "VirtualMachine.Config.AdvancedConfig",
        "VirtualMachine.Config.RemoveDisk",
        "VirtualMachine.Interact.PowerOff",
        "VirtualMachine.Interact.PowerOn",
        "VirtualMachine.Interact.Reset",
        "VirtualMachine.Inventory.CreateFromExisting",
        "VirtualMachine.Inventory.Create",
        "VirtualMachine.Inventory.Delete",
        "VirtualMachine.Provisioning.Clone"
    )
    # Privileges for Deleting Provisioned Machines
    "DeleteProvisionedMachines" = @(
        "Datastore.Browse",
        "Datastore.FileManagement",
        "VirtualMachine.Config.RemoveDisk",
        "VirtualMachine.Interact.PowerOff",
        "VirtualMachine.Inventory.Delete"
    )
    # Cryptographic operations - vTPM-Related Privileges for Citrix MCS
    "CryptographicOperations" = @(
        "Cryptographer.Access",
        "Cryptographer.AddDisk",
        "Cryptographer.Clone",
        "Cryptographer.Encrypt",
        "Cryptographer.EncryptNew",
        "Cryptographer.Decrypt",
        "Cryptographer.Migrate",
        "Cryptographer.ReadKeyServersInfo"
    )
    # Provisioning Services Privileges
    # The VApp.Export is required for creating MCS machine catalogs using machine profile. This is mandatory for W11.
    "ProvisioningServices" = @(
        "VirtualMachine.Config.AddRemoveDevice",
        "VirtualMachine.Config.CPUCount",
        "VirtualMachine.Config.Memory",
        "VirtualMachine.Config.Settings",
        "VirtualMachine.Provisioning.CloneTemplate",
        "VirtualMachine.Provisioning.DeployTemplate",
        "VApp.Export"
    )
    # Storage Profile Management Privileges
    "StorageProfile" = @(
        "StorageProfile.Update",
        "StorageProfile.View"
    )
}
				
			

Display all the privilege sets and offer them to the user

				
					# Display available privilege sets
Write-Host "Available Privilege Sets:"
$index = 1
$Privileges.Keys | ForEach-Object { Write-Host "$index. $_"; $index++ }
# Prompt user to select privilege sets to combine
$selectedIndices = Read-Host -Prompt "Enter the numbers of the privilege sets you want to assign, separated by commas (e.g., 1,3,5)"
if (-not $selectedIndices) {
    Write-Error "No privilege sets selected. Exiting script."
    return
}
$selectedPrivilegeSets = $selectedIndices -split "," | ForEach-Object { $Privileges.Keys[([int]$_ - 1)] }
# Retrieve selected privilege objects based on user's selection
$AllPrivilegeID = @()
foreach ($privilegeSet in $selectedPrivilegeSets) {
    try {
        $AllPrivilegeID += Get-VIPrivilege -Id $Privileges[$privilegeSet]
    } catch {
        Write-Error "Error retrieving privileges for '$privilegeSet'. Error: $_"
        return
    }
}
				
			

Assign the permissions and display the output for verification

				
					# Assign selected privileges to the role
if ($AllPrivilegeID.Count -eq 0) {
    Write-Error "No valid privileges found to assign. Exiting script."
    return
}
try {
    Set-VIRole -Role $Role -AddPrivilege ($AllPrivilegeID) -Verbose
    Write-Verbose "Selected privileges successfully assigned to '$RoleName' role."
} catch {
    Write-Error "Failed to assign privileges to '$RoleName' role. Error: $_"
    return
}
# Display the privileges assigned for verification
try {
    Get-VIPrivilege -Role $Role | Format-Table -Property Name
} catch {
    Write-Error "Failed to retrieve privileges for role '$RoleName'. Error: $_"
}
				
			

Prompt for disconnecting from the vCenter

				
					# Prompt user to disconnect from vCenter
$disconnectResponse = Read-Host -Prompt "Do you want to disconnect from vCenter? (y/n)"
if ($disconnectResponse -match '^(y|Y)$') {
    Disconnect-VIServer -Confirm:$false
    Write-Host "Disconnected from vCenter."
} else {
    Write-Host "Remaining connected to vCenter."
}
				
			

Compare them if needed

Have fun and leave a reply.

4 Responses

Leave a Reply

Your email address will not be published. Required fields are marked *

4 Responses

Leave a Reply

Your email address will not be published. Required fields are marked *