Microsoft Graph Filtering Results PowerShell

During a recent audit we have been trying to automate a report on what Guest account’s are active in the last 30 days and to find what groups these guest account are members of so they can be removed if they are no longer required.

We could use AzureAD PowerShell for getting guest account and group membership but it was not that easy to automate this.

We decided to use Microsoft Graph as we have a few task already automated using Microsoft Graph and certificates so there is no need to hard code any password or application secret in my script.

I have done a previous post on the getting the access token and using certificate based authentication so if you need to know how to setup you can check that post.

Connect to Microsoft Graph using MSAL and Certificate based Authentication – TheSleepyAdmins

In this query we will be using three different Microsoft Graph url’s. First is to get a list of guest users, second will be to get sign-in logs and the last will be to get the guest users group membership.

To get guest users we will filtering using userType attribute

user resource type – Microsoft Graph v1.0 | Microsoft Docs

below are the permission that will be required

ApplicationUser.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All

To get sign-in’s we will be filtering on two different attributes (userPrincipalName & createdDateTime)

List signIns – Microsoft Graph v1.0 | Microsoft Docs

below are the permission that will be required

ApplicationAuditLog.Read.All and Directory.Read.All

To get Group membership we will be using the memberof

user: getMemberGroups – Microsoft Graph v1.0 | Microsoft Docs

below are the permission that will be required for getting the group membership.

ApplicationUser.Read.All, Directory.Read.All, Directory.ReadWrite.All

First step as with any Graph query is to create the token request that will be used to access the different Graph Url’s. We will be using MSAL module and a certificate to generate.

To filer results using Graph we can put in ?filter= and then use a supported filter attribute. In this case we will be using usertype.

We will also create a blank array variable that will be used to output to later and a date variable to filer the sign-in logs.

This first filter will get all guest users. Currently usertype is only available when using the beta Graph version so we will be using that.

"https://graph.microsoft.com/beta/users/?filter=usertype eq 'Guest'"

Once we have the Guest users we will loop through each one, use a second filter that uses the mail address to filter the guest user sign-in logs and use a date variable to show only sign-in over the last 30 days.

"https://graph.microsoft.com/beta/auditLogs/signIns/?filter=userPrincipalName eq '$($User.mail)' and createdDateTime ge $Date"

The next filter is going to use the user ID to get the memberof for the user and we will use the group-object to put all groups display names in to one object so it easier to call to the console windows or export to a CSV.

"https://graph.microsoft.com/beta/users/$($User.ID)/memberof"

Once we have all the information returned from the Graph queries we need to format the results. For this we will use a hash table and an if statement to output user with or without sign-in logs to the correct hash table and add the values to the results variable.

This script is only going to return the latest sign-in log as I only really want to have a report that the users has been active in the last 30 day that’s why I am using [0] to select the latest object in the $logins variable.

The last part of the script just outputs the results and use select-object to format the order.

Now that we have the full script the below is what the result should look like.

To make the script more reusable there are three variable for TenantId , ClientId and CertThumprint.

To export the result to a csv instead of the console windows there is an -Exportpath parameter that just needs to have the path specified.

The full script can be download from my Github repository

Scripts/MSGraph/GuestUserAuditReport at master · TheSleepyAdmin/Scripts (github.com)

To filter on other attributes we can use the same process as above just change the Graph url and check the document for that url to view what is a valid filter attribute. Filtering results in the the Graph url speeds up the script and mean we don’t do addtional filtering after returning all data.

Connect to Microsoft Graph using MSAL and Certificate based Authentication

I had a recently gotten some question’s on how to connect to Microsoft GraphApi using certificate instead of an app secret. I have set this up before using the Microsoft Graph PowerShell SDK but I wanted to test this using Invoke-RestMethod.

There is a PowerShell module that has been created that allow for much easier creation of authentication tokens using Microsoft Authentication Library.

Learn about MSAL – Microsoft identity platform | Microsoft Docs

The Microsoft Authentication Library (MSAL) enables developers to acquire tokens from the Microsoft identity platform in order to authenticate users and access secured web APIs. It can be used to provide secure access to Microsoft Graph, other Microsoft APIs, third-party web APIs, or your own web API. MSAL supports many different application architectures and platforms including .NET, JavaScript, Java, Python, Android, and iOS.

MSAL gives you many ways to get tokens, with a consistent API for a number of platforms. Using MSAL provides the following benefits:

  • No need to directly use the OAuth libraries or code against the protocol in your application.
  • Acquires tokens on behalf of a user or on behalf of an application (when applicable to the platform).
  • Maintains a token cache and refreshes tokens for you when they are close to expire. You don’t need to handle token expiration on your own.
  • Helps you specify which audience you want your application to sign in (your org, several orgs, work, and school and Microsoft personal accounts, social identities with Azure AD B2C, users in sovereign, and national clouds).
  • Helps you set up your application from configuration files.
  • Helps you troubleshoot your app by exposing actionable exceptions, logging, and telemetry.

The PowerShell module that can be used to create tokens is called MSAL.PS and the latest version as of today is 4.21.0.1.

PowerShell Gallery | MSAL.PS 4.21.0.1

In this post we will be going through installing and using this module to generate an authentication token using a self signed certificate and using that token to connect to Microsoft Gaph.

The first step is to install the MSAL.PS module

Once the module is installed we can generate the certificate that will be used to connect to Microsoft Graph

To create the self signed cert I used the below command. There was a error when trying to generated the token when I didn’t use -KeySpec when generating the cert. The fix to use -KeySpec was on the GitHub issue page.

Get-MsalToken with Client Certificate fails on Windows PowerShell 5.1 · Issue #15 · AzureAD/MSAL.PS (github.com)

New-SelfSignedCertificate -DnsName TennatDomainName -CertStoreLocation "Cert:\CurrentUser\My" -FriendlyName "MSAL_Cert" -KeySpec Signature

Once the cert has been created, export the cert so that it can be uploaded to the App registration.

Get-ChildItem Cert:\CurrentUser\my\CertThumbprint | Export-Certificate -FilePath C:\temp\Graph_MSAL_Cert.cer

Once the cert is exported we can upload to the app registration that we created before. See previous post if app registration hasn’t been created in Azure yet for Microsoft Graph.

Connecting to Microsoft GraphAPI Using PowerShell – TheSleepyAdmins

To add the cert open the Azure portal > Azure Active Directory >  App registrations and select the Graph app and go to certificates & secrets

Select upload certificate

Click add to apply the cert

After the cert is upload we should now be able to connect. We will need the TenantId, clientId and certificate

The tenantID and ClientId can be gotten from the app registration overview page and the cert can be gotten using Get-Item and the cert location / thumbprint.

Import-Module MSAL.PS
$TenantId = "TenantId"
$ClientId = "ClientId" 
$ClientCert = Get-ChildItem "Cert:\CurrentUser\my\CertThumbprint"
$MSToken = Get-MsalToken -ClientId $ClientId -TenantId $TenantId -ClientCertificate $ClientCert

If you want to use the same cert for any users on the device we can export and import the cert under localmachine cert store with the private key and update the $clientCert to use localmachine instead of currentuser.

Get-Item "Cert:\localmachine\my\CertThumbprint"

Once we have the token, it’s now the same process as we have used before to connect using invoke-restmethod but using the $MSToken.AccessToken we generated using the Get-MsalToken and our certificate.

$GraphGroupUrl = 'https://graph.microsoft.com/v1.0/Groups/'
(Invoke-RestMethod -Headers @{Authorization = "Bearer $($MSToken.AccessToken)"} -Uri $GraphGroupUrl -Method Get).value.displayName

Using MSAL.PS module provides a much quicker and easier way to generate access tokens for Microsoft Graph with the added security of using a certificate over having to put in any application secret.

Microsoft Graph API Result Size Limit

Recently we have been running some Microsoft Graph API queries and were not getting back all the results expected.

Microsoft Graph seems to have a limit of 1000 results for signin logs, when the limit is reached graph will then start paging the result and adding them to @odata.nextLink property.

There is a Microsoft doc on paging in Graph.

Paging Microsoft Graph data in your app – Microsoft Graph | Microsoft Docs

There are different limits depending on the API.

Below is an extract from the paging doc.

Paging behavior varies across different Microsoft Graph APIs. Consider the following when working with paged data:

  • Different APIs might have different default and maximum page sizes.
  • Different APIs might behave differently if you specify a page size (via the $top query parameter) that exceeds the maximum page size for that API. Depending on the API, the requested page size might be ignored, it might default to the maximum page size for that API, or Microsoft Graph might return an error.
  • Not all resources or relationships support paging. For example, queries against directoryRoles do not support paging. This includes reading role objects themselves as well as role members.

