Creating Custom Address Lists with Exchange Online

Holy cow it has been a while since I made a post on here!  Things have been crazy.  Anywho, let’s talk address lists.  So typically when users ask for “folders” in the global address list (GAL), even with Exchange Online, the first thing my brain goes to is public folders (PF).  Now I got thinking, that’s kind of the old school way of doing things, and a particular customer of mine was really not into that idea.  Therefore I did some research came up with a solution using custom address lists!

So custom address lists are just like any of the other predefined address lists that you are used to seeing like the GAL, All Contacts, etc.  They show up as their own separate address list under All address lists, or under the Directory option if you’re using Outlook web app (OWA).  The cool thing is you can set filters on what show up in these address lists based on what’s in your GAL.  For example, if you want just contacts from the state of Arizona to show up in a custom address list you name Arizona Contacts you can totally make that happen.  Better yet, it’ll maintain itself!!!  Follow this link for more information, we’re going to move on to the good stuff.  Since there is no UI option to do this, it must be done using PowerShell as of the time of writing this.

Creating a Custom Address List in Exchange Online

To begin, you must login to Exchange Online and ensure that you have the admin role Address Lists assigned to you.  This admin role is not assigned by default, so you may want to make your own role group and with just the Address Lists role assigned to it and add your members.

Once you have the permissions all sorted out (they can take a while to apply, heads up), start by logging into Exchange Online with PowerShell.

Now that you’re connected, creating a custom address list is a simple one liner.  We’ll run with the contacts from Arizona example I mentioned in the intro.  See the reference material links at the end of this post for more information on how you can filter.

You would think you were done right?  WRONG!  Custom address lists have what I would consider a bug, and Microsoft considers acceptable behavior.  YOu have to follow the steps in this article for the address list to start functioning correctly.

From what I can make of this, there is some sort of modified attribute for each object on the backend that we don’t see and the address lists need that to be more recent than the creation date of the address list.  That is just a guess, don’t hold me to it!

With that you are all done.  Moving forward as you add contacts from Arizona, they will automatically be added to your address list.  Pretty cool!


Reference Material:

Manage Address ListsNew-AddressListSet-AddressListFilterable Properties, Get-Recipient

Add SSO Support for Chrome Browser with ADFS 3

By default, ADFS 3 (Windows Server 2012R2) only supports the seamless Single Sign-on (SSO) that we all expect with Internet Explorer browsers.  Chrome can be enabled though by following these steps:

1.  Login to your on-premises ADFS server and launch PowerShell as administrator.

2.  Run the following command to see the current set of supported browsers:

If you have the default configuration, it will return the following:

3.  Run the following command to add Chrome support to the list:

4.  Confirm your change running the same get command from step 2.  You should have the following output:

5.  Restart the ADFS service to apply changes:

All done!

Create Exchange Online IP Blacklist

You may have gotten the hint over the last few posts that I had some brute force issues from a particular set of IPs (a couple /24’s to be exact).  Well after much heartache I found the solution.  Thinking about it now this is probably a pretty common on-prem Exchange configuration option, but alas I have very little Exchange experience so I’m always just figuring it out as I go.

Start by connecting to Exchange Online:

The cmdlet that we will be working with is the Set-OrganizationConfig cmdlet.  As you can see by going to the Microsoft doc linked, there is a whole lot that you can configure for your tenant with this single cmdlet.  For this particular post though, I just needed to make a blacklist to stop the brute force attempts.  To do so I configured the IPListBlocked option:

If you do not currently have any IPListBlocked, you will not need the “add=” portion, but it doesn’t hurt.  All it does is tell it to append to the current array.  Give it about four hours as the warning you’ll see describes and then you should start seeing the desired result.  As always, review the Microsoft docs for syntax and whatnot before.

Configuring Exchange Online Client Access Rules

Client Access Rules give you a lot of control over who can access Exchange Online from where.  Microsoft gives a pretty good definition so I’ll just throw that at you because I’m lazy:

Client Access Rules help you control access to your Exchange Online organization based on client properties or client access requests. Client Access Rules are like mail flow rules (also known as transport rules) for client connections to your Exchange Online organization. You can prevent clients from connecting to Exchange Online based on their IP address, authentication type, and user property values, and the protocol, application, service, or resource that they’re using to connect.

The most common use case I have seen for this is restricting access to just the corporate/company networks.  While this is cool, you can also use these rules to not allow specific networks as well should have the need, as well as a bunch of other situations.  Use your imagination, these things are pretty cool.

One thing to note is that these do not help with brute force attacks.  The user first authenticates and then Exchange Online will evaluate the Client Access Rules like an ACL, going down the priority list and stopping when it finds a match.  Anyhow, to get them set up we need to start by connecting to Exchange Online.  Open up an administrative PowerShell session and run the following:

Great, now we’re connected to Exchange Online with PowerShell.  First things first, we need to make sure we can always do that.  You will find this plastered all over the Microsoft documentation and any other guides on the interwebs, make your Priority 1 Client Access Rule preserve your access to Exchange Online with PowerShell.  Do this with the follow line:

Just do it.  You don’t wanna be the guy who has to call Microsoft because you locked yourself out of your Exchange Online tenant.

Now you have a lot of options with where you go from here.  Most examples are going to show you how to deny everything accept for X network, I will show you the opposite.  The following will create a rule that will allow any network except for X networks (replace 10 networks with public ranges, or drop the CIDR notation and do particular IP):

You can test this with the following:

And you can modify by:

Like I said earlier, play with the options/settings and use your imagination.  This configuration option isn’t for every org, but it does have a surprising amount of use cases.

In my next post I’ll describe how to handle brute force attacks from malicious IP ranges hitting your AD FS portal.

Connect to Exchange Online

Client Access Rules Information

Client Access Rules Procedures

New-ClientAccessRule Microsoft Doc

Export Licensed Office 365 Users Using PowerShell AzureAD 2.0 Module

I figured it was time to bite the bullet and start converting all of my scripts from using the MSOnline V1 module to the new and shiny AzureAD 2.0 module.  Since I was finding few to no posts on pulling licensed users using the new module out there on the interwebs, I figured I’d share my findings.  You can get the AzureAd module quite easily from the PowerShell gallery by using the command:

Once you have that, you are ready to rock and roll.  The following script will connect to multiple AzureAD tenants, snag all AzureAD users, determine if they have a license assigned to them, and if they do export their UPN to a custom PowerShell object with the property name of Email Address.  I only did this because this is for marketing, and that’s what they wanted (they didn’t want to have to edit the export file at all).  But that’s enough explanation, let’s get to the good stuff.


Loosely based off of some of the examples found in this blog post.

Create a “Dynamic” AD Group using PowerShell

I had a request come to me today for an AD group that will always contain all of the users in a particular OU.  If you have come across my little place on the internet before, you are likely familiar that I do a lot of work with AD FS.  Keeping that in mind, I wanted to make sure only users that were synced with Azure AD/O365 from this OU were added to the group.  Additionally, if that user were no longer synced with Azure AD/O365 I wanted to remove them from the group to keep it tidy.  And thus I came up with the following script that I have run every hour:


Export Licensed User Properties from Multiple Azure AD Tenants

This is a pretty easy one, but it is quite useful.  Usually when I have a need to do this I just need to export FirstName, LastName, and UPN but the properties are really plug and play.  Look up the different properties on the Get-MsolUser Microsoft Doc found here.  This may go without saying, but you could always just run this as a one liner after connecting to your tenant if you don’t have a need for exporting multiple tenants.  I use this mostly for internal stuff, so I want all the users that we manage.  Without further ado:


ADFS User Sign-In Customization

I’m not going to lie to you, like most of my posts this is just a reference for myself but hey maybe one of you stalkers of the interwebs didn’t know how to do this.  Anywho there is a whole bunch of customizations that you can make to the ADFS sign-in page with simple PowerShell one liners, all of which can be found at this page (and its linked pages).  Me, I’m just going to highlight the few that I do.

Change the Company Logo:

Change the Illustration (the wallpaper-like image on the left side):

Customize the Update Password Page Description:

Add Help Desk Link:

There are many other things you can customize by following the link at the beginning of the post, but these are the ones I like to set.  That’s it for this one!

Copy AD User Group Membership to Another User

Had the guy on my service desk that handles all of the user creation come to me recently with this request.  Well when I say recently it was like a month or two ago, but you know how things go.  Anyhow I threw this script together rather quickly to copy the group membership of one AD user to another.  The basic breakdown is I ask for admin creds, prompt for what customer we’re dealing with so I know what DC to point to, specify the source user you want to copy, specify the target user you want to copy to, and finally confirm you’re sure that’s what you wanna do.  Simple!


Automated Windows Updates with PowerShell and PowerCLI

Holy cow it’s been a while!  Real life must be catching up with me or something, I am not sure.  Anywho, I’ve had this issue where I have never felt comfortable automating Windows Updates on my servers in case the worst should happen.  Seems like a reasonable concern right?  Well I finally got over it, did some digging, and found a suitable solution that I am comfortable with.

It really is quite simple.  I hijacked some PowerShell modules from Technet Script Center (found here) and then did some work with the PowerCLI module from VMware to take a snapshot prior to the updates.  Once it is done taking a snapshot of a VM (I pull them from an array) it will begin updates, and restart as needed.  I do not delete the snapshots in an automated fashion at this time, I just check everything is still good when I get in the office in the morning and then remove them all with PowerCLI (assuming there is no issues) as seen below:

Since I said I run this while I’m sleeping, I obviously just have it set up with Task Scheduler running with a service account I created with access to all the necessary servers and my vCenter environment.  Without further ado, I give you what I have coined “UpdateAutoPilot” below: