Using the Azure Run As Account in Azure Automation to Connect to Azure AD with a Service Principal

If you are using Azure Automation and working with Runbooks for automating against your Azure subscription, you can create an Azure Run As Account for authenticating and logging in to your subscription. The Azure Run As Account is configured in your Automation Account, and will do the following:

  • Creates an Azure AD application with a self-signed certificate, creates a service principal account for the application in Azure AD, and assigns the Contributor role for the account in your current subscription.
  • Creates an Automation certificate asset named AzureRunAsCertificate in the specified Automation account. The certificate asset holds the certificate private key that’s used by the Azure AD application.
  • Creates an Automation connection asset named AzureRunAsConnection in the specified Automation account. The connection asset holds the applicationId, tenantId, subscriptionId, and certificate thumbprint.

You can read more about setting up Azure Run As Accounts here, including how to do a more customized setup with PowerShell: https://docs.microsoft.com/en-us/azure/automation/automation-create-runas-account.

Something worth noting is that this Azure Run As Account will by default have the Contributor role to your entire subscription, so it would make sense to look into changing RBAC settings for the subcription or resource groups if you want to limit that. Also, all users that have access to the Automation Account will also have the opprotunity to use this Azure Run As Account.

Having said that, the Azure Run As Account is a great way to authenticate securely with certificates and a service principal name without needing to store a username and password in a credential object.

So I thought, wouldn’t it be great if we could use this same Azure Run As Account to log in to your Azure AD tenant for the possibility to run Azure AD PowerShell commands? The reason I thought of this is because of this article showing how to authenticate with Azure AD v2 PowerShell and Service Principal: https://docs.microsoft.com/en-us/powershell/azure/active-directory/signing-in-service-principal?view=azureadps-2.0. In this short blog post will show you how to do this.

Getting the Azure Run As Account details

First, look into your Automation Account and Account Settings to find any Run as accounts:

image

Click on the Azure Run As Account to see the details (or to create one if you haven’t before). Take a note of the Service Principal Object Id, we will use that later:

image

Creating a Runbook that Authenticates with Service Principal to Azure AD

Now, let’s create a PowerShell runbook using the Azure Run As Account for connecting to Azure AD.

First, I set the connection name  “AzureRunAsConnection”, and then save that as a variable for holding my service principal details using the Get-AutomationConnection cmdlet.

Then, logging in to Azure AD is done with specifiying TenantId, ApplicationId and CertificateThumbprint parameters, as shown below:

image

This will log in my service principal to Azure AD and I’m ready to run some commands, for example getting some organization details for the tenant, or counting different types of user objects:

image

Running this runbook will for example show me this output for my tenant. This shows that I successfully authenticated with the Azure Run As Account service principal:

image

Here is a link to a Gist where I have included the above PowerShell runbook script:

Role Permissions for the Service Principal

Depending on what kind of automation you want to do against Azure AD, especially if you want to write data, you will have to add the Service Principal to an Azure AD Role. Here is a couple of examples, using the object id for the service principal I told you to note earlier from the Azure Run As Account:

# Get the associated Service Principal for the Azure Run As Account
$runAsServicePrincipal = Get-AzureADServicePrincipal -ObjectId ""

# Add the Service Principal to the Directory Readers Role
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "Directory Readers"}).Objectid -RefObjectId $runAsServicePrincipal.ObjectId

# Add the Service Principal to the User Administrator Role
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "User Account Administrator"}).Objectid -RefObjectId $aaAadUser.ObjectId

# Add the Service Principal to the Global Administrator Role
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "Company Administrator"}).Objectid -RefObjectId $runAsServicePrincipal.ObjectId

That concludes this short blog post, hope it has been helpful! Thanks for reading and remember to share if it was useful Smile

Azure MFA Report Dashboard in Azure Portal–The Good, The Bad and The Ugly

If you are working with EMS and implementing Azure AD, Intune, MDM, MAM, Information Protection and more, you can build yourself some great dashboards in the Azure Portal using tiles and pin blades to your customized dashboard. This is an example from my own workplace:

image

Often when I work with projects implementing Identity & Access, Conditional Access and Azure MFA, I wish I could have a dashboard to report on MFA registration, and be able to pin that to my EMS dashboard as shown above.

It might be in the future that Azure MFA registrations and methods will be native in the portal, but for now this information have to be retreived in another way. In this blog post I will show you how you can set up a solution for showing this information. I will use the Markdown Tile from the gallery for displaying this information, and in the end it will look like this:

I referred in the title of this blog post to the good, the bad and the ugly, and by that I mean the process of setting this up, because it starts easy enough in the beginning but it will get more “ugly” in the end 😉

The Good – Setting up the Markdown Tile

I will use the Markdown Tile for the content in my customized dashboard in my Azure Portal. The first part is easy to set up, just click Edit and find the Markdown tile from the gallery, as shown below:

image

Drag the tile to a place you want it on your dashboard, and the Edit the title, subtitle and content as prompted:

image

There is a sample content provided, other than that you can write your own markdown. I will not get into details on markdown format here, there is a lot of good guides for learning the format, for example this: https://guides.github.com/features/mastering-markdown/. I will however provide you with a sample for reporting MFA registrations and default methods. This is how I set up my markdown tile:

image

And here is a link to my github repository where you can get the complete MFAReport.md file sample:

https://github.com/skillriver/AzureMFADashboard/blob/master/MFAReport.md

Now we need to fill that markdown tile with some real Azure AD MFA report data to report on.

The Bad – PowerShell Script for getting MFA registration and methods to Markdown

So the “bad” news is that we are reliant on running some Azure AD PowerShell commands for getting user details for MFA registration and methods. For now we are also reliant on the Azure AD v1 PowerShell (MSOnline) Module, as the new v2 AzureAD Module does not yet have any methods to get MFA authentication data. We cannot use the Microsoft Graph API either to get MFA user data, but I expect that to change in the future.

So lets look at the script I use, and after authenticating and connecting to Azure AD in my tenant with Connect-MSOLService, I will run the following commands to get details from each user where there has been configured one or more StrongAuthenticationMethods, and Group on those methods and save the results to a hash table. The results are stored in the $authMethodsRegistered object variable. Similarly I run the command once more, filtering on only showing the methods that are set to default for each user, and save to the $authMethodsDefault variable.

# Connect to MSOnline PowerShell (Azure AD v1)
Connect-MsolService

# Get MFA Methods Registered as Hash Table
$authMethodsRegistered = Get-MsolUser -All | Where-Object {$_.StrongAuthenticationMethods -ne $null} | Select-Object -Property UserPrincipalName -ExpandProperty StrongAuthenticationMethods `
| Group-Object MethodType -AsHashTable -AsString

# Get Default MFA Methods as Hash Table
$authMethodsDefault = Get-MsolUser -All | Where-Object {$_.StrongAuthenticationMethods -ne $null} | Select-Object -Property UserPrincipalName -ExpandProperty StrongAuthenticationMethods `
| Where-Object {$_.IsDefault -eq $true} | Group-Object MethodType -AsHashTable -AsString

# Create a Custom Object for MFA Data
$authMethodsData = New-Object PSObject
$authMethodsData | Add-Member -MemberType NoteProperty -Name AuthPhoneRegistered -Value $authMethodsRegistered.TwoWayVoiceMobile.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name AuthPhoneAppRegistered -Value $authMethodsRegistered.PhoneAppOTP.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name OfficePhoneRegistered -Value $authMethodsRegistered.TwoWayVoiceOffice.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name AlternatePhoneRegistered -Value $authMethodsRegistered.TwoWayVoiceAlternateMobile.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name OneWaySMSDefault –Value $authMethodsDefault.OneWaySMS.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name PhoneAppNotificationDefault –Value $authMethodsDefault.PhoneAppNotification.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name PhoneAppOTPDefault –Value $authMethodsDefault.PhoneAppOTP.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name TwoWayVoiceMobileDefault –Value $authMethodsDefault.TwoWayVoiceMobile.Count
$authMethodsData | Add-Member -MemberType NoteProperty -Name TwoWayVoiceOfficeDefault –Value $authMethodsDefault.TwoWayVoiceOffice.Count

# Write to Markdown file
"## MFA Authentication Methods`n" | Set-Content .\MFAReport.md -Force -Encoding UTF8
"### Registered`n" | Add-Content .\MFAReport.md -Encoding UTF8
"The following methods has been registered by users:`n" | Add-Content .\MFAReport.md -Encoding UTF8
"| Method | Count |" | Add-Content .\MFAReport.md -Encoding UTF8
"|:-----------|:-----------|" | Add-Content .\MFAReport.md -Encoding UTF8
"| Authentication Phone | " + [string]$authMethodsData.AuthPhoneRegistered + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| Phone App | " + [string]$authMethodsData.AuthPhoneAppRegistered + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| Alternate Phone | " + [string]$authMethodsData.AlternatePhoneRegistered + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| Office Phone | " + [string]$authMethodsData.OfficePhoneRegistered + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"" | Add-Content .\MFAReport.md -Encoding UTF8
"### Default Method" | Add-Content .\MFAReport.md -Encoding UTF8
"The following methods has been configured as default by users:" | Add-Content .\MFAReport.md -Encoding UTF8
"" | Add-Content .\MFAReport.md -Encoding UTF8
"| Method | Count |" | Add-Content .\MFAReport.md -Encoding UTF8
"|:-----------|:-----------|" | Add-Content .\MFAReport.md -Encoding UTF8
"| OneWay SMS | " + [string]$authMethodsData.OneWaySMSDefault + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| Phone App Notification | " + [string]$authMethodsData.PhoneAppNotificationDefault + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| Phone App OTP | " + [string]$authMethodsData.PhoneAppOTPDefault + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| TwoWay Voice Mobile | " + [string]$authMethodsData.TwoWayVoiceMobileDefault + " |" | Add-Content .\MFAReport.md -Encoding UTF8
"| TwoWay Voice Office Phone | " + [string]$authMethodsData.TwoWayVoiceOfficeDefault + " |`n" | Add-Content .\MFAReport.md -Encoding UTF8
"Last reported " + [string](Get-Date) | Add-Content .\MFAReport.md -Encoding UTF8

"" | Add-Content .\MFAReport.md

The complete PowerShell script can be found at my GitHub repository here:

https://github.com/skillriver/AzureMFADashboard/blob/master/MFAStrongAuthenticationUserReport.ps1