The @odata.nextLink then needs to be called to get the addtional results.

When we run a query and the results are under the limit there will be two objects returned

@odata.context and value

If we run a query that goes over the max results limit of 1000 the value object is changed to @odata.nextLink

If we use count on the $Results variable it returns 996 items.

To query the addtional results we need to loop through each page to extract the results.

To loop through the results we can create a new variable with the @odata.nextLink and use while loop to go through the variable to get results from the pages.

When we do this the $results count go up to 1142

Below is the full script to get the addtional results.

$ApplicationID = ""
$TenatDomainName = ""
$AccessSecret = Read-Host "Enter Secret"


$Body = @{    
Grant_Type    = "client_credentials"
Scope         = "https://graph.microsoft.com/.default"
client_Id     = $ApplicationID
Client_Secret = $AccessSecret
} 

$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenatDomainName/oauth2/v2.0/token" `
-Method POST -Body $Body

$token = $ConnectGraph.access_token

$LoginUrl = "https://graph.microsoft.com/v1.0/auditLogs/signIns"
$LoginResults = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Token)" } -Uri $LoginUrl -Method Get

$Results = @()
$Results += $LoginResults.value

$Pages = $LoginResults.'@odata.nextLink'
while($null -ne $Pages) {

Write-Warning "Checking Next page"
$Addtional = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Token)" } -Uri $Pages -Method Get

if ($Pages){
$Pages = $Addtional."@odata.nextLink"
}
$Results += $Addtional.value
}

If using the Microsoft Graph SDK the process is much simpler.

Once connect to using Connect-Mgraph we can then run

Get-MgAuditLogSignIn | 
Select-Object UserDisplayName,UserPrincipalName,IPAddress,AppDisplayName,ResourceDisplayName,ClientAppUsed,CreatedDateTime

The $signins results variable returns the same 996 results as we got with the above invoke-restmethod graph api query.

To get all the addtional results all we need to do is add the -All parameter and this should then return all results.

This shows the two different method to get the larger results from GraphAPI queries.

Azure Application Proxy SSO Integrated Windows Authentication

Today I was setting up Integrated Windows Authentication single sign on for an Azure Application proxy that connects to an internal Apache web application.

We had already configured the application for SSO internally.

Below is the link to the Kerberos SSO for Azure App Proxy

Kerberos-based single sign-on (SSO) in Azure Active Directory with Application Proxy | Microsoft Docs

Prerequisites

Before you get started with single sign-on for IWA applications, make sure your environment is ready with the following settings and configurations:

  • Your apps, like SharePoint Web apps, are set to use Integrated Windows Authentication. For more information, see Enable Support for Kerberos Authentication.
  • All your apps have Service Principal Names.
  • The server running the Connector and the server running the app are domain joined and part of the same domain or trusting domains.
  • The server running the Connector has access to read the TokenGroupsGlobalAndUniversal attribute for users.

First step was to confirm that there was an SPN configured for the Application. Since this is a web application we will use http for the serviceclass.

setspn -Q http/webapp.domain.local

If the SPN isn’t configured use setspn to register.

setspn -A http/webapp.domain.local computername

The next step is to configure the delegation on the Azure application proxy connector server.

Go to the server object in AD, open the properties and go to delegation.

Click add and select the computer or user account that has the SPN that will be used and select the service.

The last step that I had to do was add the server to Windows Authorization Access Group so that the connector could have read access to TokenGroupsGlobalAndUniversal users attribute in AD.

When I didn’t have the server in this group I was getting SPN issues.

Next we need to configure SSO in Azure Enterprise app. Logon to Azure

Azure Active Directory > Enterprise applications > App

Select Single sign-on and Windows Integrated Authentication

Put in the internal SPN that was configured earlier and set the delegated login, Our app uses samaccount name so I used On-premises SAM account name.

Once the above is completed close all open session to Office 365 / Azure AD and re-signed in to the external URL for the application proxy and the application should now signed in using SSO without have put in credentials a second time.

Using Microsoft Graph PowerShell SDK

In a previous post we went over connecting to Microsoft GraphApi using PowerShell and Graph Rest API.

In this post we will be going through using the PowerShell SDK as I am more familiar with this method of connecting as it is similar to the current PowerShell modules uses by Exchange online, Azure AD….. and this will make creating scripts and querying data easier.

First step to use the Graph SDK is to install the PowerShell Module.

