Integrate Microsoft Intune with ServiceNow CMDB through Graph API

When it comes to populating your CMDB in ServiceNow with managed devices from Intune, you do not have too many options at the time. An official integration/app from ServiceNow is still missing. That is why you might end up doing this one yourself.

I would like shed some light upon one of the options you have, integrating through the Microsoft Graph API. Although the Graph API is a great API with many possibilities, it is rather difficult to find a good automated solution available in the documentation.

The solution we would like to implement, is a regularly import of devices from Microsoft Intune and place them as CIs in the CMDB. To list Intune devices from the API the following method seems like a good option:

List managedDevices

To use this method, the documentation state that we will need to use Delegated (work or school account) permission type with either DeviceManagementManagedDevices.ReadWrite.All or DeviceManagementManagedDevices.Read.All permission. Application access is not supported.
This means that we would have to authenticate with a user account each time we access the API. As we often would like this to be fully automated, it sounds like a bad idea to use Delegated permissions.

Luckily, the documentation is not completely updated. Microsoft is currently working on making more of the Intune API available for application access / service principal. The method List managedDevices is actually currently available on application access even though the documentation does not state this.

Take a closer look at this Microsoft Intune User Voice request and the communication from Microsoft to achieve some insight on the last feedback I have seen from Microsoft on this subject officially.

Intune Graph API should be accessible non-interactively

Continue by setting up the integration by connecting to Microsoft Graph API, follow the documentation provided.

Microsoft Graph – Get access without a user

  1. Register the app in Azure AD
  2. Configure Application permissions through Graph API: DeviceManagementManagedDevices.Read.All
  3. Make sure the app has administrator consent in Azure AD
  4. Register the app in ServiceNow Application Registry as an OAuth Provider
    1. Use Client ID and Secret provided from Azure AD Application.
    2. Default Grant Type: Client Credentials
    3. Authorization URL:
    4. Token URL:
    5. Redirect URL:
    6. Define OAuth scope: DeviceManagementManagedDevices.Read.All
  5. Next you can go ahead and request token.
  6. Finally use the token to call the API.

Local Folder Not exist – OneDrive Migration

So I have been playing around with the SharePoint Migration Tool trying to perform a OneDrive for Business migration from a local file server. During the setup of the migration in the SharePoint Migration tool, I got some errors which stated Line#1, Local Folder Not exist… for all the different lines:
Local Folder Not exist

In my case, It seemed like the path I placed in the CSV file, didn’t work for the SharePoint Migration Tool. Instead of setting the path like this:


I had to change it to include the disk name “C$”, like this:


I spoke to representatives from Microsoft about this, we didn’t conclude but they believed it to be caused by the dollar sign in the shared folder “HOME”.
Although it don’t seem too logical that the dollar signed used in the shared drive should work, when the shared folder doesn’t.

Set primary SMTP as targetAddress with PowerShell

This will show you how to step forward if you would like to set the targetAddress for all users within an Active Directory OU, to the primary SMTP address from the proxyAddresses attribute.

STEP 1: Update the script with the right OU, something like:

Get-ADUser -SearchBase "OU=Europe,CN=Users,DC=corp,DC=contoso,DC=com" 

STEP 2: Start PowerShell as an Admin on the local network with access to the local Active Directory. Import the ActiveDirectory module and run the script.

Import-Module ActiveDirectory

(You might have to update execution policy!)

//xostmoen – Alexander Østmoen

# xostmoen

# This script get all users in AD from a specified OU and all sub-OU's
# It also fetches the ProxyAddresses from the object

