{"id":4446,"date":"2016-08-11T07:00:28","date_gmt":"2016-08-11T15:00:28","guid":{"rendered":"https:\/\/www.atumvirt.com\/?p=4446"},"modified":"2016-08-11T07:00:28","modified_gmt":"2016-08-11T15:00:28","slug":"scripted-creation-of-xenapp-and-xendesktop-admin-scopes-and-roles","status":"publish","type":"post","link":"https:\/\/avtempwp.azurewebsites.net\/2016\/08\/scripted-creation-of-xenapp-and-xendesktop-admin-scopes-and-roles\/","title":{"rendered":"Scripted Creation of XenApp and XenDesktop Admin Scopes and Roles"},"content":{"rendered":"

Often times it is necessary to set up multiple identical sites. One key tenant in enabling efficient IT delivery today is having automation. As administrators, you must find the balance between the need to automate and the deadline for delivery. To that end, rather than focusing on an end-to-end automated site install (where others<\/a> have done an excellent job at that!) I wanted to focus on an often overlooked but valuable feature of XenApp and XenDesktop 7.x \u2013 Roles and Scopes.<\/p>\n

By default, XenApp and XenDesktop 7.x come with a number of pre-defined roles that are fairly functional \u2013 Read Only, Help Desk Administrator, Full Administrator, Host Administrator, and Machine Catalog Administrator. Most Citrix Admins I know generally receive Full Administrator and provide Help Desk Administrator to their users. However, there is one default in that role that can be problematic in the wrong hands: Reset profile. To that end, I like to create a slightly more \u201crestricted\u201d Help Desk role that removes this singular permission. Additionally, in Director, the Help Desk Administrator cannot see Trends, Dashboard, or Filters. For that, we will create an \u201cOperator\u201d role.<\/p>\n

First, a function to create the roles.<\/p>\n

function CreateXAXDRoles {\n\n<\n\n.SYNOPSIS\n\nCreate Roles from CSV\n\n.DESCRIPTION\n\nCreate XenDesktop roles based on a mapping from CSV Values. The CSV Header should contain RoleName,Permissions,description\n\nPermissions should be colon (:) separated\n\n.EXAMPLE\n\nCreateXDAdministrators -csvData (import-csv C:\\temp\\roles.csv)\n\n.PARAMETER csvData\n\nCSV Data from Import-CSV\n\nCSV Format\n\nCOMPANY HelpDesk Administrator,AppDNA_Read:DesktopGroup_ChangeMachineMaintenanceMode:DesktopGroup_PowerOperations_VDI:DesktopGroup_SessionManagement:Applications_Read:DesktopGroup_Read:Director_KillApplication:Director_KillProcess:Director_ShadowSession:Director_HelpDesk_Read:Director_ClientHelpDesk_Read:Director_ClientDetails_Read:Director_MachineDetails_Read:Director_UserDetails_Read:EdgeServer_Read:Zone_Read,\"Can view Delivery Groups, and manage the sessions and machines associated with those groups. (copy of Help Desk Administrator, without Reset Profile or Reset VDisk)\"\n\nCOMPANY Operator,AppDNA_Read:DesktopGroup_ChangeMachineMaintenanceMode:DesktopGroup_PowerOperations_VDI:DesktopGroup_SessionManagement:Applications_Read:DesktopGroup_Read:Director_KillApplication:Director_KillProcess:Director_ShadowSession:Director_ResetVDisk:UPM_Reset_Profiles:Director_HelpDesk_Read:Director_ClientHelpDesk_Read:Director_ClientDetails_Read:Director_Dashboard_Read:Director_SliceAndDice_Read:Director_MachineDetails_Read:Director_Trends_Read:Director_UserDetails_Read:EdgeServer_Read:Zone_Read,\"Can view Delivery Groups, and manage the sessions and machines associated with those groups. (copy of Help Desk Administrator with Trends, Filters, and Dashboard enabled)\"\n\n.LINK\n\nhttp:\/\/www.atumvirt.com\n\n>\n\n[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]\n\nparam\n\n(\n\n[Parameter(Mandatory=$True,\n\nValueFromPipeline=$True,\n\nValueFromPipelineByPropertyName=$True,\n\nHelpMessage='Supply the csvData object')]\n\n$csvData\n\n)\n\nbegin {\n\n}\n\nprocess {\n\nwrite-verbose \"Beginning process loop\"\n\nforeach ($row in $csvData)\n\n{\n\nWrite-Verbose \"Processing $($row.ADGroupName)\"\n\n$logId=[GUID]::NewGUID()\n\nGet-LogSite -AdminAddress $controllerAddress\n\nStart-LogHighLevelOperation -AdminAddress $controllerAddress -Source \"Studio\" -StartTime (get-date) -Text \"Create role `'$($row.RoleName)`'\"\n\ntry {\n\nNew-AdminRole -AdminAddress $controllerAddress -Description $($row.RoleDescription) -LoggingId $logId -Name $($row.RoleName)\n\n$permissions=$row.permissions.split(\":\")\n\nAdd-AdminPermission -AdminAddress $controllerAddress -LoggingId $logId -Permission $permissions -Role $($row.RoleName)\n\n$tryResult=$true\n\n}\n\ncatch {\n\n$tryResult=$false\n\n}\n\nStop-LogHighLevelOperation -AdminAddress $controllerAddress -EndTime (get-date) -HighLevelOperationId $logId -IsSuccessful $tryResult\n\n# Script completed successfully\n\n}\n\n}\n\n}\n<\/pre>\n

Next, a function to create the Administrators themselves.<\/p>\n

function CreateXAXDAdministrators {\n\n<\n\n.SYNOPSIS\n\nCreate Administrators from CSV\n\n.DESCRIPTION\n\nCreate XenDesktop administrators based on a mapping from CSV Values. The CSV Header should contain ADGroupName,RoleName,Scope.\n\n.EXAMPLE\n\nCreateXDAdministrators -csvData (import-csv C:\\temp\\roleScopeMatrix.csv)\n\n.PARAMETER csvData\n\nCSV Data from Import-CSV\n\nCSV Format\n\ncontoso\\CitrixLevel1,Read Only,All\n\ncontoso\\CitrixLevel2,COMPANY Help Desk Administrator,All\n\ncontoso\\CitrixLevel3,COMPANY Operator,All\n\ncontoso\\CitrixLevel4,Full Administrator,All\n\ncontoso\\CitrixSeattle1,Read Only,Seattle\n\ncontoso\\CitrixSeattle2,COMPANY Help Desk Administrator,Seattle\n\ncontoso\\CitrixSeattle3,COMPANY Operator,Seattle\n\n.LINK\n\nhttp:\/\/www.atumvirt.com\n\n>\n\n[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]\n\nparam\n\n(\n\n[Parameter(Mandatory=$True,\n\nValueFromPipeline=$True,\n\nValueFromPipelineByPropertyName=$True,\n\nHelpMessage='Supply the csvData object')]\n\n$csvData\n\n)\n\nbegin {\n\n}\n\nprocess {\n\nwrite-verbose \"Beginning process loop\"\n\nforeach ($row in $csvData)\n\n{\n\nWrite-Verbose \"Processing $($row.ADGroupName)\"\n\n$logId=[GUID]::NewGUID()\n\nGet-LogSite -AdminAddress $controllerAddress\n\nStart-LogHighLevelOperation -AdminAddress $controllerAddress -Source \"Studio\" -StartTime (get-date) -Text \"Create Administrator `'$($row.ADGroupName)`'\"\n\ntry {\n\nNew-AdminAdministrator -AdminAddress $controllerAddress -Enabled $True -LoggingId $logId -Name \"$($row.ADGroupName)\"\n\nAdd-AdminRight -AdminAddress $controllerAddress -Administrator \"$($row.ADGroupName)\" -LoggingId $logId -Role \"$($row.Role)\" -Scope $($row.Scope)\n\n$tryResult=$true\n\n}\n\ncatch {\n\n$tryResult=$false\n\n}\n\nStop-LogHighLevelOperation -AdminAddress $controllerAddress -EndTime (get-date) -HighLevelOperationId $logId -IsSuccessful $tryResult\n\n# Script completed successfully\n\n}\n\n}\n\n}\n<\/pre>\n

Finally, we create the scopes<\/p>\n

function CreateXAXDScopes {\n\n<\n\n.SYNOPSIS\n\nCreate Scopes from CSV\n\n.DESCRIPTION\n\nCreate XenApp\/XenDesktop scopes based on a mapping from CSV Values. The CSV Header should contain ScopeName,MachineCatalog,DeliveryGroup,HypConnection\n\n.EXAMPLE\n\nCreateXDAdministrators -csvData (import-csv C:\\temp\\ScopeMatrix.csv)\n\n.PARAMETER csvData\n\nCSV Data from Import-CSV\n\nCSV Format\n\nSeattleScope,MC_Seattle,DG_Seattle,Seattle_vCenter\n\nPortlandScope,MC_Portland,DG_Portland,Portland_vCenter\n\n.LINK\n\nhttp:\/\/www.atumvirt.com\n\n>\n\n[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]\n\nparam\n\n(\n\n[Parameter(Mandatory=$True,\n\nValueFromPipeline=$True,\n\nValueFromPipelineByPropertyName=$True,\n\nHelpMessage='Supply the csvData object')]\n\n$csvData\n\n)\n\nbegin {\n\n}\n\nprocess {\n\nwrite-verbose \"Beginning process loop\"\n\nforeach ($row in $csvData)\n\n{\n\n$logid=[GUID]::NewGUID()\n\nGet-LogSite -AdminAddress $controllerAddress\n\nStart-LogHighLevelOperation -AdminAddress $controllerAddress -Source \"Studio\" -StartTime (get-date) -Text \"Add Administrator Scope `'$($row.scopeName)`'\"\n\ntry{\n\nNew-AdminScope -AdminAddress $controllerAddress -LoggingId $logid -Name $($row.scopeName)\n\n#Add delivery group to Scope\n\nif(!([string]::IsNullOrWhiteSpace($($row.deliveryGroup)))){\n\nWrite-Verbose \"DeliveryGroupName is not null, empty, or whitespace\"\n\nAdd-BrokerScope -AdminAddress $controllerAddress -DesktopGroup $($row.deliveryGroup) -InputObject @($($row.scopeName)) -LoggingId $logid\n\n}\n\n$createdScope=Get-AdminScope -AdminAddress $controllerAddress -name $($row.scopeName)\n\n#Add HypConnection to scope\n\nif(!([string]::IsNullOrWhiteSpace($($row.HypConnection)))){\n\nWrite-Verbose \"ScopeName is not null, empty, or whitespace\"\n\n$hypconUID=$($(Get-BrokerHypervisorConnection $row.HypConnection).HypHypervisorConnectionUid)\n\nAdd-HypHypervisorConnectionScope -AdminAddress $controllerAddress -HypervisorConnectionUid $hypconUID -Scope $($createdScope).id\n\n}\n\n#Add machine catalog to Scope\n\nif(!([string]::IsNullOrWhiteSpace($($row.MachineCatalog)))){\n\nWrite-Verbose \"MachineCatalog is not null, empty, or whitespace\"\n\nGet-BrokerCatalog -AdminAddress $controllerAddress -Name $($row.MachineCatalog)\n\nAdd-BrokerScope -AdminAddress $controllerAddress -Catalog $($row.MachineCatalog) -InputObject @($row.MachineCatalog) -LoggingId $logid\n\n}\n\n$tryResult=$true\n\n}\n\ncatch { $tryResult=$false}\n\nStop-LogHighLevelOperation -AdminAddress $controllerAddress -EndTime (get-date) -HighLevelOperationId $logid -IsSuccessful $tryResult\n\n}\n\n}\n\n}\n<\/pre>\n

To use these functions, we require CSV data. The CSVs require all fields specified in the function comments. In order to obtain the permission names, I suggest you manually create the role with the desired permissions, then click the \u201cCitrix Studio\u201d node, find the Powershell tab, then copy the permissions from that tab. It will save a significant amount of time.<\/p>\n

Finally, we need to call these functions. Here we will populate the path to our CSV sheets.<\/p>\n

\n#Now that we've defined the functions, specify our data and actually call them\n\n$controllerAddress=\"XDController.contoso.local:80\"\n\n$roleCsv=import-csv \"C:\\temp\\roleList.csv\"\n\n$scopeList=import-csv \"C:\\temp\\scopeList.csv\"\n\n$roleScopeMatrix=import-csv \"C:\\temp\\roleScopeMatrix.csv\"\n\nCreateXAXDRoles $roleCsv\n\nCreateXAXDScopes $scopeList\n\nCreateXAXDAdministrators $roleScopeMatrix\n<\/pre>\n

Repeat this on each additional XenApp and XenDesktop site you need to, or combine with other methods. You can create delegated administration in mere moments!<\/p>\n","protected":false},"excerpt":{"rendered":"

Often times it is necessary to set up multiple identical sites. One key tenant in enabling efficient IT delivery today is having automation. As administrators, you must find the balance between the need to automate and the deadline for delivery. To that end, rather than focusing on an end-to-end automated site install (where others have […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10,75,77],"tags":[103,121,122],"_links":{"self":[{"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/posts\/4446"}],"collection":[{"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/comments?post=4446"}],"version-history":[{"count":0,"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/posts\/4446\/revisions"}],"wp:attachment":[{"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/media?parent=4446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/categories?post=4446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/avtempwp.azurewebsites.net\/wp-json\/wp\/v2\/tags?post=4446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}