So now we have a script where we can get MFA authentication details for each user and create a markdown file that we can use in the tile in the Azure Portal custom dashboard. But it is all a manual process now, and it works fine for an ad hoc update. If we want to automate however, we have to get into the “ugly” stuff 😉

The Ugly – Automating Markdown creation and update Dashboard

This part requires multiple steps. First we need to schedule and run the PowerShell commands from above. Then we need to find a way to update the customized dashboard tile with the updated markdown file. To summary, this is what we need now:

  • Schedule the PowerShell script to run automatically. We can use Azure Automation for that.
  • Programmatically change the markdown tile in the customized dashboard. We can use Azure Resource Manager Rest API for that.

Lets get into the Azure Automation solution first. To run a PowerShell script I will need to create a Runbook, and in that Runbook I need to authenticate to Azure AD. I can define a Credential Asset with a username and password for a global admin user, but I like to use the least privilege possible, and besides that all my global admins are either protected by Azure AD PIM and/or MFA, so that won’t work. I prefer to use a service principal whereever possible, but after testing extensively with Connect-MSOLService that is not supported either.

So I tested with a dedicated Azure AD credential account, first by only adding the user to the Directory Readers role. I was able to list all users with Get-MSOLUser, but not any StrongAuthentication info. Neither did it work with Security Readers. In the end I added the user account to User Administrator role in Azure AD, and I was successful getting StrongAuthentication methods.

So, in my automation accont I will add or reuse my credentials:

image

Next, I will create a new PowerShell script based Runbook, basically I will use the PowerShell script from earlier in the blog, but with a couple of added parameter and getting the credential using the Get-PSAutomationCredential method. This is how it looks, you will get link to the complete script later:

image

And after testing, I can see that I successfully will get the MFAReport.md content (added a Get-Content .\MFAReport.md at the end to display the output):

image

Now that we have a solution for running the PowerShell script and generating the markdown file, the next part is how to update that data in the custom dashboard. And for that we need to look into programatically changing Azure Portal dashboards. There is a good resource and starting point for that in this article: https://docs.microsoft.com/en-us/azure/azure-portal/azure-portal-dashboards-create-programmatically.

First you need to share the custom dashboard, remember to include the markdown tile we set up in the first part of this blog post. At the top in the portal dashboard, select the Share button:

image

By sharing the dashboard will published as an Azure resource. Specify a name, select the subscription and either use the default dashboard resource group or select an existing one:

image

Go to Resource Explorer in the Portal:

image

Navigate to Subscriptions, Resource Groups, and find the resource group and resource containing the custom dashboard. From there you will be able to see the JSON definition of the dashboard and specifically the markdown tile containing the content we want to update:

image

So for next process now we need to copy this complete JSON definition containing all your tiles including the markdown tile. Locally on your computer, create a .json file in your favorite JSON editor, I use Visual Studio Code for this, and paste in the content. I have named my file DeploymentTemplateMFAReport.json.

Now we need to change this template to be ready for deployment, and for that we need to add or change a couple of things. First, in the start of the JSON file, add schema and versioning, and parameters, variables and resources section like I have shown below in line 1-17:

image

I have chosen to use 3 parameters, the markdown content itself, and name of the dashboard and the title of the dashboard.

Next, find the tile for the markdown content, and change the content value to the value of the parameter, like I have done at line 113 here:

image

And last, at the end of the json template, add and change the following settings, I have used my parameters for the dashboard name and the dashboard title here in the lines 401-411:

image

My deployment template for the customized dashboard is now completely general and can be used in every environment. In fact you are welcome to borrow and use my template from above her, I have included it in my github repository:

https://github.com/skillriver/AzureMFADashboard/blob/master/DeploymentTemplateMFAReport.json

Working locally in my Visual Studio Code editor, I can now test the deployment using Azure PowerShell, as shown below and described with these simple steps:

  1. Connect to Azure Resource Manager and select the Subscription
  2. Specify a variable for the Resource Group you want to deploy to
  3. The MFAreport.md file (which we created earlier) need some converting to JSON format, I’m removing all espace characters and any uneeded special characters
  4. Specify variable names your environment for name and title for the dashboard
  5. Deploy the custom dashboard to the resource group

image

However, now that we can test the deployment, I want to schedule a deployment using Azure Automation, and I will continue on my previous runbook from before. But first we need to set up some connections for authenticating to Azure and some variables.

I Azure Automation we can create an Azure Run As Account, this will also create a service principal. If you navigate to your Automation Account in the Azure Portal, and go to the section called Run as accounts, you can create an Azure Run As Account automatically, as I have done here:

image

If I look more closely at this generated Run As Account, I can see details for Azure AD App Registration, Service Principal, Certificate and more. This account will also automatically be assigned Contributor role for my Azure Subscription. If you want more control over Azure Run As Accounts, you can create your own as described in the following article: https://docs.microsoft.com/en-us/azure/automation/automation-create-runas-account

image

I will use this Azure Run As account in my environment to deploy the dashboard resource, I’ll just need to make sure the account has contributor access to the resource group. Next I will set ut a few variables under the Variables section for my Automation Account, I will use these variables when I deploy the resource:

image

Now we are ready to finally put together the complete Runbook and test it. You will have the complete link later in the blog post, but I will share some screenshots first:

After I’ve connected with Connect-MSOLService I’m creating a variable for the markdown content, so I’ve changed from earlier when I saved a .md file temporarily, now I just adding lines using the newline special character (`n):

image

The next part is for logging in to Azure (using the Azure Run As Account mentioned above), and then getting my variables ready for deployment:

image

Then I convert the markdown content to Json format, and removing any escape characters that I don’t need:

image

And then deploy the dashboard resource with parameters for markdown content and dashboard name & title. Note that I’m using my deployment template as a source from my github repository via the TemplateUri property:

image

You can use any TemplateUri you want, for example from a more private source like a storage account blob etc.

Testing the Runbook gives the following output, which shows it was successful:

image

When I now go and refresh the dasboard in the portal, I can see that the markdown tile has been updated:

image

That leaves me with just publishing and scheduling the runbook:

image

When creating a new schedule specify a name and recurrence:

image

Link the schedule to the runbook and any needed parameters, I have to specify my credential that are allowed to Connect-MSOLService:

image

That concludes this lengthy blog post. The script will now run regularly and update my custom markdown tile with MFA report data.

Here is the link to the PowerShell script used in my Azure Automation runbook, enjoy your MFA Reporting!

https://github.com/skillriver/AzureMFADashboard/blob/master/MFAStrongAuthenticationUserReportAutomation.ps1

 

Getting started with Azure AD PIM PowerShell Module

This is a short blog post showing how you can get started and some examples of using the PIM PowerShell Module for Azure AD Privileged Identity Management.

You can read more about Azure AD Privileged Identity Management here: https://docs.microsoft.com/en-us/azure/active-directory/active-directory-privileged-identity-management-configure, or by just using the following short URL: https://aka.ms/AzureADPIM!

Installing the Azure AD PIM PowerShell Module

Since there are no PIM related commands in the AzureAD or AzureADPreview PowerShell Modules, we will have to install a separate module for PIM. You can find this module at the PowerShell Gallery here: https://www.powershellgallery.com/packages/Microsoft.Azure.ActiveDirectory.PIM.PSModule

To install the module just run the following command in an elevated PowerShell session:

Install-Module Microsoft.Azure.ActiveDirectory.PIM.PSModule

image

After installing you can list the available commands in the PIM module:

Get-Command -Module Microsoft.Azure.ActiveDirectory.PIM.PSModule

image

Here is a short explanation of the available commands:

  • Connect-PimService. Prompts you to log on with an Azure AD Account that might have any PIM roles assigned. You can optionally specify a username, tenantname or credential object as parameters. Especially tenantname would be useful if you are a guest user with roles assigned in another tenant.
  • Show-PimServiceConnection. This will show the active PimService session details you have, after connecting with Connect-PimService.
  • Get-PrivilegedRoleAssignment. This would list any permanent or eligible role assignments the user you connected with using Connect-PimService has.
  • Enable-PrivilegedRoleAssignment. This command will enable a specified role assignments. It is required to specify which role either by RoleId or by a RoleAssignment variable. It is also required to specify a Duration for activation. Optional parameters includes Reason, TicketNumber, TicketSystem and StartTimeUtc.
  • Disable-PrivilegedRoleAssignment. If you previously have activated one or more roles with Enable-PrivilegedRoleAssignement, you can preemptively deactivate these roles again before the duration expires. You must specify a RoleId or RoleAssignment variable.
  • Disconnect-PimService. Disconnects any previous sessions to PimService.

Examples of Azure AD PIM Commands

In the following I will show some examples of using the Azure AD PIM Module.

Connect-PimService

In the following I’m connecting with a specified username, if it is required to use Azure MFA for this user I will be prompted for that as well:

Connect-PimService –UserName <username>

image

image

After authenticating, PIM service connection details are returned, here slightly masked:

image

The above returned is exactly the same as would be returned by running the command:

Show-PimServiceConnection

Get-PrivilegedRoleAssignment

This command will list any role assignments, permanent or eligible your user might have. Here is a couple of examples for outputs for two different admin users. The first user is eligible for Security Administrator and Privileged Role Administrator, and permanent for Global Administrator:

image

The second admin user is eligible for Exchange Administrator and Global Administrator:

image

If I want to assign a variable to a role assignment, I can do it like the following command:

$roleAssignment = Get-PrivilegedRoleAssignment | Where {$_.RoleName -eq "Privileged Role Administrator"}

I now have a role assignment variable I can use in the following commands.

Enable-PrivilegedRoleAssignment

To enable one of my roles, I need to specify a duration (PS! keep inside the allowed role settings for max duration!), and specify which role either by RoleId or RoleAssignment variable. Optional parameters like Reason etc can also be specified.

Here is a working example:

Enable-PrivilegedRoleAssignment –Duration 1 –RoleAssignment $roleAssignment –Reason “Add crmadmin to CRM Administrators”

After running the command, if successful it will return as a submitted request for activating role membership.

image

By running Get-PrivilegedRoleAssignment again, we can now see that the role of “Privileged Role Administrator” is indeed activated (elevated), and with a ExpirationTime (UTC time):

image

PS! If you have required MFA on activation for the role, one of two things will happen:

  1. If the user already has verified the identity with Azure MFA when authenticating with Connect-PimService, the user will not be asked again. This is the same experience as by using the Azure Portal for activating roles.
  2. If the user hasn’t verified with Azure MFA, the user will be prompted when activating the role, similar to this example:

    image

Disable-PrivilegedRoleAssignment

Any roles you have activated will automatically deactivate after the duration specified has passed. However, if you are finished doing administrative tasks with your role, you can deactivate the role manually.

To deactivate an active assignment, run the following command specifying a RoleId or RoleAssignment variable:

Disable-PrivilegedRoleAssignment –RoleAssignment $roleAssignment

image

Disconnect-PimService

To end your connection to Azure AD PIM Service, run the following command:

Disconnect-PimService

After running that command you can also see that there are no role assignments to list anymore.

image

Hope these commands and examples have been helpful, enjoy working with Azure AD PIM!

How to configure Conditional Access for Azure AD PIM

Azure AD Privileged Identity Management is a really great security feature for controlling those Azure AD and Azure Subscription administrator roles. By implementing Azure AD PIM you can let users with admin roles elevate themselves when they need to, using just in time (JIT) and eligible roles instead of permanent admin roles. You can even implement approval workflows and audit trails, so if you haven’t looked into it you should really take a look!

With Azure AD PIM you can require Azure MFA when activating admin roles, but outside that you cannot set conditions and access control scenarios like you can do with Azure AD Conditional Access.

But now recently there is a new option in public preview for assignments to users and groups for Conditional Access policies, you can assign the CA policy to directory roles!

image

So I was wondering how this would work together with Azure AD Privileged Identity Management, for example in the following scenario:

I have an Exchange Administrator that from time to time performs Exchange Online admin tasks, and have configured this admin user with Azure AD PIM and eligible for Exchange Administrator Role among others:

image

Lets say that I only want this user to perfom Exchange Administrator tasks from a Compliant Device. Even though the Azure AD PIM role is protected by MFA at activation, making the user secure and trusted, I really want the device he is using to be secure and compliant with any management profiles I have defined using Intune MDM. Especially when he is doing admin stuff in our Exchange Online tenant or even running some Exchange Online PowerShell commands.

Lets set up this scenario.

Creating Azure AD Conditional Access Policy for Directory Role

The first thing I set up is the CA policy for my specific Directory Role in this scenario. I specify a name and then select the Directory role of Exchange administrator as shown below:

image

Next for Cloud apps I select Exchange Online:

image

For Access controls I select to require the device to marked as compliant:

image

After that I enable the policy and save. We are now ready to test the user experience.

Testing Azure AD PIM Role Activation and Conditional Access

So now we can test the scenario. Remember that the idea is that the CA policy only will kick in when the user has activated his Azure AD PIM role assignment as Exchange Administrator.

PS! If this user also has a Exchange Online license and mailbox, the same CA policy will apply and require the device to be compliant as long as the Exchange Administrator role is active. That could pose some not intended side effects, requiring the devices that access Exchange Online for normal mailbox access to be compliant as well, but as long as the Exchange Online Admin isn’t available as a Cloud app in Conditional Access we have to do it this way.

With my admin user, I first go to http://aka.ms/myroles, which will redirect me to my roles defined in Azure AD PIM. Lets sign in first:

image

And here is my eligible roles:

image

I select the action link to activate my Exchange Administrator role, and then to verify my identity with Azure MFA:

image

After verifying I can specify a reason or adjust the activation duration:

image

After that I’m activated and has an access valid for the set period of time:

image

Now, let’s go to to the Exchange Online Admin portal: https://outlook.office365.com/ecp. After signing in, if I’m not already signed in, I will get this message:

image

The details will tell me that the access rules require a compliant device:

image

We could also check using Exchange Online PowerShell module, and I get the same message:

image

Note that this message only works with the Connect-EXOPSSession that use Modern Authentication. The “old” way of using remote PowerShell and credential object to Exchange Online use basic (legacy) authentication so we cannot control that information flow, but the admin user will be denied there as well:

ExoPS

To conclude this blog post, I have shown that by combining the new preview feature of Directory Roles assningments for Azure AD Conditional Access, and Azure AD Privileged Identity Management, we can implement more complex scenarios for conditions and access rules for using those directory roles. In my example I used compliant device, but you could also use any other of the conditions and access controls available.

Configure Azure AD Authentication for Project Honolulu version 1803

Just a few days ago a new version of Project Honolulu, technical preview 1830, was released for Windows Server Insiders, https://blogs.windows.com/windowsexperience/2018/03/13/announcing-project-honolulu-technical-preview-1803-and-rsat-insider-preview-for-windows-10/.

One of the major updates to that version was the support for changing access control from local group/Active Directory to Azure AD Authentication. Configuring Azure AD Authentication will provide the ability to pre-authenticate users with their Azure AD credentials, as well as restrict access to selected users or even integrate with Azure AD Conditional Access.

In this blog post I will provide some steps, examples and screenshots for how I did that configuration in my own environment.

This scenario builds on the previous installation I have made with Windows Server 1709 (Server Core) and Project Honolulu, see blog article for how my setup is: https://gotoguy.blog/2018/02/13/installing-windows-server-version-1709-on-intel-nuc-skull-canyon-and-configure-hyper-v-for-remote-management/

Update existing version of Project Honolulu to version 1803

Since I had an existing installation of Project Honolulu on this server ELVEN-NUC-HV1.nuc.group, I downloaded the 1803 installation file, connected to the server and ran the following command to silently install and update the existing installation:

msiexec /i HonoluluTechnicalPreview1803.msi /qn /L*v log1803.txt SME_PORT=443 SSL_CERTIFICATE_OPTION=generate

After that I navigated to the https://elven-nuc-hv1.nuc.group url from my client machine, and verified that I could sign in and see that the Project Honolulu website was updated.

image

I also note the certificate warning I receive because my client doesn’t trust the self generated certificate the gateway server installation provided. This will be a problem when using Azure AD Authentication, so in the next step I will make sure the client trusts that.

Export and trust self signed certificate

First, start a PowerShell session on the Honolulu Gateway Server, and then run the command:

Get-ChildItem –Path cert:\LocalMachine\My | FL

This will return any certificates in the machine store. As I have previously installed and generated a self signed certificate for Project Honolulu gateway server, I see 2 certificates now, and can note the thumbprint for the most recent one:

image

Next I will run the following commands for getting the certificate and exporting it to a .cer file:

$cert = (Get-ChildItem –Path cert:\LocalMachine\my\<THUMBPRINT>)
Export-Certificate –Cert $cert –FilePath <path>\<filename>.cer.

In my enviroment I ran the following:

imageAfter that, transfer the .cer file to the client computer(s) you want to be able to connect to the Project Honolulu website, and run the following commands to get and import the .cer certificate into trusted root store:

$cert = (Get-ChildItem –Path <path>\<filename>.cer)
$cert | Import-Certificate –CertStoreLocation cert:\LocalMachine\Root

In my enviroment this looked like this (from an elevated PowerShell window):

image

I took the extra step of verifying that the self signed certificate indeed was imported into trusted root store:

image

Change Access Control to Azure AD

Now I am ready to change access control in Project Honolulu. Click on the Settings cogwheel, and under Settings click Access.

My current settings are set to Active Directory or Local groups, so I click on Change access control:

image

I then change to Azure Active Directory (AAD), and see the prerequisites for connecting the gateway to Azure:

image

I downloaded the New-AadApp.ps1 script, note that this script requires the modules AzureRM.Resources and AzureAD to be installed at the machine where you run the script. If you don’t have them installed, you can install these using Install-Module, as shown in this example:

image

I chose to run this script on my client computer (not on my server core gateway computer), and with the following command:

.\New-AadApp1803.1.ps1 –GatewayEndpoint https://elven-nuc-hv1.nuc.group

(PS! I didn’t have the AzureAD module installed, but the AzureADPreview module instead. A simple change in the Requires section of the script fixed that;)

Running the script prompted me to specify a Global Administrator account for the tenant I wanted to register the Azure AD App in, and after sucessfully authenticating I got confirmation. Note the AAD Application name and other Id’s:

image

Back at the Access Control settings, refresh the browser, note the changed instructions show in the dialog below, and then Save. This will restart the gateway service.

image

After refreshing the browser again, you will be prompted by the following consent for permissions (provided that you already had an active logged on session, or else you will prompted to log in to the tenant you registered the app in):

image

After successfully authenticating and accepting, I’m logged into the Project Honolulu website. Under Settings and Azure, I can verify that I’m logged in and sign out again if needed.

image

Logging on with other users from the tenant

Remember by default all members of the Azure AD tenant will have user access to the Honolulu gateway service. That includes any B2B Guest Users!

Each user logging in need to first time consent to permissions, in the following screenshots I have logged on with a normal user account and then a B2B guest account:

imageimage

Only local administrators on the gateway machine will have administrator access to the Honolulu gateway.

Under Access Settings you can click on a link to go directly to the Azure AD App that got registered when you ran the script earlier:

image

Clicking on that link and logging in with a Global Administrator, you will get to your SME-<name> app. From there you can go to users and groups, and all users that have logged in until now will be listed. By default they will not have any role assigned, but you can change role between Gateway Administrator or Gateway User as I have done below:

image

If you want to restrict which users or groups that are allowed to log into the Project Honolulu site with their Azure AD Credentials, you can go to Properties and then enable the setting for require user assignment:

image

After enabling this setting users that aren’t added to the list of users or groups either directly or via group membership will not be allowed to log on to Project Honolulu.

Summary and next steps

In this blog post I have shown a first look for enabling Azure AD Authentication for Project Honolulu version 1803 technical preview.

The next step is to look into configuring Azure AD Conditional Access for this application, that will come in a later update to this blog article, stay tuned!

A couple of issues is also on my list:

  • I’m prompted to log on with local admin credentials in addition to the Azure AD credentials
  • When I follow the link from Access Control settings I’m able to find the Azure AD App, but I cannot see it by just browsing the Enterprise Applications list. Based on the documentation I this should have work. This means for now I cannot add that App to any Conditional Access policies as it is not browseable.
  • The .\New-AadApp1803.1.ps1 script cannot be run on the Windows Server 1709 core version, as there is no GUI and I get iframe errors, it could be that this is related to the issue above, as I ran the script on my client instead.

I will also look into these issues in an update to this blog post. Please comment below if you are seeing similar issues or have any other experiences. Thanks for reading 🙂

Install & Register Azure AD Application Proxy Connector on Windows Server 1709

I recently installed the new release of Windows Server, version 1709 on my Intel NUC, you can read about that here.

I have installed Project Honolulu for remote server management on that server, but as this Intel NUC is usually located on my home lab network, I want to be able to publish and access the Honolulu website using Azure AD Application Proxy.

As the Windows Server 1709 is Server Core, I need to install and configure the Azure AD Application Proxy Connector silently, and these are the steps I did to do that.

First, you need to download the Application Proxy connector install file, and transfer it to the server. You can access the connector download from Application Proxy section in your Azure AD portal:

image

After that, run the following command to do a quiet install of the connector, skipping registration interactively:

AADApplicationProxyConnectorInstaller.exe REGISTERCONNECTOR=”false” /q

image

Next we need to register the Application Proxy connector to Azure AD, and for that we need to run some PowerShell commands. There are two ways this can be done, with a Credential Object, or using an Offline Token. Using Credential is simplest, but has the drawback that you cannot use that method if your Global Administrator account is protected with Azure MFA. Lets look at both methods below.

Using Credential Object:

On the Server you want to register the Azure AD App Proxy Connector, start a PowerShell session and run the following commands for setting the Global Administrator user name and password, and then create a Credential Object.

image

After that, run the following commands to run the RegisterConnector.ps1 script for register the connector using Credential object as authentication:

image

You can copy the PowerShell commands used above using the Gist linked at the end of this blog post.

Using Offline Token:

If you can’t or don’t want to use a credential object, you have to use a offline token. The following commands will get an access token for the authorization context needed for Application Proxy Connector Registration.

Getting the Token can be run from any client, and then transferred to the server, but you will need to have the Azure Active Directory Authentication Library (ADAL) installed at the machine you are running the PowerShell commands. The easiest way to get the needed libraries installed is to Install the AzureAD PowerShell Module.

The following commands locates the AzureAD (or AzureADPreview) Module, and then finds the ADAL Helper Library: Microsoft.IdentityModel.Clients.ActiveDirectory.dll, and adds that as a Type to the PowerShell session:

image

Next, run these commands to define some constants, these values are the same for all tenants:

image

Now we can run these commands for setting the authentication context and then prompt user for AuthN:

image

Running the above commands will result in an authentication prompt, this is where you would specify your Global Administrator account, and if MFA enabled this will also work:

image

After authenticating we can check the result and save the token and tenantId in variables as shown below:

image

Next, copy the contents of the $token and $tenantId to the Windows Server 1709, and run the following command to create a secure string from the token:

image

And then run the RegisterConnector.ps1 script with AuthenticationMode as Token and using the secure token and tenant id as parameter values as shown below:

image

PS! According to the official documentation, there are no description or examples for the mandatory parameter “Feature”, but I found that it accepts the value “ApplicationProxy” as used above.

You can copy the above PowerShell commands from the Gist linked at the end of this blog post.

So to recap, after installing the Application Proxy Connector silently on the Windows Server 1709, and then registering the connector, I can now verify in the Azure AD Portal that the connector is available for use. I can see it has a status of Active, from my home IP address, and I have already placed it in a Connector Group.

image

I’m now ready to publish Azure AD Proxy Apps using this connector, and in my next blogpost I will publish the Project Honolulu management website using this!

Here is the Gist source for the above linked PowerShell commands:

Installing Windows Server, version 1709, on Intel NUC Skull Canyon and Configure Hyper-V for Remote Management

A while back I wrote a blog post on Installing Hyper-V Server 2016 on my Intel NUC Skull Canyon: https://gotoguy.blog/2016/10/17/installing-microsoft-hyper-v-server-2016-on-intel-nuc-skull-canyon/

You can read more on the hardware setup on that referred blog post, but in this blog post I will revisit the steps on how to repeat this setup on the new Semi-Annual Channel release of Windows Server, version 1709. You can read more on this new server version here: https://docs.microsoft.com/en-us/windows-server/get-started/get-started-with-1709

Setup Windows Server, version 1709

I needed to add a bootable volume for which I could install Windows Server, version 1709, and prepared an USB stick for which I would boot up the installation media for Windows Server 1709. The following steps should help you set up a bootable USB stick for Windows Server, version 1709:

  1. Download the .iso image for the Windows Server, version 1709, and mount it to a drive letter (in my example this will be f:)
  2. Make sure the USB stick is inserted and note the drive letter (in my case this is E:)
  3. Launch an elevated Command Prompt or PowerShell window (Run as Administrator)
  4. Run command: Diskpart (this will start DiskPart tool in interactive mode)
  5. Run command: list disk (from the list, note the disk number of the USB drive)
  6. Run command: select disk 1 (use the number from above, double check before next step which is to clean)
  7. Run command: clean (careful, this will wipe out the usb drive completely, so make sure you have selected the correct disk number)
  8. Run command: create partition primary
  9. Run command: select partition 1
  10. Run command: active (this will mark the selected partition as active)
  11. Run command: format fs=ntfs quick label=”1709″ (wait after for formatting to complete)
  12. Run command: exit
  13. You have now exited diskpart, change to the mounted iso drive (f:), and the run command: cd boot
  14. Run command (change drive letters if different in your environment): F:\boot>bootsect /nt60 e:
  15. You will now have updated NTFS filesystem bootcode on the USB drive, and the last step is to copy all Windows Server, version 1709 files:
    xcopy f:\* e: /H /F /E
  16. This could take a while, especially copying the large install.wim file. After copying is finished, you are ready to boot the USB stick on the Intel NUC Skull Canyon.
  17. At the Intel NUC boot screen, hit F10 to enter boot menu, and select the boot option for UEFI USB drive. After this the Windows Server, 1709 server install should begin.

Install the Windows Server, 1709 following the installation process, and since 1709 is only available in Server Core, you will have to use Command Prompt and “SConfig” tool for initially configuring the server as shown in the next section.

Configuring the Windows Server, 1709 version for Remote Management and Hyper-V Server

After installation and changing the Administrator account password before first time logon, the Server Core configuration was ready for to start configure the server.

I first did these changes:

  • Renamed the Computer Name, in this case I renamed the Computer to ELVEN-NUC-HV1
  • Renamed the Workgroup name to NUCGROUP (optional)
  • Enabled Remote Desktop (All clients, less secure). This setting can be reversed after I have configured all the Remote Management scenarios I need to.
  • Under Configure Remote Management, I also Enabled the Server to Response to Ping, that could be useful when setting up the Server.
  • I also downloaded and installed any pending updates.

2018-02-13_00-29-31

My next step was to add the Hyper-V Server Role and configure for Remote Management via Hyper-V Manager.

Add and Configure the Hyper-V Host for Remote Management

In the Command Prompt of the server, type powershell.exe to start a PowerShell session.

Then run the following command to install the Hyper-V Role:

Add-WindowsFeature -Name Hyper-V,RSAT-Hyper-V-Tools

2018-02-13_22-36-56

After a reboot we are ready to configure the server for remote management

I want to use my Windows 10 machine and Hyper-V Manager to remote manage this Hyper-V Host, as described in this link: https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/user_guide/remote_host_management.

As this will be my home/portable lab, the Hyper-V Server will not be in a domain, so I need to use the instructions at the end of the above article for Manage a Hyper-V host outside your domain (or with no domain).

This is the steps I went through to set that up:

Configure FQDN for the Hyper-V Host

I want to set the FQDN for the Hyper-V Host so that:

Computername = ELVEN-NUC-HV1
Desired Primary DNS Suffix = nuc.group

In PowerShell, I first add the FQDN of the computer with the Netdom command:

netdom computername $env:computername /Add:ELVEN-NUC-HV1.nuc.group

Second, I add the FQDN of the computer to primary:

netdom computername $env:computername /MakePrimary:ELVEN-NUC-HV1.nuc.group

Restart the server before the next step.

Add the FQDN and IP address to the Hosts file

To be able to access the Hyper-V Server from my Windows 10 client, I add the IP address (I have created a DHCP reservation for it on my Router) and the FQDN in my Hosts file in C:\Windows\System32\Drivers\Etc directory.

image

Configure Remoting on the Hyper-V Server

On the Hyper-V host to be managed, start PowerShell.exe, and run the following as an administrator:

Enable-PSRemoting

Enable-PSRemoting will create the necessary firewall rules for private network zones.

To make sure that the connection are in the private network zone, I check with the command:

Get-NetConnectionProfile

In my case, as this server is in a workgroup, I must specifically change the network zone from public to private:

Set-NetConnectionProfile -InterfaceIndex 4 -NetworkCategory Private

When checking after that, the connection is now Private:

2018-02-13_23-04-11

After that I run the following command:

Enable-WSManCredSSP -Role server

Configure the Client

On my Windows 10 client machine, I run the following commands in a PowerShell (Run As Administrator) session:

# Start the WinRM Service
Start-Service WinRm

# Add the Hyper-V Server as Trusted Host
Set-Item WSMan:\localhost\Client\TrustedHosts -Value “elven-nuc-hv1.nuc.group”

# Add the Hyper-V Server to the list of servers to delegate credentials to
Enable-WSManCredSSP -Role client -DelegateComputer “elven-nuc-hv1.nuc.group”

If you later when adding the Server to Hyper-V Manager, get this error message, you need to follow these instructions on the client via GPedit.msc:

Configure the following group policy: * Computer Configuration | Administrative Templates | System | Credentials Delegation | Allow delegating fresh credentials with NTLM-only server authentication *

Click Enable and add wsman/elven-nuc-hv1.nuc.group

image

 

Add the Server to Hyper-V Manager

Finally, we should be ready to add the Server to Hyper-V Manager:

  1. Select Connect to Server, specify name and Connect as your Admin user:image
  2. And now I can successfully configure the Hyper-V Server:
    2018-02-13_23-09-11

I can now configure Hyper-V Settings and add VMs to the Server via Hyper-V Manager from my Windows 10 client to the Windows Server, version 1709!

Manage the Windows Server 1709 with Project Honolulu

Another way to remote manage the Windows Server, version 1709 is to use the browser based server management tool “Project Honolulu”, https://docs.microsoft.com/en-us/windows-server/manage/honolulu/Honolulu.

Project Honololu is supported in Gateway Mode on the 1709 server version, and to install you first have to download the Honolulu installer, and then run a command like this:

msiexec /i <HonoluluInstallerName>.msi /qn /L*v log.txt SME_PORT=<port> SSL_CERTIFICATE_OPTION=generate

In my example I ran the command like this:

msiexec /i HonoluluTechnicalPreview1712-05002.msi /qn /L*v log.txt SME_PORT=443 SSL_CERTIFICATE_OPTION=generate

After installing Project Honolulu I can now also remote manage via browser from my client:

2018-02-13_23-26-59