Active Directory

Null Dynamic Membership Rules in Azure Active Directory

Azure Active Directory has the ability to create Security Groups with Dynamic membership. This is great if you can apply logic to a group, as members will fall in and out of scope without any work required.

Microsoft have a great writeup on how it all works and how to create rules, however I’ve run into a scenario not covered in the documentation.

If you create a Dynamic membership rule and want to include only attributes that have no value, the term ‘null’ works fine. You can create your group or modify the rule without issue.
However, if your binary operator (the equals part in the example above) is set to ‘not’, it won’t work.
The use case I had for ‘not null’ was to have a group of users which only had employee numbers, which was an easy way of filtering out test accounts, service accounts and so on.

You’ll get this error:

Failed to create group

Failed to create group ‘groupname’. Dynamic membership rule validation error: Invalid operands found for operator.Invalid operands found for operator -not

The way to fix this is to go into the ‘Advanced Rule’ option and change the term ‘null’ to ‘$null’

Note that you can’t do this from the simple rule view, changing ‘null’ to ‘$null’ there results in the code looking like this:

(user.extensionAttribute1 -eq “$null”)

 

Where it should look like this, without the quotes:

(user.extensionAttribute1 -eq $null)

A simple fix, but something that’s not documented on the support page. Hope this helps anyone who runs into the same problem.

Updating the Country Field in Active Directory

Wanting to have all users to have the country ‘Australia’ in Active Directory, I thought it would be a simple PowerShell command. Get all the users you want and set a field to ‘Australia’. However, it’s more complicated than that.

As you can see from the above, the Country/region field is a dropdown, where you can select the country. If you look in PowerShell using ‘get-aduser username -properties *’, there’s 4 fields that get populated with this setting:

c : AU
co : Australia
Country : AU
countrycode: 36

Trying to just change one of these fields will result in an error such as:

Set-ADUser : A positional parameter cannot be found that accepts argument ‘Au’.
Set-ADUser : A positional parameter cannot be found that accepts argument ‘Australia’.
Set-ADUser : A value for the attribute was not in the acceptable range of values

The answer is that all fields need to be set at the same time. The C and Country fields are based on ISO 3166 codes, with Australia being AU and 36.

The resulting command would end up being:

set-aduser adam.fowler -Replace @{c="AU";co="Australia";countrycode=36}

Of course this can be done on a boarder scale by using ‘get-user’ with a larger scope, and piping that into the set-aduser command:

get-aduser -filter "company -eq 'Contoso'" | foreach {set-aduser $_ -Replace @{c="AU";co="Australia";countrycode=36}}

That’s all that’s required to change the field.

Checking CSV Against Active Directory Users

I’ve written before on how to update Active Directory from a CSV. This time, I’ve got a CSV list of users that I want to check are valid users against my Active Directory (AD) environment.

There’s a huge amount of ways this can be done, and this is just one of them. If you have others, or ways to improve this I’m always keen to hear!

This script assumes you have a CSV file with the header (first line) with the word ‘users’. Here’s an example CSV file: myusers.csv

Below is the PowerShell script I wrote. I’ve also written about ‘If’ and ‘Else’ before, so read that if you want some clarification. The user list I have is based on User Principal Name (UPN) rather than just username, so I’m searching AD to see if there’s a match or not.

Import-Module ActiveDirectory

$Data = Import-Csv myusers.csv

foreach ($user in $data){
$upn = $user.user
$check = $(try {get-aduser -filter "userprincipalname -eq '$upn'"} catch {$null})
if ($check -ne $null) { }
else { "$upn Doesn't Exist" }
}

What I’m doing here is setting each line of the CSV as the $UPN variable to search for. Then using the ‘Try‘ function, I’m catching if there is no result/match (null). If there’s a match, it won’t equal null, so display nothing. Else, show the UPN via the $UPN variable and follow that with ‘Doesn’t Exit’.

This way, I will only get results back from each AD search where the UPN in the CSV doesn’t match a user’s UPN in my AD environment – and I get to see what those results are.

This script method can be applied in many different ways of course, but it was the first time I’d used the Try function, and it worked really well.

 

Azure AD Group-Based License Management For Office 365

It’s finally here! At least in public preview…

The ability to allocate Office 365 licenses via groups is now available for everyone to use. This has been a long-awaited feature, up until now licenses have either been applied manually via the portal, or via scripts/3rd party software with logic applied for automation.

