Without any big announcements, a preview version of the Azure AD PowerShell module was released last week. In this article, we will go over the release in a bit more detail and cover some of the changes in comparison with the MSOnline module.
A brief history of PowerShell
PowerShell has been one of the main tools in the cloud administrator’s arsenal ever since the BPOS era. Back then only a handful of cmdlets existed, but the module grew steadily over the course of the next few years. It also received several name changes, first as the “Microsoft Online Services Module for Windows PowerShell” and then the “Azure Active Directory Module for Windows PowerShell.” Along the way, it also lost support for the 32-bit version, and only the 64-bit binaries are available now. The current version of the module, 1.0.9031.1, boasts a total of 87 cmdlets.
At the end of last year, a Preview version of the module was also released, which brought support for ADAL/Modern authentication. In other words, it made possible using administrative accounts protected with 2FA. The latest version in this branch, designated as Public Preview v3 (22.214.171.124), rounded up the available cmdlets to 100.
Now, yet another Preview is available, which brings some major changes, a new direction and a name change – the Azure AD (Preview) PowerShell module. Let’s go over the details.
Why a new PowerShell module?
One of the biggest issues with the ever-changing landscape of Office 365 is the inability to keep up with the release cadence. This applies not only to the Office 365 IT Pros, but to the different Microsoft teams as well. Administrative controls often appear long after a new feature is introduced, which leads to lot of criticism.
In the case of the Azure AD, being reliant on a module that requires a standalone installer and even has some dependencies (the infamous Sign-In Assistant) is at best, a major nuisance. Things are much easier in the Exchange Online world – one just creates a remote PowerShell connection, and the latest cmdlets are downloaded and ready to use. Other Office 365 workloads however are faced with difficulties when it comes to keeping the admin tools current.
PowerShell itself has changed a lot in the past few years. The latest versions allow for robust package management that supports any internal or external package repository. Downloading or updating a module now takes a single cmdlet and can easily be scripted or automated, which in turn allows the dev team to support a faster release cycle. With that in mind, it comes as no surprise that the Azure AD module is now hosted on the PowerShell Gallery (in case you need some details on how the Gallery works, read this brief guide). Just to illustrate the flexibility such a move brings, here’s a picture of the Version History:
That’s three versions in the past 10 days! Of course, as the module matures, the pace will slow down a bit, but the above picture shows just how fast can a new version be pushed out when needed.
Another reason for moving to a new module is the desire to keep Azure AD PowerShell in close alignment with the Graph API. This accounts for some of the renames of objects and parameters as compared to the old MSOnline module. All the cmdlets themselves have the “AzureAD” prefix now, to reflect the change in the module name and to conform with the Azure PowerShell naming conventions. There’s no confirmation at this point whether the team will keep the old cmdlet names as aliases to ensure backward compatibility for your scripts, so you might want to plan accordingly.
Getting and updating the module
So, how does one get the module then? If you are using Windows 10 or have the Windows Management Framework 5.0 installed, all you need to do is run the following cmdlet:
Install-Module -Name AzureADPreview
Otherwise, you will have to do some preparation first, as detailed in this Getting started guide. As an example, on a Windows Server 2012 R2 box one might have to download and install the standalone PackageManagement PowerShell Module, then load the PackageManagement and PowerShellGet modules (typically located under C:\Program Files (x86)\WindowsPowerShell\Modules\). You will also need to install the NuGet package provider and confirm that you trust the PSGallery package repository. Once all the prerequisites are met, you can install the module via the above cmdlet.
Updating the module is also a very simple task. You can check whether a newer version is available via the Find-Module cmdlet, or update directly via Update-Module. In this example, we updated from the 126.96.36.199 version to the latest one:
If you have loaded the module or used any of the cmdlets, you will have to restart PowerShell to use the new version, otherwise a simple “Remove-Module” should suffice.
A short overview of some new cmdlets
Let’s now move on to the important part – what’s new in the module and what’s changed compared to the MSOnline one. We already mentioned that all the cmdlets now use the “AzureAD” prefix, so in general you should simply replace the “Msol” prefix with it in order to get the updated cmdlet. For example, connecting to the Azure AD instance is now done via Connect-AzureAD:
As the module builds on the previous, ADAL-enabled Preview branch, specifying credentials is not mandatory. If you skip them, you will be presented with the familiar ADAL-aware dialog where you can enter your username and password and optionally perform additional authentication. You will however be prompted to confirm the connection beforehand, which is something to be wary about if you are planning to use this in automated scripts. To bypass the prompt, use the -Confirm switch, without any value (which is a bit counter-intuitive as it replaces the -Force switch and will probably be fixed in later release).
A multitude of new cmdlets has been introduced, with their number now totaling 128. One notable addition is the Disconnect-AzureAD cmdlet, which allows you to end the current session. This is a much welcome addition (and one I can take some credit for), as previously the only way to end the session was to close the PowerShell window. For people like me, constantly switching between multiple Office 365 tenants using the same PowerShell console, this will significantly reduce the chance of running that highly destructive cmdlet in the wrong tenant.
Next, we have some cmdlets that reveal the relationships within the organization. We are now able to get the Manager and any direct reports for a particular user or contact object in the Azure AD directory. For example, the Get-AzureADUserDirectReport cmdlet will return any subordinates for the user, while Get-AzureADUserManager will show the manager:
At this point it might be a good idea to discuss some of the “not so good” changes in the module. After running the first few cmdlets, one will undoubtedly notice that no proper formatting is in place and instead the full object is usually returned. Moreover, the default and only input parameter for the majority of the cmdlets is the -ObjectId. This makes things a bit unpleasant when trying to run a cmdlet against specific user, as those pesky GUIDs are probably the last thing any of us will want to memorize. The Get-AzureADUser cmdlet for example does not have the -UserPrincipalName parameter, and what’s even worse, it does not have the -SearchString parameter, either. Instead, one either has to know the Object’s GUID or use the crappy OData filter syntax (yes, I said it, it’s crappy!).
In the above example, I tried to illustrate how a replacement for the -SearchString parameter might look, by using the “startswith” filter operator. The first cmdlet looks for a user object with display name starting with “vasil”, then passes the object to the Get-AzureADUserManager cmdlet to return the manager. Some additional PowerShell magic is required to get an actual human-readable output instead of the manager’s object GUID. In the same fashion, the second cmdlet takes my manager as input and displays all the direct reports. Similar cmdlets can also be used for contact objects (Get-AzureADContactManager and Get-AzureADContactDirectReport respectively.)
Apart from getting the user’s manager, we can also set the manager via the Set-AzureADUserManager cmdlet or remove it via Remove-AzureADUserManager. Here’s an example:
Another new addition is the ability to check, add or remove (modern) Group owners. While this is also possible via the Exchange Online cmdlets, it can now also be done via the corresponding *-AzureADGroupOwner cmdlets. For example:
It’s a lot easier to list all groups to which a particular user has access now. Simply use the Get-AzureADUserMembership cmdlet:
Yet another set of improvements deals with management of apps and Certificate Authority through PowerShell. Some details can be found in the release notes or in the documentation on MSDN. Of course, we cannot cover all the cmdlets in a single article, so let’s move on to the next section.
Changed cmdlets and parameters
We covered some of the changes in the previous section, but let’s expand on them here. Apart from the generic rule of replacing “Msol” with “AzureAD” in the cmdlet name, few of the familiar cmdlets have received further changes. For example, the Get-MsolCompanyInformation cmdlet is now Get-AzureADTenantDetail, the Get-MsolAccountSku is Get-AzureADSubscribedSku and so on. Other cmdlets, such as the Set-MsolUserPrincipalName one, have been removed and the corresponding action can now be performed by invoking the Set-AzureADUser cmdlet with the -UserPrincipalName parameter (remember that the only parameter to designate the input object is -ObjectId, thus the -UserPrincipalName one has this different role now).
None of the federation related cmdlets are currently available via the Azure AD Preview module, and the same applies to the DirSync related cmdlets. On the bright side, it seems we will soon be able to manage the workload associations for domains via PowerShell.
Another important functionality currently missing is the “recycle bin.” There isn’t any way to return any soft-deleted objects currently, or to recover such objects for that matter. Rest assured, this functionality will surely return in a future update of the module.
As already mentioned in the previous section, many of the cmdlet parameters related to filtering out a subset of the objects, for example the -UnlicensedUsersOnly to list all the unlicensed users, are not currently available. While some cmdlets do support the -Filter parameter, the very small number of properties supported by the OData filter syntax makes it not as useful as one would hope. Client-side filtering is of course still possible and works pretty much the same, the only major difference being having to working with GUIDs in most of the cases. Here’s an example on how to filter out the users who have the E3 SKU assigned:
Lastly, the actual output of many cmdlets has changed. Not only the formatting, but the data returned is lacking some polish, with many attributes missing. For example, a user object returned by Get-AzureADUser will not have the alternate email address or phone displayed, the creation date, the recipient type, the password change timestamp, and so on. While many important attributes are gone, there are some new additions as well, a notable one is the ThumbnailPhoto attribute (though it’s value was null in my case).
This concludes our short overview of the new Preview module for Azure AD PowerShell. It will take a while for the module to become a viable replacement for the old MSOnline module, as it currently misses some important functionality. It will also take us, the admins, some time to adjust to some of its quirks and update our scripts accordingly. Even in this early stage however, the module adds some value, with improved support for Azure AD apps, new cmdlets to list user’s manager or direct reports, membership to groups and roles, and more. Given the faster release cycle, I’m certain most of the issues will be addressed shortly and new interesting features will become available in the near future.