Open an admin PowerShell Window and run the below command.

Install-Module Microsoft.Graph

Once the module is installed we can now connect to graph.

I only want to query user information so I will use User.Read.All as the scoped permission.

Below is a link to the Microsoft document on graph permissions.

Microsoft Graph permissions reference – Microsoft Graph | Microsoft Docs

Connect-MgGraph -Scopes "User.Read.All"

Go to the URL in the PowerShell response and enter the code.

Accept the permission request.

Once accepted, PowerShell should now be connected.

All command’s in the Graph Module use MG in the name which can be used to find commands needed.

To get all users we can use Get-mguser.

By default the Graph SDK will use API v1.0 to change to the beta version which has more information and is the default one that I use.

To set the profile run the below.

Select-MgProfile -Name "beta"

Now if we look at the user type it now returns guest or member value since the change to the beta version.

This image has an empty alt attribute; its file name is image-33.png

We can also use filters to only return required users, the below will only return guest users.

Using connect-msgraph with a user account requires manual steps to connect so it’s not great for automation.

We can use a certificate and app registration to automate the connection.

Use app-only authentication with the Microsoft Graph PowerShell SDK – Microsoft Graph | Microsoft Docs

We covered the app registration in a previous post so we wont go over creating the app registration again.

First step is to create the cert that will be used, we will be using self signed cert but you can use a cert issue from an internal CA also.

To create the self signed cert I used the below command

New-SelfSignedCertificate -DnsName TennatDomainName -CertStoreLocation "Cert:\CurrentUser\My" -FriendlyName "Graph_SDK"

Once the cert has been created, export the cert so that it can be uploaded to the App registration.

Get-ChildItem Cert:\CurrentUser\my\CertThumbprint | Export-Certificate -FilePath C:\temp\Graph_SDK_Cert_Test.cer

Logon to Azure portal > Azure Active Directory > App registrations > graph app registration

Select the exported certificate

Once uploaded the cert detail will show under certificates.

Now that the cert is uploaded we can use either the thumbprint or the certificate name, ApplicationID and TenantID to automate connections to Microsoft Graph.

Connect-MgGraph -CertificateThumbprint Thumbprint -ClientID YOUR_APP_ID -TenantId YOUR_TENANT_ID

I used the below to automate checking for Guest users and there sign-in logs.

$Cert = "Thumbprint"
$AppID = "YOUR_APP_ID "
$TenantID = "YOUR_TENANT_ID"

Connect-MgGraph -CertificateThumbprint $Cert -ClientId $AppID -TenantId  $TenantID

$GuestUsers = Get-MgUser -Filter "usertype eq 'Guest'"

foreach ($Guest in $GuestUsers) {
Write-Warning "Checking Guest User $($Guest.DisplayName) SignIn Logs"
Get-MgAuditLogSignIn -Filter "UserId  eq '$($Guest.ID)'" | 
Select-Object UserDisplayName,UserPrincipalName,IPAddress,AppDisplayName,ResourceDisplayName,ClientAppUsed
}

Checking Sign-in logs in Azure AD using Microsoft Graph API

In a previous post we went through configuring and connecting to Microsoft Graph API.

In this post we will going through querying sign-in logs.

Connecting to Microsoft GraphAPI Using PowerShell – TheSleepyAdmins

We have been trying to audit guest account activity and sign-in logs are the only way I have been able to find if these account’s have been active for the last 30 days. Instead of manually filtering sign-in logs from Azure AD I want to automate this using Graph.

To query sign-in logs the below API permission are required. since we are using client secret we only require Application permission.

Below is the link to the Microsoft doc I used for getting info on listing sign-ins.

List signIns – Microsoft Graph v1.0 | Microsoft Docs

Permission typePermissions (from least to most privileged)
Delegated (work or school account)AuditLog.Read.All and Directory.Read.All
Delegated (personal Microsoft account)Not supported
ApplicationAuditLog.Read.All and Directory.Read.All

Next step was to run the command to get to the access token for connecting to Microsoft Graph this is covered in the previous post so we won’t be going over that here.

To connect to the sign-in Graph use the below Url

https://graph.microsoft.com/v1.0/auditLogs/signIns

Below is the command to connect and view all sign-in logs data

$LoginUrl = "https://graph.microsoft.com/v1.0/auditLogs/signIns"
(Invoke-RestMethod -Headers @{Authorization = "Bearer $($token)"} -Uri $LoginUrl -Method Get).value

This will return all the default values for each sign-in log.

This image has an empty alt attribute; its file name is image-58.png

We only wanted to have Displayname,UPN,IP,App used and date the log was created. We also wanted to only have Logs that where created in the last 30 days.

$LoginUrl = "https://graph.microsoft.com/v1.0/auditLogs/signIns"(Invoke-RestMethod -Headers @{Authorization = "Bearer $($token)"} -Uri $LoginUrl -Method Get).value | Select-Object userDisplayName,userPrincipalName,ipAddress,clientAppUsed,createdDateTime | Where-Object {$_.userPrincipalName -notlike "*DomainName.com" -and $_.createdDateTime -gt "2020-09-29"}

Below is the results from the above query.

Now that we have the query, we can either run the query manually or in my case I will be setting up an script to run on a scheduled to export this data.

Connecting to Microsoft GraphAPI Using PowerShell

Recently I have been looking to use Microsoft Graph to query specific information for Microsoft 365 services.

Microsoft Graph is an development tool that connects to multiple Microsoft 365 services to allow querying data and automate tasks.

There are a few steps required to start using Graph which involves creating a app registration on Azure to issue authentication tokens and API permission to view data.

Use the Microsoft Graph API – Microsoft Graph | Microsoft Docs

I also used a blog post by AlexAsplund on adamtheautomator as this was very good at explaining the process and goes more in depth.

Using the Microsoft Graph API with PowerShell (adamtheautomator.com)

In this post we will be going through configuring the app registration and query some data from Azure AD.

First step is to logon to the Azure portal > Azure AD > App registration and click on New registration.

Give the app a name and specify the support account type in this case we only want account from our tenant.

Once completed, we should now see the app has been created.

Next step we need to configure the API permissions, depending on the type of access required we will use either delegated or application permission as some data can only be access by either permission types.

below is a extract from the Microsft Docs on permission types

Microsoft identity platform developer glossary | Microsoft Docs

permissions

client application gains access to a resource server by declaring permission requests. Two types are available:

  • “Delegated” permissions, which specify scope-based access using delegated authorization from the signed-in resource owner, are presented to the resource at run-time as “scp” claims in the client’s access token.
  • “Application” permissions, which specify role-based access using the client application’s credentials/identity, are presented to the resource at run-time as “roles” claims in the client’s access token.

To assign permission go to the app registration we created earlier and go to API permissions > Add a permission and select Microsoft Graph.

To check which permissions are required I used the below Microsoft Docs .

Microsoft Graph permissions reference – Microsoft Graph | Microsoft Docs

Select the permission type and the required permission in this case I want to be able to read groups, users and directory so.

Once the required permissions are added if they required admin permission those will need to be granted using the grant admin consent option below.

There are many different way’s to connect to Microsoft Graph but in this post we will be using client secret.

We will need the application ID

We will create a client secret

Give the client secret a name and set the expire in this case we will use 1 year.

There should now be client secret and the value is used to authenticate. (Take note of the value and save in secure location like a password vault or Azure Key vault as once you leave the app blade the value will be hidden and if you lose, it will have to be recreated.)

Once we have the above configured we can connect to GraphApi to generate a token. We will used Invoke-RestMethod.

The secret can be hardcoded but I decided to use read-host so that I could add the secret manually, as it’s not recommend to have any password/secret hardcoded in script.

Below is the command I used to get the token.

$ApplicationID = ""
$TenatDomainName = ""
$AccessSecret = Read-Host "Enter Secret"