Now, you can automatically apply and manage license allocation using whatever logic you like. You can create on-premise AD groups, apply a license set to the groups, and members will be allocated the relevant licensing. If that doesn’t work for you, there’s also cloud based Dynamic Groups which let you use whatever logic you can come up with to add members to the group. You could do it on something like a department name, or use an extension attribute and populate that based on what license you want to allocate.

The above link covers a lot of information about how to deploy this. At the time of writing, I couldn’t get to the Azure Licensing page by searching for the word ‘Licensing’, and instead had to use a direct link: https://portal.azure.com/#blade/Microsoft_AAD_IAM/LicensesMenuBlade/Products

I’ve already deployed it, it seems to work quickly and without issue.

 

Once you’re done, you’ll need to remove the Office 365 licenses applied manually. This TechNet article shows the commands to use for removal. I used this:

$Users = Get-MsolUser -All | where {$_.isLicensed -eq $true}; $Users | foreach {Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -RemoveLicenses "litwareinc:ENTERPRISEPACK"}

This removes licenses from all your users, to be more specific add extra criteria to the first ‘Get-MsolUser’ command. Also note you need to swap ‘litwareinc’ with your tenant ID, and ENTERPRISEPACK with whichever license you’re removing. I’d recommend testing on one account first!

To see what your tenant’s license options are just use:

Get-MsolAccountSku

And you’ll see a list of the license options along with existing allocations.

If you have any questions please comment below.

Azure Active Directory – Assigning Groups to Applications in PowerShell

Azure Active Directory Applications have been around for a while, but it’s I’ve found it hard to find good information on them beyond the biggest benefit of Marketplace Apps.

Along with my Azure AD B2B journey (still in preview at time of writing), the option of pushing out something like a SharePoint Online site as an app is one of the jigsaw pieces required to make the whole B2B process work – as a version of the apps page is displayed as the default link to anyone who accepts an Azure AD B2B invite and logs in for the first time.

MyApps – an externally invited user will only see the apps they have access to (by default, none)

I’m trying to gloss over details here, as there’s a lot of steps with different parts of the Microsoft world to get a process automated end to end for inviting external users to a SharePoint Online site – but the last step of assigning a user or group to an application has no documentation I could find, that showed how to achieve this via PowerShell.

All I want to do here, is create an Application in Azure AD, then assign a group to it. Members of the group will then see the application on MyApps.

Two different modules are required – Azure Active Directory V2 PowerShell module and Azure Resource Manager.

What we can do with these two modules is first create the application with the New-AzureRMADApplication command:

New-AzureRmADApplication -DisplayName "SharePoint Online Site A" -HomePage "https://contoso.sharepointonline.com/sitea" -IdentifierUris "https://contoso.sharepointonline.com/sitea"

Easy, now you have an application that will point to the URL entered in Azure Active Directory. Assigning a group to it is a bit trickier…

First, a few values need to be obtained:

$app = Get-AzureRmADApplication | where displayname -eq "SharePoint Online Site A"
$appid = $app.ApplicationId
$fullgroup = get-msolgroup -all | where displayname -eq "SharePoint Online Site A"

This is getting the two objects as variables – the Application itself, and the group that you want to add onto it.

Then a new Service Principal needs to be created based on the Application, as this is required when adding the group onto the application:

New-AzureADServicePrincipal -AppId $appid

Another variable is needed, which is the new Service Principal we just created:

$servicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$appId'"

Finally, we can assign the group to the application:

New-AzureADGroupAppRoleAssignment -objectid $fullgroup.objectid -principalid $fullgroup.objectid -resourceid $serviceprincipal.objectid -id ([Guid]::Empty)

You can check that this has applied by the Azure Active Directory portal too, by going to your Active Directory section, choosing ‘Applications’ and finding your app, then go into ‘users and groups’ and find the group. You should see a ‘yes’ in the assigned field.

If there’s any interest in documenting the entire SharePoint Online and Azure AD B2B invite process and script, let me know. It’s a great way of sharing data with clients via a portal.

Update 15th June 2017

Microsoft made a change with the IdentifierURI field, which is also called AppID if you view it in the Azure portal. Previously, it could be any unique URL, it just has to be unique amongst your apps (as to why it has to be a URL at all, I couldn’t get an answer on). Now, it can be anything as long as it’s not sharepoint.com or dynamics.com as they’ve reserved those for other reasons. My example above, and what I’d been using in production was variants of sharepoint.com – as the unique URI might as well be the actual URL of the site. If you use a URL that’s not allowed anymore, you’ll get the error:

New-AzureRMADApplication : Operation returned an invalid status code ‘BadRequest’