Author Archives: Andreas Lindahl

New module EasyGraph for accessing Microsoft Graph from PowerShell

Microsoft Graph has been an increasingly important tool when working with automation tasks. With its many APIs, Graph has become a gem in the automation toolbox, with one single interface to interact with all sort of data.

To simplify access to Microsoft Graph, I have written a PowerShell module, EasyGraph. The module provides a simple way of connecting and querying Microsoft Graph, in a similar way as for example the AzureAD module. The module works cross-platform and the source code is available on GitHub. It is installed directly from PowerShell Gallery:

Install-Module -Name EasyGraph

The EasyGraph module allows several different types of authentication, both interactive and silent, purposed for automation and background jobs.

  • Certificate based authentication with thumbprint (Windows only)
  • Certificate based authentication with Pfx file
  • Username and password (Windows only)
  • Client credentials
  • Device Code

You also need to register an application in the Azure portal in order to use the module.  In the application you also have to delegate the permissions needed for your script.

Detailed information about the module is available in the EasyGraph repository on GitHub. Below is a simple example on how we for example could update some user attributes of all users in AzureAD.

# Load the module
Import-Module -Name EasyGraph

# We need the ClientId/AppId from the App you created in AzureAD
$MyApp = 'a72b9508-6cbc-4117-b6d7-ff69cf248290'

# Connect using the username+password method
Connect-EasyGraph -AppId $MyApp

# Define whe attributes we want to update
$NewAttributes = @{
    city       = 'Stockholm'
    postalCode = '11130'
}

# Get all users and loop through them
Invoke-EasyGraphRequest -Resource '/users' | Foreach-Object {
    # For each user, get the id ($_.id) and call Graph to set the new attributes
    Invoke-EasyGraphRequest -Resource "/users/$($_.id)" -Method PATCH -Body $NewAttributes
}

# All done, disconnect
Disconnect-EasyGraph

With this simple example it is now up to you to come up with the next big thing, that unleash the power of Microsoft Graph. Happy coding!

/ Andreas

Advertisement

Unable to Connect to Skype for Business using old BPOS account

Recently I had to make a change in the Skype for Business Online environment of a customer. When I was trying to connect with Remote PowerShell I got an error message saying that it was “Unable to query AutoDiscover URL”.

lyncdiscover_missing

It turned out that this customer was once using BPOS, and the domain used at that time was tenant.emea.microsoftonline.com. This domain is not supported to use with Skype for Business, since important DNS records are missing.

Luckily there are two solutions for this problem:

Solution 1

Connect using the -OverrideAdminDomain option, as described in KB2909536.

$cssession = New-CsOnlineSession `
        –Credentials $cred `
        –OverrideAdminDomain 'tenant.onmicrosoft.com'

This will force the cmdlet to look for DNS records at the tenant.onmicrosoft.com domain

Solution 2

This solution requires you to change the user name of the admin account to a supported domain (or create a new account). Renaming accounts can be tricky, but it is worth the job, since the emea.microsoftonline.com domain support is deprecated.

Result

By using a new admin account I was able to connect.

lyncdiscover_working

/ Andreas

Export legacyExchangeDN from Global Address List in Outlook

In some migration scenarios it is necessary to export all legacyExchangeDN addresses from your Exchange environment. This is for example the case if you are doing a mail migration with .pst files. If you are migrating from a Hosted Exchange environment this information can sometimes be hard to get. However, there are solutions.

It is quite easy to export all legacyExchangeDN addresses from the Global Address List using Access and Outlook on a client that is connected to the Exchange environment.

Start by opening Access and create a new empty database.
On the External Data tab select Outlook Folder

legacydn-access_1

In the Import Guide select to import data into a new table, and click OK

legacydn-access_2

Select your Outlook profile

legacydn-access_3

Now select the address list to export from, in this case I select the Global Address List to get all addresses.

legacydn-access_4

In the next step it is possible to adjust the data, just click Finish.

legacydn-access_5

Now we’re done! A new table has been added to the database, and in the E-mail address column you will see the legacyExchangeDN for all users

legacydn-access_6

Now it is easy to add these addresses as a x500 alias addresses in your migrated mailboxes.

/ Andreas

Back to Basics: Creating new users in an Exchange Hybrid Deployment

Some of the most common questions I get from my clients are related to how to create new users in an Exchange Hybrid environment. I have seen users set up in an incorrect way in most Hybrid Environments. Some common problems resulting from this include missing Autodiscover functionality or bouncing emails from external users. The reason for these kind of problems is that your on-premises Exchange server doesn’t recognize the Exchange Online mailbox.

The best way of creating new users during the Hybrid is to use the New Remote Mailbox guide in Exchange Management Console (this can of course also be done in an on-premises Exchange 2013 server, the principle is the same). This will create both the AD account, and populate all necessary attributes for Office 365. It will also enable you to continue using Exchange Management Console for managing all Exchange attributes.

The key is to use the Mail Contact pane in Exchange Management Console. Start by right-clicking and select the New Remote Mailbox guide.

remotemailbox1

Select the type of mailbox you are creating, normally a User Mailbox.

remotemailbox2

Fill in all the information that you would normally fill in when creating a new AD user.

remotemailbox3

If you are not using Archive Mailboxes just click Next.

remotemailbox4

Review the summary and click New.

remotemailbox5

All done! Close the guide by clicking Finish.

remotemailbox6

If we right-click on our new user and check the Email Addresses tab, we will see that it is already populated with all addresses according to our E-mail Address Policy. We even have a Routing E-mail Address set, pointing to our Office 365 tenant.

remotemailbox7

This means that we are all set, our on-premises Exchange server is now aware of the Mailbox in Office 365! The final step is to wait for DirSync (or force a sync) then assign a license to the user.

/ Andreas

Exchange Online: Adding a secondary e-mail domain to all users

I thought that I would share with you a simple script that will add an email domain to your users. This script is handy if you for example would like to add contoso.info to your already existing contoso.com environment. If you are using the email address aaron@contoso.com you want the script to automatically add aaron@contoso.info.

Please note that the domain name that you are adding first has to be added and verified in your Office 365 tenant.

DirSync version (modifying Active Directory using ADSI):

$activeDomain = New-Object DirectoryServices.DirectoryEntry
$domain = $activeDomain.distinguishedName
$searcher = [System.DirectoryServices.DirectorySearcher]"[adsi]LDAP://$domain"
$searcher.filter = '(proxyaddresses=*@contoso.com*)'
$result = $searcher.findall()
$users = $result.Path

$users | ForEach-Object {
    $user = [adsi]"$_"
    $proxyaddresses = $user.proxyaddresses.Value | Where-Object { $_ -like 'smtp:*@contoso.com' }
    foreach ($proxyaddress in $proxyaddresses) {
        $newaddress = ($proxyaddress.split ':')[1] -replace '@contoso.com', '@contoso.info'
        $user.proxyaddresses.add("smtp:$newaddress")
    }
    $user.setinfo()
}

Cloud version:

$cred = Get-Credential -Message 'Please enter your Office 365 admin crendentials'
$O365 = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://outlook.office365.com/powershell-liveid/' -Credential $cred -Authentication Basic -AllowRedirection 
$importcmd = Import-PSSession $O365 -CommandName @('Get-Mailbox','Set-Mailbox') -AllowClobber

Get-Mailbox -ResultSize Unlimited -Filter { EmailAddresses -like '*@contoso.com' } | Select-Object Identity,EmailAddresses | ForEach-Object {
    $proxyaddresses = $_.EmailAddresses | Where-Object { $_ -like 'smtp:*@contoso.com' }
    foreach ($proxyaddress in $proxyaddresses) {
        $newaddress = ($proxyaddress -split ':')[1] -replace '@contoso.com','@contoso.info'
        Set-Mailbox -Identity $_.Identity -EmailAddresses @{Add="smtp:$newaddress"}    
    }
}

/ Andreas

Updating Windows Management Framework breaking DirSync: “Invalid namespace”

Disclaimer
This blog post was written for an older version of the Azure AD Connect Synchronization Service, and has not been tested in the latest version. Always make sure that you have a valid backup before making any changes to your system.

After updating Windows Management Framework you might get an error message in the Event Viewer, “Invalid namespace”. The symptoms includes stopped scheduled synchronizations, and event 0 logged in the Event Viewer when trying to run the synchronization manually.

dirsync-event-0

The problem has to do with the WMI Performance Counters being updated when updating Windows Management Framework.

SOLUTION
The solution is to rebuild and recompile the MOF files used for the Performance Counters.

First, open a command prompt and change directory to %Program Files%\Windows Azure Active Directory Sync\SYNCBUS\Synchronization Service\Bin

 cd "%Program Files%\Windows Azure Active Directory Sync\SYNCBUS\Synchronization Service\Bin"

Open mmswmi.mof in Notepad.exe, and add the following text at the top in the file

#PRAGMA AUTORECOVER

Load the modified MOF file into the WMI repository by running the following command:

mofcomp mmswmi.mof

mofcomp

Register the Microsoft Identity Integration Server dll

regsvr32 /s mmswmi.dll

Restart Windows Management Instrumentation

net stop winmgmt
net start winmgmt

Re-run the DirSync Configuration Wizard, by running %Program Files%\Windows Azure Active Directory Sync\ConfigWizard.exe

Check the Event Viewer again and make sure that the Syncroniation was successful!

/ Andreas

Exchange Online: “This user’s on-premises mailbox hasn’t been migrated to Exchange Online”

Disclaimer
This blog post is intended for new deployment scenarios, where no mailboxes exist in Office 365. It is written for an old version of DirSync. Since then newer versions has been released with built in functionality to filter what attributes to sync. Always make sure that you have a valid backup before making any changes to existing environments.

Normally you would use the build-in tools to migrate a mailbox from your on-prem environment to Exchange Online. In some scenarios the built-in tools cannot be used, and then you have to be able to create the cloud mailbox while the on-prem mailbox is still available. The problem is that when you assign a license to the cloud user you get a warning that “The user’s on-premises mailbox hasn’t been migrated” and the new mailbox will not be created.

warning_onprem_mailbox

If you are using DirSync and your on-prem Exchange environment is not published to the internet according to best practice you may consider using third party migration tools instead of the built in tools to move your mailboxes to Office 365. This is one example of a scenario where you would encounter this warning message.

To solve this problem we have to exclude attributes from being synced in DirSync. The solution is very similar to a problem with Lync that we described a while ago, and I will use the same solution here. The idea is to exclude the msExchMailboxGuid attribute from DirSync.

Start the Synchronization Service Manager (miisclient.exe) on the DirSync server. In the “Management agents” pane, select properties on the Active Directory connector.

2014-04-06 22-41-04

In the management agent designer, select “Configure attribute flow” and remove the msExchMailboxGuid for both the User and inetOrgPerson Data Source from the attribute flow as below.

2014-04-06 22-44-06

msExchExchangeGuid

Finally we have to delete the Active Directory Connector Space.

2014-04-06 21-42-25

2014-04-06 22-46-58

2014-04-06 22-47-25

2014-04-06 22-47-48

After the connector space has been deleted, run a Full DirSync again, wait a few minutes and now you will be able to create mailboxes by assigning an Exchange Online license.

Happy provisioning!

/ Andreas

Creating a Catch-all Mailbox using Transport Rules

There are as many reasons to use catch-all mailboxes as there are against, and of course spam is one of the biggest concern. Nevertheless people are still asking for this feature, and therefore I want to show that it is possible also using Exchange Online in Office 365.

I will achieve this by using Transport Rules to control our mail flow. Transport Rules are a very flexible and powerful solution, yet easy to maintain. We have previously here at 365lab.net written a few posts of Transport Rules, but I still think that they deserve a little more attention.

