Time to check your PoSH-connection to Exchange Online

I’ve been using the same action to connect my Powershell-session to Office 365 and Exchange Online for quite some time now. A while ago, I created a function that lives in my ‘all users, all hosts’ Powershell-profile to setup the remoting session to Exchange Online:

As you can see, the function gets the credentials for setting up the session and creates the remoting session to the Exchange Online endpoint.

It turns out I’ve been using the <I>https://ps.outlook.com/powershell</i> endpoint all the time, while the endpoint has changed. So far, this hasn’t been a problem but recently it started acting up. This seems related to the 10525 Windows 10 release, but that could be a coincident. The endpoint should be <I>https://outlook.office365.com/PowerShell-liveId</i>

So I changed the function in my profile:

After this, everything worked like a charm again ūüôā

Lesson learned: when using custom functions to perform regular tasks, be sure to check stuff like this every once in a while to stay up to date with changes in the services.

If you want to connect to all O365 services in one Powershell windows, including SharePoint, Skype for Business and the compliance center, there is a pretty decent write-up on TechNet that you can use a starting point.

Use Powershell to check on external sharing in SP Online

Sharepoint online enables you to share (sub)sites, lists, libraries or files with external user, when the tenant administrator allows this feature.

Using Powershell, you can check the users that have access to a (sub)site. To do so, you’ll need the Sharepoint Online powershell module: https://technet.microsoft.com/en-us/library/fp161362.aspx.
Once, connected, use the connect-sposervice cmdlet to connect to the administrative site of your tenant (https://tenant-admin.sharepoint.com). After that, you can use the get-spoExternalUser cmdlet to retrieve the external users known to the site.

As you can see, you’ll see who invited the external user and the live-id / account used to accept te invitation.

Using cmdlet extensions to automate Exchange

There are some days I actualy feel sorry for my colleagues. Not because we hate our jobs (far from!) or because we have to drink bad coffee while in the office, but because my standard resposne to every request for help seems to be: “Have you tried using Powershell?” ūüėČ

Ever since Windows Server 2012 and Exchange 2013 it’s obvious that Powershell is the way to go: it’s here to stay! The GUI’s for management are stripped down more and more, especialy in Exchange where the GUI has been nothing more than a graphical shell around Powershell for a while now.

However, there still are things that don’t come naturally in Powershell or the EMC. One of those things I ran into a few weeks ago, while setting up Exchange retention policies on an on-prem Exchange server.

The particular costumer was using Exchange 2010 SP3, in combination with a software based anti-spam solution. Ever since they’ve been using this software, all users have gotten used to the ‘spam’ or ‘junk’ folder in Outlook, where the anti-spam software would place suspicious emails. The user then can scan this folder manualy, checking if the mail is indeed a spam message or that a legitimate mail has been marked as spam: a so-called false positive. There is one downside to this way of working: users check the folder, read or move the mail they need and just ignore the rest. The junk folder quickly fills up with bad emails using up storage and backup resources, while they ofcourse just should be deleted.

The solution is relatively simple: retention policies. Just create a retention tag for the junk folder, set it to ‘delete after 30 days’ and create a retention poicy you can apply to all mailboxes.

Applying the policy to all mailboxes is done in a blink, when using PoSH

Easy as that‚Ķ But the policy now only applies to existing mailboxes. Newly created mailboxes won’t get this policy applied automaticly. It’s not possible to set a default policy for all mailboxes in you environment or in a particular database.

No matter if your using EMC or EMS, when creating a mailbox you will have to specify explicitly that you want to apply this policy.

So that’s where the Exchange cmdlet extension agents come in! In this case, the scripting agent.

Exchange comes with several ‘extension agents’, for example to mange the Offline Address Book. The scriptig agent is one of those seven agents and is the only one that is disabled by default.

The agent’s work is fairly simply, but it’s an unknown (or better: relatively unmentioned) part of Exchange. After activating the scripting agent, it will be called every time a cmdlet is run on the server. That goes for cmdlets run directly from the Powershell interface, but for cmdlets run from EMC, Exchange services or Exchange Control Panel too.

When the agent is called, it checks if there are scripts defined for that particular cmdlet. So that’s what we are going to do to make sure our retention policy is applied on all new mailboxes!

First of all, we have to activate the scripting agent. This is simple: in the <installation path>\V14\bin\cmdletextensionagents folder there’s a ScriptingAgentConfig.xml sample. By renaming this to ScriptingAgentConfig.xml we create the config file for the scripting agent. The agent itself, we active through, you guessed it, Powerhsell.

Now we have to make the script do what we want.

First we’ll have a look at the entire script, after that we’ll break it in pieces to see what it does.

The first thing to notice, is that it isn’t an actual script, but it’s XML. The XML-file specifies what script to run in what situation. Because of this setup, it’s easy to have multiple actions in one config file.

The first ‘real’ lines after opening the XML-file call the action on creating new mailboxes or mail-enabling existing users.

In other words: when using the new-mailbox or enable-mailbox cmdlet an action should be started, when the cmdlet has been run completely. The ‘feature name’ tag is something we can specify freely and is purely meant to clearify the XML-file. For example, you can separate scripts meant for provisioning from scripts that should be started when removing a mailbox.

The next few lines specify when the action should be run and ofcourse what the action is.

First, the $name variable is set, bij the called API, with the name of recently created mailbox. Next, set-mailbox is called to the $name mailbox for setting the retention policy.

In the script blcok, specified by the { and } symbols, we can run any regular PoSH-code. However, we can chooste to call an external .ps1-file as well. When you are going the use the scripting agent a lot and for more complex code, that will surely improve the readability of the config file.

The actions that are run by the scripting agent aren’t visible in the Powershell code the EMC displays when creating a mailbox. You do get feedback however, when the API-call running the scripting agent can’t be run correctly and returns an error. In that case, the mailbox will be created succesfully but the extra actions from the scripting agent won’t be run on the mailbox.

When the scripting agent does it job without any problems, directly after creating the mailbox you can check the properties of the newly created mailbox to see the retention policy has been applied.

As you see, using the scripting agent enables you to automate a lot in your Exchange-environment. The best way to check it out, is to fire up your testing environment to see what you can do.

Just to get you started, another cool example of using the agent:

In this case, the ‘validate’ API-call is use. When running an cmdlet, Exchange will always check if the cmdlet is valid and if there is enough information to start the cmdlet. If this is the case, the scripting agent Is triggered. So, this happens before the cmdlet is actualy run. Whit this information, can you guess what above code does? ūüėČ

Last tip before you start using the scripting agent: in a multiserver environment, the scripting agent must be activated on each server and the XML-file must be available on each server. The easiest way ofcourse, is to just copy the XML-file between servers.

If you want to know more about the scripting agent, you can ofcourse check Technet: http://technet.microsoft.com/en-us/library/dd297951.aspx

Use a PoSH-function to connect to MS Online

I like to make my life as easy as possible. One of the ways is doing this, is bij using Powershell whenever I can. To quicly connect to O365 and Azure AD through PoSH, I use a simple function in my Powershell-profile.

When called through open-msolconnection, the function will ask for credentials, create a new PoSH-session to O365 and starts the Exchange Online session, so you can interact with both the Office 365 backend as the Exchange Online service in one session.

Ofcourse, you can expand this function as much as you’d like. For example, you could add a parameter that gets the stored credentials from disk for a given tenant, so you won’t have to manually enter those credentials when connecting.

Doing this would also make it easier to use the function in other scripts, so you can automate as much as possible!

Get to know the real Windows-geeks in your environment

I always like to check out who is using my environment, be it an on-prem Exchange setup or an Office 365 tenant.
One of the things I find interesting, is checking in on the devices being used to connect to Exchange. Mostly because it can warn me of issues that my occur; it wouldn’t be the first time some iOS update causes trouble. The second reason I like to do this, is because I like to know what user are the first to upgrade their device, be it Apple, Android or anything else. Those ‘early adopters’ might be the perfect users to help in testing out new features in Office 365. They’re usualy tech-savy and willing to cope with issues that come with working with bleading edge technology.
When iOS7 was released, I used this simple Powershell one-liner to check on all devices running this operating sytem:

Note: get-mobiledevice will work in Exchange 2013 or O365 up from wave15. For Exchange 2010 of O365 wave14 I used the get-activesyncdevice cmdlet.
If you know what users are using a particular operating system on their mobile device, you can also use this information to block certain devices. For example if the latest iOS-relase breaks something in ActiveSync, like happened in the past.
With some Powershell, you can easily create an ActiveSync rule that blocks certain iOS-versions (or Android, or Windows Phone, or whatever).

Just to show my company actualy is full of nerds (well, I actualy prefer the term geek), I ran the following command against our Office 365 tenant:

As you can see, more then one on every six mobile devices in our organisation is running a beta-preview of the new Windows Mobile operating system!