Get-ADUser -SearchBase "OU" -Filter * -Properties ProxyAddresses | foreach {

$proxyAddress = $_ | Select -ExpandProperty ProxyAddresses | ? {$_ -clike "SMTP:*"}

#For each user, we find the primary SMTP address, and set this to be the new targetAddress

Set-ADuser $_ -Add @{targetAddress="$proxyAddress"}


Calendar Sharing – Cross Tenant

So, I have successfully enabled Free/Busy Calendar Sharing across tenants between two organizations, but why are the users still not able to open up each others calendar?

The boring answer to this question is that you probably misunderstood how Free/Busy Calendar Sharing actually work.

Many users will try to open the calendar of other users by adding it to the list of their existing calendars in Outlook. Unfortunately this is NOT the functionality that comes with Free/Busy Calendar Sharing.
So when trying to add the calendar of a user from another Exchange organization, you will probably see something like this error message:

Couldn't open calendar

Couldn’t open calendar
“The calendar for the mailbox you chose can’t be opened. You may not have permission to open this calendar.”

What permission am I missing here? What is the permission that Free/Busy Calendar Sharing does not provide for us?

The answer is the correct MailboxFolderPermission set for the Calendar, like in this example:


In this example, user AllanD from the organization M365B502168 has shared his calendar with user AdeleV from organization EMS840558. The user did this himself, “manually”.

As we can see, the user get the prefix ExchangePublishedUser, as it is not an internal user in the organization, but exist on another tenant. Now, the only way to setup this permission, is by the user choosing to share the calendar with an external user themselves. It is NOT possible to set this permission as an admin. If we try to set this up on another user by using:

Add-MailboxFolderPermission -Identity\calendar -User -AccessRights Reviewer

(Even without the prefix ExchangePublishedUser)
You will get an error message:


So logically the Free/Busy setup does not configure any MailboxFolderPermission for external users.

The statement I’ve got from Microsoft as of why it is like this, it that its not designed to work this way with Free/Busy, so they recommended to instruct the users on how to use the Free/Busy functionality as it is by design or to work out a workaround.
Since I still have left to come up with a good workaround, I would suggest that users receive training on how to:

  1. Use the Scheduling Assistant
  2. Share their calendar themselves

//xostmoen – Alexander Østmoen

Mandatory TLS in Exchange Online with PowerShell

This is the scenario, you want to enable forced TLS on all messages you send through Office 365 / Exchange Online with a partner Organization.
The quickest way to do this, is by PowerShell.

First, you create a new inbound connector.

New-InboundConnector -Name "Contoso Inbound Connector" -SenderDomains * -RequireTls $true

Second, you create a new outbound connector.

New-OutboundConnector -Name "Contoso Outbound Connector" -RecipientDomains * -TlsSettings CertificateValidation

This enables all the settings you need in Office 365 for requiring only use of TLS on all email messages between your organization and your partner organization.

Of course, the partner organization also need to set up this in their environment as well.

Important to note, it will take some time before this actually is activated in Office 365 after you have created the connectors. From my own experience, it will be working within 15 minutes.

You can test the setup by using tools from this webpage:

//xostmoen – Alexander Østmoen

450 4.7.320 Certificate validation failed

I wanted to share something peculiar that happened while working with a customer the other day.
We had finished a hybrid setup with Exchange 2013, and most of the users where still on-premise. The minute we switched the mail flow to go through Exchange Online Protection instead of their old setup, we started having some challenges. Even though we didn’t experience any challenges when we did the testing of the mail flow on beforehand.

Now some of the messages took forever to go through Office 365 and Exchange Online Protection, but some went through straight away.

When tracing the messages, we could see this error message on the deferred messages:

Reason: [{LED=450 4.7.320 Certificate validation failed [Message=SubjectMismatch] [] [LastAttemptedIP=] []};{MSG=SubjectMismatch};{};{IP=};{LRT=11/1/2017 12:12:45 PM}]. OutboundProxyTargetIP: OutboundProxyTargetHostName:

The strange thing in this case, was that some messages seemed to be OK, but the other half seemed to have a problem with the certificate.

After some time it came to me that the receiver connector on the on-premises Exchange server contained some settings for the certificate for “”, and this is something that is automatically configured by the Hybrid Configuration Wizard:

Set-ReceiveConnector -Identity 'SERVERNAME\Default Frontend SERVERNAME' -TLSCertificateName [CERTNAME] -TLSDomainCapabilities [CERTDOMAINCAP]

Then I came to the discovery; only one of the two Exchange servers with a receiver connector had been configured with the TLS Certificate settings.

By using PowerShell:

Get-ReceiveConnector -Identity 'SERVERNAME\Default Frontend SERVERNAME' |fl

I could see that the attributes TlsCertificationName and TlsDomainCapabilities where set for one of the servers, but not the other.

“Easy!” – you say,  “then we just need to run it for the other one as well? ”
Of course, the only thing to remember is to get the correct Certificate Name, and then run the Set-Receiveconnector cmdlet.

First i had to find the Thumbprint of the Certificate by running:


Take note of the Thumbprint for the right certificate, then go on…

$certificate = Get-ExchangeCertificate -Thumbprint 0011223344556677889900112233445566778899
$tlscertificatename = "<i>$<$certificate.Issuer><s>$<$certificate.Subject>"
Set-ReceiveConnector -Identity 'SERVERNAME\Default Frontend SERVERNAME' -TLSCertificateName $tlscertificatename -TLSDomainCapabilities

Now after running this, and checking that everything is right with the Get-ReceiveConnector cmdlet, things started working as it should again.

//xostmoen – Alexander Østmoen