Using Azure AD Managed Service Identity to Access Microsoft Graph with Azure Functions and PowerShell

Recently Microsoft released an exciting new preview in Azure AD: Managed Service Identity! You can go and read the details at the Enterprise Mobility + Security blog, and some examples of usage scenarios:

Managed Service Identity makes it possible to keep credentials out of code, and that is a very inviting prospect. As I have been exploring Microsoft Graph in different scenarios using PowerShell, I thought I should have a go at using Managed Service Identity in an Azure Function and run some PowerShell commands to get data from the Microsoft Graph. Lets get started!

Configuring the Azure Function

First, if you haven’t already created an existing Azure Function App, go ahead and do that. Here is my Function App I will use in this demo:


Next, open the Function App and go to Platform features, and then click on Managed service identity:


Under Managed service identity, select to Register with Azure Active Directory:


After saving you should get a successful notification that the managed service identity has been registered.


Let’s check what has happened in Azure AD, to that I will use the AzureAD PowerShell CmdLets. After connecting to my Azure AD tenant, I will try to get the Service Principal:


And get some properties of that object:


We can see that the Service Principal object is connected to the Azure Function App and of type ServiceAccount.


Now, we are ready for the next step, which is to create a function that will get data from Microsoft Graph. But first we will need to give this Service Principal some permissions.

Permissions and Roles for the Managed Service Identity