$Body = @{    
Grant_Type    = "client_credentials"
Scope         = "https://graph.microsoft.com/.default"
client_Id     = $ApplicationID
Client_Secret = $AccessSecret


$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenatDomainName/oauth2/v2.0/token" `
-Method POST -Body $Body

$token = $ConnectGraph.access_token

To verify we have a token run the variable $ConnectGraph to view.

Now that we have a token we can run a queries against GraphAPI.

Below we will be running a query for Azure AD groups and selecting display name.

$GrapGroupUrl = 'https://graph.microsoft.com/v1.0/Groups/'
(Invoke-RestMethod -Headers @{Authorization = "Bearer $($token)"} -Uri $GrapGroupUrl -Method Get).value.displayName

To view some examples we can use Graph Explorer.

Graph Explorer – Microsoft Graph

In a future post we will be going through more query’s and automating tasks using GraphAPI.

Create Azure conditional access policy with named location

In this post we will be going through creating an Azure conditional access policy to restrict logging on to Azure / Office 365 from specific locations.

Conditional access policies are used to set requirements for accessing Azure or Office 365 resource, when using Named locations we can then set based on IP range, Trusted locations or Countries and regions.

Below diagram is from Microsoft on how conditionals access works.

What is Conditional Access in Azure Active Directory? | Microsoft Docs

Conceptual Conditional Access process flow

First step is to logon to Azure and go to Azure AD conditional access

Create a named location that will be used to restrict access.

Once in named location we can either create a location based on IP range or countries / regions. In this case we will be using a country.

Next we will create the conditional policy

Give the policy a name, we will be using a group to apply the policy but this could be change to all users or by directory role. (We can use select users or groups to apply the policy to a specific group as if applied to all users there could be a risk of locking yourself out of Azure portal)

Next we can apply the policy to specific apps or all apps. (If applying to all apps there will be a warning to not lock yourself out)

Next we set the conditions in this case we will be using location, I will be applying the policy to any location.

We can then set the named location as excluded in the policy so that it wont be applied if the access is coming from a country that is on the allowed named location.

This image has an empty alt attribute; its file name is image-26.png

Next we can set the access control settings, in this case we will block access but this could be changed to require MFA or other settings below.

Last step is to set session options to use conditional access app control, force sign-in frequency, Persistent browser session. We wont be setting any of the session settings as this policy is to block access.

There are three options report-only, on or off. To test the policy and check what will be blocked without running the risk of blocking real users set to report-only (This would be recommend for testing policy before rolling out to all users.)

Click create and the policy should now show and the state should be report-only.

To test if the policy is going to be applied we can check a users sign-ins, click on a signing log and go to Report-only, click on the three dots and show details.

This will show what part of the policy has been satisfied and not satisfied. Since the location has not been satisfied (as we are connecting from a excluded location) and the policy is not applied.

This image has an empty alt attribute; its file name is image-31.png

When the users tries to access from a country that is not in the allowed location, the result will be a failure and the users would be blocked from accessing.

Once testing has been completed and there are no unexpected blocks we can then go back to the conditional access policy and change the state to on, to apply the policy to users.

Now when a restricted user try’s to access an Azure / Office 365 resource from country not in the named location they will receive a message like the below.

MECM 2002 Cloud Management Gateway Configuration

I have been looking at setting up MECM cloud management gateway (CMG) for a while but haven’t been able to, due to the need for PKI or Azure AD joined.

With the recent release of MECM 2002 this has added a new feature,  that allows token based authentication. I decided to do a test deployment in my lab to see how this would work before deploying to our production environment.

With a CMG we can manage clients that don’t regularly connect back to the cooperate network which has become more of a priority recently.

There is a cost for running the VM’s in Azure that will be used as the CMG and for outbound data transfers. Johan Arwidmark has done a good real world cost estimates for a CMG.

https://deploymentresearch.com/real-world-costs-for-using-a-cloud-management-gateway-cmg-with-configmgr/

First step should be to have a read of the docs for planning a CMG

https://docs.microsoft.com/en-us/mem/configmgr/core/clients/manage/cmg/plan-cloud-management-gateway

To use token base authentication require MECM 2002, so that is a pre-requisites for deploying a CMG in this way.

https://docs.microsoft.com/en-us/mem/configmgr/core/clients/deploy/deploy-clients-cmg-token

There will be some required permission in Azure also for deploying the CMG.

  • Account that has Global Admin and Subscription Owner roles.
  • Content filter rules to allow outbound access (If there is a proxy or Firewall filtering traffic)

There will also be a requirement for a cert to be applied to the CMG, it is  recommend to have a third party cert as it should automatically trusted by clients.

From looking through the documents below are the required URL https://docs.microsoft.com/en-us/mem/configmgr/core/plan-design/network/internet-endpoints#cmg-connection-point

*.cloudapp.net

*.blob.core.windows.net

login.microsoftonline.com

Once all pre-requisites have been confirmed we can start to configure the CMG. We will need to pick a unique cloud service name as this will be required later, easiest way to check if the name you have select is unique is to logon to Azure go to cloud services (classic)

CloudService

Once the cloud service has been checked,  then we need to configure the Azure services.

Logon to the MECM console and go to Administration > Cloud services > Azure services.

Click configure Azure servicesCMG1

Give the service a name and select cloud management CMG2

We need to configure a server and client applications CMG5Give the applications a name and sign in to Azure using a account with the required permission CMG3CMG4I just left user discovery enabled. CMG6Click next to finish configuring the Azure services. CMG7Once finished the Azure service should now be showing CMG8The Azure AD tenant should also show with both application we just created. CMG9

 

Once this has all been configured we can now start to setup the CMG.

To start the configuration go to Administration > Cloud services > Cloud Management Gateway

Click Create Cloud Management GatewayCMG10

Select AzurePublicCloud and sign in. (If the subscription ID doesn’t show it might be the account you are using is not an owner of the subscription.)CMG11

Now we need to configure the cloud services, this is where we will use the name we checked earlier.

  • Select the cert file, this needs to be a PFX with the private key (I am using one created on my internal CA but in production I will be using a third party CA like digicert or godaddy)
  • The cert name will be automatically set the deployment services name so this is why we should confirm the name before hand so we can generate the cert with the same name.
  • Select the region the CMG will be configured in
  • Either select a existing or create a new resource group (I chose new one to keep the CMG separate from my other Azure resources)
  • Select the required amount of VM’s this can go up to 16 (for high availability it recommend to configure 2 VM’s at least)
  • Tick the required security authentication I just ticked Enforce TLS 1.2
  • I also ticked using CMG and cloud distribution point

CMG12I left the alerting as default CMG13Just follow the wizard to complete. CMG15

Once completed the CMG should show as provisioning started 

This slideshow requires JavaScript.

We can also logon to Azure to verify the cloud service has been created. CMG18

After the CMG has been configured we then need to install the Cloud management connection point to connect MECM to the CMG.

Go to Administration > site configuration > servers and site system roles, Add the Cloud management gateway connection point to the primary site server in MECM

This slideshow requires JavaScript.

After the role has been configured we need to configure a few steps on the site server, management point and software update point (if installed and configured)

Open the management point properties and tick the allow configuration manager cloud management gateway traffic. (If the tick box for is greyed out there is an additional step required.) 

Go to Administration > site configuration > sites, then configure the primary site to use configuration manager generated certificate in communication security. Once this is done go back to the management point and the tick box should now be available.

CMG27

CMG23CMG24To allow the software update point to communicate with the CMG, tick the allow configuration manager cloud management gateway traffic. CMG26After this has been configured the clients should now pick up a the CMG as a internet based management point in the network tab of client agent properties. CMG25

Once the client moves off the internal network and does a location lookup we should see that the connection type will change to internet from internal. CMG29

We can also check the location services log to see if the CMG is being picked up. CMG28

Connect Windows Admin Center to Azure

In this post we will be going through connecting Windows Admin Center to Azure to allow management of Azure VM’s. To install WAC see previous post.

The Azure integration allows the management of Azure and on-prem servers from a single console.

First step is to register WAC with Azure, Open the WAC admin console and go to settings tab. AZ1

Go to the Azure in the  gateway settingsAZ2Copy the code and click on the enter code hyperlink and enter the codeAZ3AZ4

Sign-in using an admin account on the Azure tenant. AZ5AZ6

Now go back to WAC and click connect to finish the registration AZ7

Once WAC is registered it require admin application permission to be granted to the application registration in Azure AZ8

Now that the registration is completed we can now add Azure VM’s to WAC go to add and select Azure VMAZ9

Select the subscription (if there are multiple subscription in your tenant),  resource group  and VM that will be added. AZ10

Once the Azure VM is added, to allow management there will need to be management ports opened to allow a connection between WAC and the Azure VM. If you are using a site to site VPN you can just allow the ports over the VPN connection.

I have a public IP associated with my VM and I will be modifying my network security group to allow the ports from my public IP.

I wont be going through configuring an NSG as this was covered in a previous post. AZ15

On the VM itself you need to enable winrm and allow port 5985 through the windows firewall if enabled. This can be done by running the two command below from an admin PowerShell session.

winrm quickconfig
Set-NetFirewallRule -Name WINRM-HTTP-In-TCP-PUBLIC -RemoteAddress Any

Once the NSG is configured we should then be able to connect to the VM. AZ12

Below shows the overview of the VMAZ14We can also now connect to the VM using integrated RDP console in WACAZ13

WAC also allows us to manage services, scheduled tasks, backups, check event logs and other admin task, along with connecting using remote PowerShell directly from WAC.AZ16