Role-based administration: The advanced case of no read resource rights in any collection

ProblemRBAThis week a pure ConfigMgr post and I have to admit that it’s been a long time since the last. This blog post will be about the role-based administration model and a really specific issue that I ran in to. This post will contain the scenario, the problem and a PowerShell script to get the complete solution.


CollectionsRBALets start with a short description of the scenario that I’m dealing with. The environment has a lot of different administrators, all with different collections of devices that they’re managing. As an example of the structure see the screenshot on the right that shows different collection structures that are limited to the All Systems collections. In this example every administrator would be limited to their own top-level collection and, by that, automatically inherit permissions to the collections limited to that collection.


There is no problem with a collection structure like this, in fact the role-based administration model is build for structures like this. However, the problem that we were suddenly seeing was that administrators were not able to remove or edit collection membership rules of some collections that were limited to their top-level collection. Looking at the same scenario we were seeing that an administrator that was limited to the PTCLOUD_Level 2 collection was not able to edit the collection membership rules of the PTCLOUD_Level 2.1 collection. The very cryptic error message of User \”PTCLOUD\\lvanderwoude\” has no read resource rights in any collection for this ResourceID”; would show.

After digging in to this I suddenly noticed that for some reason the PTCLOUD_Level 2.1 collection contained a direct membership rule of a device that did not exist in the PTCLOUD_Level 2 collection. That can happen when an administrator with permissions on a level higher added that direct membership rule.


The solution for this problem is easy, simply remove that direct membership rule, with an administrator with permissions on a level higher, and everything will work as designed again. However, when that collection has a lot of direct membership rules it might be hard to determine which direct membership rule is causing the problem. That’s why I created a small, but effective, PowerShell script. Let’s quickly go through the highlights of the script.

Step 1: Get the required information

The first step that I need is to get information. I need to get the resources that the administrator has permissions to, which means the resources in the top-level collection, and I need the collection membership rules of the problematic collection. Keep in mind that I need the collection membership rules and not the collection members. That’s a big difference. To get the required information I used the Get-CMDevice and the Get-CMDeviceCollection cmdlets.

$AllResourceIDs = (Get-CMDevice ` -CollectionName $TopCollection).ResourceId $ProblemCollectionRules = (Get-CMDeviceCollection ` -Name $ProblemCollection).CollectionRules

Step 2: Get the device direct membership rules

The second step that I need to do is to filter the collection membership rules of the problematic collection. In this case I’m only interested in the direct membership rules for devices. To filter that information I looked for the collection membership rules with the ResourceClassName of SMS_R_System.

foreach ($ProblemCollectionRule in $ProblemCollectionRules) { if ($ProblemCollectionRule.ResourceClassName -eq "SMS_R_System") { $DirectResourceIDs += $ProblemCollectionRule.ResourceID } }

Step 3: Compare the two lists with resources

The third step that I need to do is to compare the two lists with resources that I created. To compare the two lists I used the Compare-Object cmdlet and to eventually get a readable device name I went back to the Get-CMDevice cmdlet.

$ResultList = Compare-Object $AllResourceIDs $DirectResourceIDs if ($ResultList.SideIndicator -eq "=>") { Write-Output (Get-CMDevice -ResourceId $ResultList.InputObject).Name }

Step 4: Final notes

The fourth and last step is more about some notes for completion. To use the above lines of code, make sure to import the ConfigurationManager module and make sure to provide the following variables. Keep in mind that I’ve set the values to match my example.

$AllResourceIDs = @() $DirectResourceIDs = @() $TopCollection = "PTCLOUD_Level 2" $ProblemCollection = "PTCLOUD_Level 2.1"


Verify the role-based administration model via PowerShell

Let’s switch back to pure ConfigMgr and PowerShell this week. It will be a relatively short blog post, but in this post I’ll go through WMI and show how to get the right information about the role-based administration model. I know that this information is also available through the console, but what if I want to verify the configured role-based administration model. In that case I don’t want to go through the console, in that case I want to automate it. That way I can schedule it every now and then.


To get the information that I’m looking for I have to look at the SMS_Admin class in WMI. This class represents all the different administrative users. The first step is quite easy and straight forward, I simply get the administrative users via PowerShell by running the following command.