Depending of what you want to do with your Function App, the managed service identity, represented by the service principal, will need some permissions to access resources. You could give the service principal rights to Azure resources like Virtual Machines, or to access Key Vault secrets (a nice blog post on that here:

In my scenario I want to access the Microsoft Graph, and specifically get some Directory data like user information from my Azure AD. When accessing Microsoft Graph you would normally register an Azure AD Application and set up Application or Delegated Permissions, and follow the authentication flow for that. But in this case I want the Service Principal to be able to directly access Directory Data, so I will have to give my Service Principal permission to do that.

The following Azure AD commands adds my service principal to the AD Directory Role “Directory Readers”:

image When listing membership in that role I can see my Service Principal has been added:


Creating a PowerShell Function for the Managed Service Identity

In your Function App, you can now create a new Function, selecting language PowerShell, and in this case I will create it as a HttpTrigger Function:


If you have been following the flow of the blog post until now, we can now check if the Function App is ready for using the Managed Service Identity (MSI). Two environment variables will be created, and you can check if they exist by going to Platform features, and then selecting Advanced tools (Kudo). Under environment you would se something like this if everything is ready (it could take a little time, so re-check until its there):


These two environment variables will be needed in the Azure Function, so we will start by getting that:


If I run the Function I can see from the output that I was able to retrieve the environment variables:


Next I will specify some URI and parameters for my authentication request using the managed service identity. I will need to specify the version (currently 2017-09-01 as specified in the documentation), and since I want to get data from the Microsoft Graph, I will need to specify that as the resource URI. I then build the URI for getting the authentication token:


With that, I can now do an authentication request, which if successful will return an access token I can use as a Bearer token in later queries agains the Microsoft Graph:


Let’s do another test run and verify that I can get an Access Token:


Querying the Microsoft Graph

With a valid Access Token, and with the correct permissions for the resources I will want to access, I can now run some Microsoft Graph API queries.

In my example I have some test users in my tenant named after the popular Seinfeld show. In fact I have set a “Seinfeld” department attribute value on those. So my query for getting those users would be:$filter=Department eq ‘Seinfeld’

A great way to test Microsoft Graph Commands is to use the Graph Explorer,, and if you sign in to your own tenant you can query your own data. As an example, I have showed that here:


In my Azure Function I can define the same query like this (PS! note the escape character before the $filter for it to work):


And with that I can request the user list using Microsoft Graph and a Authorization Header consisting of the Access Token as a Bearer:


Let’s output some data from that response:


And there it is! I’m able to successfully query the Microsoft Graph using Managed Service Identity in an Azure Function, without handling any credentials.

For reference, I have attached both the Azure AD PowerShell  commands, and the Function PowerShell commands below from my Gist. Enjoy!

Azure AD PowerShell SPN commands:

Azure Function PowerShell Trigger:

Looking in to the Changes to Token Lifetime Defaults in Azure AD

In a recent announcement at the Enterprise Mobility Blog,, there will be a change for default settings to the Token Lifetime Defaults in Azure Active Directory for New Tenants only. This change will not affect existing old Tenants.

I have summarized the changes in this table:


This is great news for many customers to remove user frustration over authentication prompts when refresh tokens expired after a period of inactivity. For example, if I havent used an App on my mobile phone for 14 days, I have to reauthenticate with my work/school account again to get a new Access Token and Refresh Token. Some Apps I use quite often, like Outlook and OneDrive, and by keeping active the Refresh Token will be continously renewed as well together with the Access Token (which by default is valid for 1 hour). For my existing tenant this would mean that keeping active, and at least using the Refresh Token inside the 14 Days, I will get new Access and Refresh Tokens, but after 90 Days the Single and/or Multi factor Refresh Token Max Age will be reached, and I have to reauthenticate again in my Apps.

Some Apps I will naturally use more rarely, for example Power BI, Flow, PowerApps etc. (this will be different for each user type), but I risk having to reauthenticate every time if I only access these Apps every other week.

So for New Tenants this has now changed, as Refresh Tokens will be valid for 90 Days, and if you use the Refresh Token inside that period, you will get 90 more days. And furthermore, the Max Age for Single/Multi factor Refresh Token will have a new default of Until-revoked, so basically it will never expire.

Keep in mind though, that Azure AD Administrators can revoke any Refresh Token at any time. Refresh Tokens will also be invalid if the authenticated users password changes or expire. It is also nice to be aware of that every time a Refresh Token is used to get a new Access Token, Conditional Access and Identity Protection from Azure AD will be used to check if the User or Device is in a Compliant State with any policies defined.

A few words on the Confidential Clients also. Confidential Clients are typically Web Apps that are able to securely store Tokens and identity itself to Azure AD, so after the User has Authenticated and actively Consented to access specific Resources, the resulting Access and Refresh Tokens can be used until revoked, as long as the Refresh Token are used at least once inside 90 Days (New Tenants) or 14 Days (Old Tenants).

If you want to read more deep dive on configurable Token Lifetimes, you can follow this link:

Azure AD PowerShell examples for changing Token Lifetime Defaults

I have created some Azure AD PowerShell V2 examples for how you can change the Token Lifetime Policy defaults in your organization.

First connect to your Tenant and see if there already are defined any policies (normally there would be nothing):


Then lets make a definition that reflects the new defaults for New Tenants:


So if you already have an existing old tenant, and you want to change the default policy so that it reflects the new Token Lifetime settings, you can run this command:


A different scenario, lets say I have a New Tenant, and want to use the old default values instead. I will make a definition that reflects that:


And create a policy using these definitions:


Last, I will leave you with commands for changing any existing Azure AD policies:


The complete list of Azure AD PowerShell CmdLets used and examples can be found here at my Gist repository.

Hopefully this has been informative and helpful for Azure AD Administrators and others Smile!

Experts and Community unite again at Experts Live Europe in Berlin

Last week I was back at this great Community conference, previously known as System Center Universe Europe (SCU Europe), and this year for the first time under the name Experts Live Europe, part of the Experts Live network ( This conference is well known for its great content, top speakers, sponsors and great community, where you meet friends old and new, and generally have a great time the 3 days the conference lasts.

This year the conference was held in the BCC by Alexanderplatz in Berlin, the same venue as last year. With almost 400 people from 28(!) different countries, I was very proud again to be among the great set of Experts and MVPs presenting sessions on topics from Cloud, Datacenter, Management, PowerShell, IoT, Azure, EMS, and more.


I presented two breakout sessions, the first one was about how to “Take your Azure AD and Intune Management Skills to the Next Level with Microsoft Graph API and PowerShell”, a practical and demo-heavy session.  The PowerShell script I used in the demos can be found in my GitHub repository:


The second session I presented was on “Mastering Azure Active Directory v2”, where I discussed features in the new Azure AD Portal for Azure AD Administrators that have previously used the classic portal or Office 365 admin portal for managing users, licenses, and admin roles and more. We also looked at the Azure AD v2 PowerShell, that will replace the v1 (MSOL) cmdlets. Look to my Gist repository for several examples on using Azure AD v2 cmdlets,


I also had the pleasure to be in a discussion panel with Microsoft Intune Principal Program Manager Simon May, CDM MVP Tudor Damian and my fellow Norwegian EMS MVP Jan Ketil Skanke, where we had good questions and discussions from the attendance on the topic Identity, Security and Compliance.


The days went by really fast, and soon it was time for the closing note and the traditional trivia with funny stories and facts from the past conferences. One of the questions was how many have attended all 5 conferences (speakers, sponsors and attendees), the correct answer was not known, but the audience who had done this was invited onto the stage, and 10 people (in addition to Marcel) had their loyalty appriciated with claps and cheers from the room. And, I’m one of those that has been to all conferences 🙂


So with that ended the 5th annual conference that used to be SCU Europe and is now Experts Live. I have made some great friends there, and the conference has a family feeling going back there every year. There has been some early mornings, and some late nights, as it should be.


Thanks for me, Berlin and Experts Live, next year it will another place, it will be exiting to see where it will be. I know I will be back, hope you will to!


Speaking at Experts Live Europe 2017, Berlin!

Once again I’m very proud and excited to announce that I will be speaking at Experts Live Europe 2017, in Berlin August 23rd to 25th.

Experts Live Europe, previously known as System Center Universe Europe, is celebrating 5 years anniversary this year, after beeing arranged in Bern, Basel x 2, and last year moved to Berlin, where it was announced that the conference in the future would be part of the Experts Live Network!

SCUE16 – System Center Universe Europe becomes Experts Live Europe from itnetX AG on Vimeo.

I have been lucky to attend every single one of the previous conferences, and last year I presented a couple of sessions there as well. I have got to know some great community leaders and IT pros from all over the world at this conference, it really is one of the best community conferences around, as well as top experts and contents in sessions!

This year I will present 2 sessions:

I will also be running a Discussion Panel on “Identity, Security & Compliance” , together with Simon May, Principal Program Manager – Intune, Microsoft, EMS MVP Jan Ketil Skanke, and CDM MVP Tudor Damian.

And, in addition to the already mentioned great experts, content and community, there’s also great parties there!


Read my recap of last years conference at the same venue here:

If you haven’t already registered, and are still wondering wether to go, read more about the conference and register here:

Hope to see you there!

Get Started with Group Based Licensing in the Azure AD Portal!

Just the other day I wrote a blog post on how you could use Azure AD v2 PowerShell and Dynamic Groups based on extension attributes to set EMS license plans for your cloud and on-premises users,

And now, User and Group based licensing in the Azure AD Portal has been added in Preview! This is a long awaited feature, and works will all of your purchased services, either its EMS, Office 365, Dynamics 365, PowerBI and many more.

Let’s take a quick look on the functionality. Based on the above referenced blog post, I will use the same Dynamic Groups, where membership is defined based on values for extension attributes. So I already have configured Dynamic Groups for EMS E3, EMS E5and Office 365:


The new Licensing functionality are now added to the Azure AD Preview at


When I go to the Licenses blade I get a quick overview over my purchased products and total of assigned licenses:


When I go to All products, a list of my product subscriptions are shown, with an overview of licenses assigned, available and if any are expiring soon:


If I go into one of the products, I will see the already existing licensed users, which in my case are Direct assigned (I did that with the PowerShell script in the previous blog post).


Let’s configure Licensed Groups:


Click + Assign to add a group to License, I will use my Dynamic Group:


Then, at Assignment options, I can optionally configure individual services:


After clicking OK and Assign, the group has been added for processing:


And if I look at Licensed Users again after the change has been processed, I will see that uses now have an inherited license based on the group. Of course, the Direct assignments added by PowerShell are not removed, so I will have to remove those later.


In the same way I can add my Office 365 and EMS E5 Dynamic Groups:


By the way, you can go into each group after and look at License status, and Reprocess if needed.


At the Group’s Audit Log we can track the license activity as well:


So there we have it, a long sought after functionality that I’m sure many organizations will have good use for. As this is in Preview, some more testing are should be done before setting it directly into production, and if I find anything special I will update this blog post.

I am sure there will be an announcement and blog post at the Enterprise Mobility + Security blog shortly also:

Publish the Cireson Configuration Manager Portal with Azure AD Application Proxy

Cireson will soon be releasing a new web based Portal for System Center Configuration Manager, This would make it possible to access a lot of functionality for Configuration Manager anywhere with a web browser. The Cireson Portal for Configuration Manager must be installed locally, either on the Configuration Manager server or on a server close to the Configuration Manager server and database.

This makes this an ideal candidate for Azure AD Application Proxy publishing, as we can make it available as an Azure AD App with all the features and possibilities that this can give, including:

  • Azure AD Preauthentication and Single Sign-On to the Portal
  • Assigning Users and Groups
  • Conditional Access
  • Easy access via the users Access Paneler or the Office 365 App Launcher

We will look into all this in a two-part blog post! This will also be a good opportunity to use the new management experience for the preview of Azure Active Directory management in the Azure Portal,

Part 1: Publish the Cireson Configuration Manager Portal with Azure AD Application Proxy
Part 2: Conditional Access and Self Service for the published Configuration Manager Portal Application (link when available)

Enable Azure AD Application Proxy

I you want to publish applications with Azure AD Application Proxy, there are some requirements:

  • You need an Azure AD tenant configured with licenses for Azure AD Premium P1 or EMS E3 Suite. Actually it is enough with Azure AD Basic licenses for AAD App Proxy, but if you want to configure Conditional Access you will need at least Premium P1. More on that later.
  • If you want to enable SSO for your internal users you have to synchronize those users via Azure AD Connect.
  • You have to Enable Azure AD Application Proxy for your AAD tenant directory, and download and install one or more Application Proxy Connectors.

The diagram below shows the communication flow from when the user launch the published application, authenticates to Azure AD, and then via the Application Proxy Connector installed internally access the web based portal. Single Sign-On is achieved via the Application Proxy Connector authentication on behalf of the user via Kerberos Constrained Delegation.


So the first step is to go to the Azure Portal, and open the Azure Active Directory blade, which at the moment is in preview. From there go to the Application Proxy section and make sure that the Application Proxy is enabled as shown below:


In the image above we also see that there already are some Azure AD App Proxy Connectors installed and active. They are also configured in two different groups, and these groups are used later when we publish the application. At the top of the blade, you can download a new Connector installation file.

Download and install Application Proxy Connector

The Application Proxy Connector must be installed on a server that can reach the internal web portal server. In this case I want to install the Connector locally on the Configuration Manager server that also hosts the Cireson Portal for Configuration Manager. I could have used one of my existing connectors, but they are installed respectively on an Azure VM environment and on a separate network from our Configuration Manager environment.

Following the download link from above, I download and start the Application Proxy Connector installation on my SCCM server.


During installation you must provide a global administrator admin account:


After finishing the installation of the connector, we will se the new connector with the server name in the portal.

We can now create a group, and place the connector installed in the group:


Publish the Configuration Manager Portal App

To start publishing the Configuration Manager Portal Application, go to Enterprise Applications and select Add, and from the Add your own app section select to add an “On-premises application”:


Next, specify the Name of the Application and the Internal Url. In this case I have installed it internally as http://configmgrportal. For External Url, you have a choice for the alias and domain. By default the alias will be the Application Name without spaces, appended with –<tenant name>


You can change the domain to one of your verified domains, which I have done here together with changing the alias so that the External Url now will be By the way, you have to upload a SSL certificate if you want to use your own domain, either a wildcard certificate or a certificate with the appropriate FQDN. We will look at that later.


Note that I need to add a CNAME entry at my DNS provider as stated in the info box above. I will do that right now before I proceed.

I set Pre Authentication to Azure Active Directory, as I want everyone accessing the External Url to be a valid Azure AD user from my tenant. I also select to translate URL in headers, and select my previously configured App Proxy Connector Group.

Press Add to add the application to the directory. After that you are presented with a Quick start menu like below:


First I go to Properties, and optionally you can upload a logo which I have done here, note also that User assignment is required is set to yes, this means that no user cannot access the published application until I have added users or groups to it.


After saving I go to users and groups, and add some users to test the published application:


These users will now be able to launch the published application, but we have some more configuration to do first. As I want to have Single Sign-On configured for this application, I configure the following settings for Single Sign-On. I set the mode to Integrated Windows Authentication, meaning that the App Proxy Connector will impersonate any Azure AD authenticated user to the on-premises application via Kerberos constrained delegation.

I also need to specify a internal SPN for the application, which will be HTTP/<fqdn-of-server>, where the server is where the internal web application is installed. I will also specify which delegated login identity, which in most cases will work fine with user principal name for synchronized federated users.


After configuring Single Sign-On settings, and if you elected to use your own domain name, you need to upload or specify an existing SSL certificate. Go back to Application Proxy settings and click to view or change certificate settings:


After saving this configuration, the required portal configuration for the application is now complete, but optionally we can configure self service and conditional access, We will get back to that later in part 2 of this blog post.

That leaves only one more step, and that is to configure kerberos delegation for the App Proxy Connector server. In your on-premises Active Directory, find the computer object for the server you installed the App Proxy Connector on, and go to Delegation, and select to trust this computer for delegation to specified services only, and for kerberos only adding the computer name and http service for the server where the internal web application is installed. This should med the same as the internal spn you configured in the portal earlier for Windows integrated authentication.


Testing Single Sign-On

We can now test the application. Go to and log in with one of the assigned users. Among other published apps I will see the Configuration Manager Portal:


And if I launch it, I will see that I can access the Configuration Manager Portal, and I have been automatically signed in with my local AD user via Single Sign-On and Kerberos Constrained Delegation. I also see my url,, which I can access directly if I want without going through the MyApps panel.


So now we have successfully published the Cireson Configuration Manager Portal with Azure AD Application Proxy, using SSO with Azure AD, and User Assignment so that only users that are pre-authenticated and assigned the application by Azure AD, will have access to it.

Stay tuned for part 2 of this blog post, where we will configure Conditional Access using Azure MFA and Device Compliance, and what Self Service functionality we have.

Working with Azure AD Extension Attributes with Azure AD PowerShell v2

In a recent blog post,, I wrote about how to use extension attributes in local Active Directory and Azure AD, for the purpose of using these extension attributes for determine membership i Azure AD Dynamic Groups.

In the process of investigating my Azure AD users (synchronized and cloud based),  I wanted to see how I could use Azure AD v2 PowerShell CmdLets for querying and updating these extension attributes. This blog post is a summary of tips and commands, and also some curious things I found. There is a link to a Gist with all the PowerShell Commands at the end of the blog post if you prefer to skip to that.

Lets start by looking into one user:


For my example user I have the following output:


In the above linked blog post, I wrote about using the msDS_cloudExtensionAttribute1 and 2 for assigning licenses, so I see those values and more.

I can also serialize the user object to JSON by using $aadUser.ToJson(), which also will show me the value of the extension attributes:


I can look into and explore the user object with Get-Member:


From there I can see that that the Extension Property, which is of type System.Collections.Generic.Dictionary supports Get and Set. So lets look into how to update those extension attributes. This obviously only work on cloud homed users, as synchronized users must be updated in local Active Directory. This series of commands shows how to add extension attributes for cloud users:


The next thing I thought about, was how can I make a list of all users with their extension attributes? I ended up with the following, where you either can get all users or make a filtered collection, and from there loop through and read any extension attributes:


When I look into my extended users list object, I can list the users and values with extension values:



So to some curios things I found. As explained in the blog post, if you are running a Hybrid Exchange organization you would probably use extensionAttribute1..15 instead of the msDS_cloudExtensionAttribute. In another Azure AD tenant I tested on that, but using the commands above I never could list out the extensionAttribute1..15 on my users. I never found a way to validate and check those values, but if I created a Dynamic Group using for example extensionAttribute1 or 2, members would be populated! So it was obvious that the value was there, I just can’t find a way to check it.

I even tested on Graph API, but did not find any extensionAttribute there either, only msDS_cloudExtensionAttribute. For example by querying:<userid or upn>?$select=extension_66868723f2984d3e8c18f0ebd134240f_msDS_cloudExtensionAttribute2


I can see my extension value.

However, if I try:<userid or upn>?$select=extensionAttribute2, I cannot see the value even I know it’s there.


Strange thing, hopefully I will find out some more on this, and please comment if you have any ideas. I will also ask this from the Azure AD team.

Here is the gist with all the commands: