AADUser, AADGroup, EXODistributionGroup, O365Group should have 'AdministrativeUnit' parameter
Details of the scenario you tried and the problem that is occurring
At present it is possible to add the Members of an AADAdministrativeUnit using the existing Members parameter. However:
- I would suggest that when constructing a configuration, it is much more likely that someone creating CaC would want to specify this in the section of the code where the relevant users/groups are created, rather when creating the Administrative Unit.
- This is mainly because defining the members of the Administrative Unit is less helpful than adding/removing individual users/groups to an Administrative Unit.
- Also at present adding AADAdministrativeUnit to a configuration retrieves every group member as part of the Get process, which speaking for the scenarios I am using it for, is just unnecessary.
So I would suggest allowing the following configuration is more helpful:
- Make sure an AU exists
- Create a user/group
- Make sure that user/group is inside an AU, while leaving any other users/group inside the AU alone
than
- Create 10 users/groups
- Create an AU
- Define the membersip of the AU as the above users/groups, removing any other users that also exist.
since you're more likely to use DSC to add users to existing AUs than to define new AUs and their memberships.
Verbose logs showing the problem
Suggested solution to the issue
- Remove the Members attribute from AADAdministrativeUnit (or try to make it only get members when that is requested by the config, but if you want to avoid config flapping it could just be removed)
- Add AdministrativeUnits attributes to the user/group related resources (at least AADUser, AADGroup, EXODistributionGroup, O365Group; AADDevice if that ever gets created)
For each of these:
- AADUser - trying to $expand MemberOf will return a maximum of 20 AUs so could retrieve AU memberships using Get-MgUserMemberOf | Where-Object { $_.AdditionalProperties['@odata.type'] -eq '#microsoft.graph.administrativeUnit'
- AADGroup - as AADUser but with Get-MgGroupMemberOf
- EXODistributionGroup - can retrieve a complete AdministrativeUnit ID list using the AdministrativeUnits attribute, then need to use Get-AdministrativeUnit to convert IDs to DisplayNames. Might still need to use New-MgDirectoryAdministrativeUnitMemberByRef to add new members though
- O365Group - as AADGroup or EXODistributionGroup depending on whether it's better to interface with Graph or Exchange Online
All AdministrativeUnits should be referenced by name, not ID.
The DSC configuration that is used to reproduce the issue (as detailed as possible)
N/A
The operating system the target node is running
N/A
Version of the DSC module that was used ('dev' if using current dev branch)
1.23.308.1
Tagging @salbeck-sit in case he's interested :)
@Borgquite Thanks, he is :-)
FWIW, this scenario speaks to the preview-functionality of dynamic membership of AUs just like dynamic membership of groups. Unfortunately I'm not aware of any timeline for when it goes GA. @ykuijs or others, any ideas ?
@salbeck-sit Thanks for picking this up so quickly! Can I assign you this one?
Is this functionality part of the graph beta endpoint?
Sure, in v1.0 as well, but it's only in preview. The AU-resource already supports it
PS @andikrueger, for clarity - I don't have bandwidth for adding a param to the four resources mentioned in the title of this issue, and I tend to think that a better solution would be to utilize dynamic AU membership, GA or not. That's why I'm interested in when the feature goes GA
Adding a parameter to each of the resources would add additional complexity to the all resources. I see also the chicken or egg problem if we would do so. Would we create a new AU, if it does not exist or would we throw an error in this case?
Is there a feasible solution to get the same result using the AU resource with dynamic memberships? I'm not a 100% familiar with the AU resource.
From my point of view the dynamic membership is useful, but separate. An AU is basically a 'container' for users, groups and devices, similar (but not the same as) an OU in Active Directory. We use it to define groups of objects which can be administered by e.g. a Helpdesk operative - we add the objects to an AU, then assign scoped 'User Administrator' permissions to the Helpdesk person - which means instead of the Helpdesk person having administration rights over all users in the tenant, they have User Administrator rights over just the objects assigned to the AU.
The best analogy is a 'folder' to put users, devices, groups in (since Azure AD is flat by default).
Within that analogy there are two ways to put things into the folder - assign them manually, or use attributes assigned to the things to dynamically assign them. Manual assignment is what I'm talking about here - @salbeck-sit wants dynamic assignment which would be like 'if a user has the Office attribute set to 'Seattle', put them in the 'Seattle' AU.'
In my use case, I want to put users into an 'AU' called 'Seattle', and based on that membership, I assign scoped permissions - but I also have other scripts that set their Office attribute to Seattle based on their AU - i.e. the other way around. Dynamic memberships are therefore no good to me.
In terms of your specific question, no, if the AU does exist, the command should fail. Anyone doing a configuration like this should set up the necessary AADAdministrativeUnit in the resource, and use DependsOn with the AADUser etc. This would be the same principle as is used by the RecipientAdministrativeUnitScope attribute in EXOManagementRoleAssignment, or to compare with on-premises Active Directory, the Path attribute in ADUser. The ADUser AdministrativeUnit attribute would add the single account to an existing Administrative Unit, not create or modify the attributes of that Administrative Unit itself.
There are several ways forward. I see no problem per se in adding a parameter to the resources in question in the way that @Borgquite has outlined - other than someone needs to spend time doing so. For the above example, I could point out that you would also need prior knowledge to put a user in a specific AU before updating that users' Office based on AU-membership. There are always hens and eggs lying around when managing users.
On another note, the comparison of an AU to an OU in AD is actually quite useful. In an AU you can assign scoped roles and you can also assign specific permissions to an OU to do the same (an AAD role is a set of permissions). But in AD, there's no such thing as dynamic membership. To some extent, probably because AD has become a little 'last year'.
@salbek-sit Thanks for that, and I agree with your hens and eggs analogy - the question is how that prior knowledge is first entered via attributes or AUs - 'there's more than one way to do it'.
Glad the OU/AU comparison is helpful to others, they do perform similar functions. There are just two a few differences that I know of:
- In Active Directory, every user must be within an OU/container. That's not the case within Azure Active Directory.
- In Active Directory, you can nest OUs within each other, with inherited permissions. That's not the case within Azure Active Directory.
- In Active Directory, while nesting is possible, you can't ultimately put a single object in two OUs. In Azure Active Directory, you can. It's the same as the difference between Gmail and Exchange Online - AUs are 'tags' that you can assign to objects (as many as you want) whereas OUs are hierarchical 'folders' that you can put objects in.
Is this still a present issue or did we ditch the idea?
@FabienTschanz I'd like to count myself out of the loop since the AADAdministrativeUnit resource supports dynamic membership which is what I was interested in. @Borgquite should answer for himself since his requirements aren't yet met.
@FabienTschanz I'd certainly still be interested in this feature & don't have an alternative way to do what I need to do - see previous comments for more!
So a quick update here:
- AADUser exports administrative units as part of their MemberOf property.
- AADGroup only exports security groups in their MemberOf property.
- EXODistributionGroup does not have a MemberOf property
- O365Group does not have a MemberOf property
So if we were to implement this change, for consistency's sake, it would be best to restrict the MemberOf in AADUser to only export non-dynamic groups. As soon as that is the case, we can add the AdminstrativeUnit parameter. Since O365Group is very similar to AADGroup, I suggest using Graph rather than EXO for its management.
@Borgquite Do you agree here? Since we change the behaviour of the MemberOf property, this will probably be a breaking change for October. If that's still acceptable, I can try and work on it. Shouldn't be too hard tbh.
@FabienTschanz No objections from me!