$Administrators = Get-WmiObject -ComputerName $SiteServer ` -Namespace root/SMS/site_$SiteCode -Class SMS_Admin

This will get all the properties from the SMS_Admin class that belong to the different administrative users. For some basic checks this will already provide enough information, but there are a couple of notes:

  1. The basic information only includes a collection name and that’s not a problem, in most cases, as it’s only possible to use a collection name once, per primary site;
  2. The basic information does not include information about which security role, for an administrative user, is attached to which security scope and/ or collection.


This brings me to the next step, which is getting more detailed information. Looking at the documentation of SMS_Admin, it shows many lazy properties in this class and one of them is named Permissions. This lazy property contains an array with information of the SMS_APermission class. This describes the permissions granted to the administrative user in more detail. To get the information of this property, and the other lazy properties, I can simply run the following command per administrative user.


Another method to get this information directly, is to use the PowerShell cmdlets. The Get-CMAdministrativeUser cmdlet provides this information by going through these classes for me. In this case I can simply run the following command to get the same information.

$Administrators = Get-CMAdministrativeUser

In both cases the Permissions property contains the information I’m looking for and in both cases this property is set up exactly the same. This property describes the permissions granted to the administrative user in detail. The information in this property can be used to link a security role to a collection or a security scope. To differentiate between them the CategoryTypeID property is used. This property will be either 1 for a collection, or 29 for a security scope. This basically provides me with all the detailed information that I was looking for. Also, in case of multiple primary sites, this provides me with the possibility to get the collection id. The collection id can be retrieved from the CategoryID property. This property contains the collection id when CategoryTypeID is 1 and contains the security scope id when CategoryTypeID is 29.


Now lets end this blog post with a small example of how these classes can be used. First of all in this example I’ll use WMI to take away the dependency of the PowerShell module. Second, this example requires two input parameters, one for the site server and one for the site code. This example will get all the administrative users and their lazy properties. Then it will go through the Permissions property and only list the permissions related to a collection, by using a check to see if CategoryTypeID is 1. At the end it will write the administrative user, the collection id (CategoryID) and the role.

$Administrators = Get-WmiObject -ComputerName $SiteServer ` -Namespace root/SMS/site_$SiteCode -Class SMS_Admin foreach ($Administrator in $Administrators) { $Administrator.Get() $Permissions = $Administrator.Permissions foreach ($Permission in $Permissions) { if ($Permission.CategoryTypeID -eq "1") { Write-Host $Administrator.LogonName ` $Permission.CategoryID $Permission.RoleName } } }

Further reading

A couple articles, related to this subject, can be very helpful. Trevor Sullivan did a post about PowerShell: ConfigMgr WMI Provider (feat. Lazy Properties) a few years a go, which is still very useful. Another, good to know article, is this how-to from the ConfigMgr 2012 SDK about reading lazy properties by using WMI.


Unexpected results: Use role based administration to provide different access to specific applications in ConfigMgr 2012

This time I want to address a specific scenario around role based administration. This scenario will be focused on providing different levels of access, for a user, on different applications. I’ve seen this question on different forums over the last year(s) and also had this same question with a customer recently.


This scenario is about a enterprise customer that uses ConfigMgr for managing their laptops. Nothing special, so far, not even the fact that they have around 100k laptops spread over the globe. What makes this customer special is the fact that they have a global IT department and a local IT department per country. The global IT department is responsible for making the generic applications available and the local IT department is responsible for making country specific applications available. Because of this, their requirement, for the local IT department(s), is to have read access to all global applications and full access to their own applications.


Actually the solution to this was a lot simpler then I initially thought. The only thing I could think about was that a user, or group, can only be configured once as a ConfigMgr user. Of course it’s very simple to work around this, by using security group(s), like every one should be in the first place. To solve this scenario, for one local IT department, we need the following:

  • Two AD security groups.
    • Both security groups contain the local IT department administrators;
  • Two Security Scopes;
    • One security scope will contain the global IT department applications;
    • One security scope will contain the local IT department applications;
  • Two Security Roles;
    • One security role will contain full access to applications (in this case the built-in role Application Administrator is sufficient).
    • One security role will contain read-only access to applications (in this case the built-in role Read-only Analyst is sufficient).

Now put this all together in Administration workspace, via Add User or Group on the Home tab in the Administrative Users node. Via the dialog box combine the AD security groups with the Security Roles and Security Scopes. For this last one make sure to select Only the instances of objects that are assigned to the specified security scopes or collections and select only the specific Security Scope. This should result in something like this:Overview


After these configurations it’s time to look at the results of the configurations. I do have to say that I was quite surprised by a part of the result and also can’t explain it, yet. To provide a good overview of the results, I putted three default right-click menu’s, for applications, next to each other. On the left is the right-click menu of a user with only Application Administrator rights on applications. In the middle is the right-click menu of a user with only Read-only Analyst rights on applications. Last, but not least, on the right is the right-click menu of a user with Read-only Analyst rights on the specific application and Application Administrator rights on other applications. Besides the normal read-only access, the user suddenly also has the rights to move, deploy and distribute the application. I can’t explain this behavior, yet.

Application administrator Read-only analyst Read-only analyst (with Application administrator on other applications)
FullAdmin ReadOnly01 ReadOnly02