Now to my demo. After establishing a PowerShell session to Exchange Online the first thing we have to do is to change our domain type to Internal Relay.

$domain = '365lab.net'
Set-AcceptedDomain -Identity $domain -DomainType InternalRelay

Next we need a distribution list that contains all our mailboxes. The idea is to redirect all messages sent to unknown addresses, and this distribution list will contain all known addresses, which mean we have something to use in our Transport Rule. Here I prefer to use a Dynamic Distribution List since they don’t require any maintenance after the initial configuration. Maybe you already have a distribution list that you want to re-use instead. If you want to this distribution list can be hidden from the Global Address List.

New-DynamicDistributionGroup `
	-Name 'Everyone' `
	-PrimarySmtpAddress "everyone@$domain" `
	-IncludedRecipients AllRecipients

Finally we create the Transport Rule that will do the actual redirection of the Mail Flow. In my example I want to redirect all emails to an already existing mailbox, $targetAddress.

$targetAddress = "contact@$domain"
New-TransportRule `
	-Name "Catch-all $domain" `
	-RecipientDomainIs $domain `
	-ExceptIfSentToMemberOf "everyone@$domain" `
	-RedirectMessageTo $targetAddress

All emails sent to the domain $domain is hit by this rule, as specified by the RecipientDomainIs parameter. I am also using the Everyone Distribution List in the ExceptIfSentToMemberOf parameter, so that my rule doesn’t hit existing mailboxes. It would also create a loop if messages addressed to the target mailbox were processed, they would be forwarded to the mailbox itself infinitely.

Now we are all set. All messages sent to non-existent addresses in the domain $domain will now be delivered to the mailbox $targetAddress.

/ Andreas

Troubleshooting TLS in an Exchange Online Hybrid Deployment

One of the prerequisites for having a Hybrid relationship established between your on-prem Exchange environment and Office 365 is to have a functioning mail flow using TLS. The Hybrid Configuration Wizard automatically creates the inbound and outbound connectors required both in your on-prem environment and in Office 365 as a part of the setup, and this is used for secure mail transfer between the two environments.

If TLS fails your mail flow will suddenly stop, and outgoing emails are stuck in the queue with error message 451 4.4.0 Primary target IP address responded with: “451 5.7.3 Must issue a STARTTLS command first.”. You may not even be able to complete the Hybrid Configuration Wizard, you just get an error message stating that Subtask ValidateConfiguration execution failed: Configure Mail Flow.

Several blogs on the Internet addresses these problems, but must of them show you the commands how to turn TLS off. This is not something that I recommend! A problem is not solved by hiding it’s symptoms, always try to find the root cause.

There are several possible reasons for malfunctioning TLS. A good start in the troubleshooting is to use good old telnet.exe and connect to smtp.office365.com on port 25. By simply sending the ehlo command you can easily see if the server is accepting TLS connections. If you get a 250-STARTTLS response the problem is most likely with your certificate. It may not be configured to be used with SMTP, or is longer valid. Also make sure that you have installed the latest Root Certificate Updates from Windows Update.

tls1

A response from the SMTP server without the STARTTLS extension listed might indicate that your IP address is on a blacklist. Use one of the online tools available for free to check the status of your IP address. In your telnet session you will find the IP address you are connecting from.

This IP address must also be in list of Sender IP Addresses in the Hybrid Mail Flow Inbound Connector in Office 365 created by the Hybrid Configuration Wizard. If it isn’t there it must be added. If the IP is incorrect the connector will not be used, and the mail flow will use the MX record instead, without enforcing TLS.

tls2

Another result from your telnet session could be this:

tls3

In this case a firewall is configured to filter some protocols, which effectively stops all TLS communication. In for example Cisco firewalls the solution is to turn off ESMTP inspection.

This is not a complete guide on how to solve your TLS problems, but it shows some common solutions, and hopefully it gives you some input to start your troubleshooting.

/ Andreas