Completing individual moverequests from a migrationbatch

While working on a hybrid migration from Exchange 2010 to Office 365, I found myself in a place where I had a migration batch of approximately 350 mailboxes that was ready to complete, but I only wanted to complete around five of them so my costumer could do some further testing. This was something that was decided later on in the migration traject, so the migration batch was already set up and had synced.

Now, when you use PowerShell, you can complete the entire migration batch with the complete-migrationbatch cmdlet. But there’s no such thing for completing individual mailboxes. With some workarounds though, you can complete individual moverequests from within a migration batch.

First, get the moverequest you’re completing:

You’ll see the status is ‘synced’, so the mailbox is ready to complete. To do this, we change some properties for the individual moverequest:

In this example, I set the ‘completeafter’ propertiy to 5 minutes. You can also provide a date/time string to already schedule the completion for a few days from now.

After this is set, we need to resume the migrationbatch so it will complete:

After a while, you can do another get-moverequest and see the status will be ‘completed’.

Further developing the homelab script

My previous post was about the script I used for my presentation at Experts Live: (re)building your homelab using PowerShell. As it turns out, someone got inspired 😉 Sven already did an update to the script by creating a variable for specifying the gateway address for your new VM.

As we both have plans on further developing this script into a nice module with some extra functionalities, I’ve decided to move the code to a seperate repository on GitHub. This way, the demo code from Experts Live stays the same for future reference, and the project we’re working on truly becomes a seperate project.

If you’d like to add in on further expending and developing this module, please feel free to contribute through GitHub!

Slides and code for Experts Live 2016

Last week i had the privilige to speak at Experts Live 2016. This has always been a great event to brush up on skills, gain some new knowledge and catch up with old and new friends from ‘the industry’.

I did a talk about automating (re)building your home lab environment, to make sure you can keep up with all new developments in the Microsoft world. I promissed to put my slidedeck and code online, so I made them available on GitHub. I did a blog post on (sort of) the same subject a while ago, you can check that out here.

Just so you know: I know I’ve been slacking off a bit on writing new blog posts the last couple of months, but there are some new posts on their way. So keep coming back 😉

Building a home lab, the PowerShell way

I haven’t posted here in a while, but for a good reason: I started a new job! As of May 1th, I started working as a Senior IT Consultant at Hands On.
Partly because of the job change, I wanted to build a home lab for some testing an practicing for certification exams.
My lab will run an Intel NUC, the sixth generation, with 32GB of RAM and a 500GB M.2 SSD drive. This box currently runs Windows 10 Pro, mainly because that means I can also use it as workstation while working at home. Perhaps in the future I’ll switch over to running a server OS, with a workstation as a VM… Still thinking about what the best option is.
Anyway, the box runs Hyper-V and because using it as a lab means I’ll frequently be installing new servers or reinstalling existing ones, I wanted a workflow to speed up this process. And of course I will use PowerShell to do so 🙂 I’ll share my setup and scripts in this post, but please note that this is (as always) work in progress and is by no means a perfect solution. However, because I received some requests to share my work, I decided to put them online already 🙂
First, a small look at the networking setup for Hyper-V. I wanted to isolate my guests from my main network. And because the NUC is such a nice, portable little box, I want to have the ability to take it with me and use it somewhere else, without the need to change my entire network configuration. To realize this, I decided to go with a NAT-switch in Hyper-V. This way, the guests can use there entire own subnet and still have internet-access through the host machine. For more information on this, check this out.
To save up on disk space needed for the servers, I wanted to use differencing disks. This way, there is one ‘main’ disk, with each VM having it’s own differencing disk with just the changes / delta’s to the main disk. So, I installed a plain Windows Server 2012 R2, installed all available updates and ran sysprep so I can use this as a base image.
After this, i copied the VHDX for this machine to seperate folder and marked it as read-only. Once it is used as a base disk for all other servers, changing this disk directly would break all underlying VM’s, so the read-only part is just for security.
After this, the ground work for the lab is done. Now i’ll need to build a PowerShell script to do the actual deployment.
I’ll break down the script piece by piece, to show what work is being done by the script.

This first part is where I’ll define the variables that I change whenever I run the script. I set the desired name for the VM, the IP-address I want it to use and the IP-address for the DNS server. In the future, I’ll most likely change this script into a function so I can just supply them as paramaters. For now, I’ll just manually change the script each time I run it. Like I said: work in progress 😉

These are static variables that contain stuff as file paths. These won’t change each time the script is run, but I think setting them here is nicer that just hardcoding them in the script. The ‘CertLab’ VM-Switch is the NAT-switch I created earlier.

The real work starts off with creating the VHD-file for the new server. The disk is created as a differencing disk, with the base image I created earlier as the parent disk.

This part of the script mounts the newly created VHD-file for the new-VM, and then copies an unattend.xml to this disk. I use some scripting to add content to the XML-file. This way I change the hostname, IP-address and DNS server address for the new server, based on the variables I defined in the beginning of the script.

Here, I just create the new VM. I set the MemoryStartupBytes paramater here hardcoded in the script, but ofcourse you can always choose to specify this as a variable (or a parameter if you create a function) to be able to easily change this.

Finaly, I simply start the new VM.

That’s it! By using this script, I’m able to set up a new VM in my lab with just a few clicks. Like I said, it’s work in progress. I’d like to implement PowerShell Direct to do some final configuration on the guest machine, such as adding certain roles. At this time, however, PowerShell direct requires the guest to run a Server 2016 TP OS, and as I’m also using this lab for certification and training purposes, I’m sticking with Server 2012 R2 for now. I could set up PowerShell Remoting (Robert has a great blogpost on this), but that’s something for the future 😉
If you have any comments on my code, or if you would like to add something to the script, please feel free to do so!

Remove calendar processing from a non-resource mailbox

Today I was working on converting an Office 365 room-mailbox to a ‘regular’ shared mailbox. The customer had some legitimate reasons to convert this mailbox, and who am I to question. 😉

The conversion itself is fairly simple, using PowerShell

This sets the mailbox to a ‘regular’ shared mailbox instead of a room mailbox (what it was). After setting some access rights to the mailbox I emailed the customer that his mailbox was changed and that he could access it.

After a few minutes, I received an email stating that he could send an email to the newly converted shared mailbox, but that the email would be moved to the trash can almost instantly. I know this is the default behavior for room mailbox where the calendar autoprocessing is enabled, so I reverted back to my Powershell window.

This shows that the calendar processing for this mailbox is still active. Apparently, this doesn’t get disabled when converting a room mailbox to a different kind of mailbox. No problem, because we can use the set-calendarprocessing to disable this feature.

Unfortunately, this returns an error:

The error is clear: you can only run this command on a resource mailbox. The solution was also clear: convert the mailbox back to a room mailbox, remove the calendar processing and convert the mailbox to a regular shared mailbox again.

Lessons learned: when converting a room mailbox with calendar processing enabled to a different type of mailbox, remove the calendar processing before converting the mailbox.

Getting started with Powershell for Office 365

So, you manage a nice, shiny Office 365 tenant. You use the portal to take care of your admin needs like creating users, assigning licenses and setting permissions.

But you want more. Of course you want more, you’re in IT. You always want more. You no there is one tool that can give you more: Powershell. Like for al modern Microsoft workloads, PowerShell is my go-to tool for Office 365 too. I find myself using PowerShell even for stuff I can do from within the portal, because i’m just simply used to it. Some tasks you can only do in Powershell, so you need to learn it anyway. Back in the days, when Wave14 of Office 365 was still there, you needed Powershell to create a shared mailbox, for example. By now, you can do that from within the portal, but I still find myself using Powershell because i’m used to it.

So, getting started with Powershell. How do you do that? For starters, Microsoft has a site dedicated to this. You can get started with the basic Powershell cmdlets for Office 365, find script examples and watch some Office Mechanics videos on the subject.

Furthermore, when getting started with Powershell in general, the book Learn Windows Powershell in a month of lunches is a no-brainer. In, as the title says, a month of lunches you can get started using Powershell and get to know all tips and tricks. Because it  starts from the basics, you get a solid foundation on the language so you can start building your own scripts and functions.

And last but not least: get in touch with the community. In The Netherlands, there is a very active Dutch Powershell User Group, with regular meetings to boost your knowledge. Not from our little country? No problem. There are Powershell user groups all over the world. Bing it! 😉


One final tip, for when you’re ready to really get your Powershell going: invest in license for IseSteroids. This enhancement for the integrated script editor provides lots of functions to make your live easier. Really worth the money!

Change the Office 365 language for synced users

Office 365 is all about letting users set up their own environment and preferences. One of those preferences can be the language in the Office 365 interface. I work for a company in The Netherlands, where everyone speaks Dutch, but I still prefer my computer and software to be in English. In Office 365, I can set this up… Unless I’m a ‘synced user’, a user who originates in an on-prem AD and that is being synced to the cloud.

Even when I ask my administrator, he can’t set the preferred language via the appropriate PowerShell cmdlet

This will result in an error:

So, what causes this error? It’s pretty simple. When you use DirSync (or the newer AADSync), the on-prem directory is leading. You could say the sync is one-way: changes sync from on-prem to the cloud, but not the other way around. Therefore, you can’t make changes to properties of the identity in Office 365. So, if you want to change the preferred language for such users, you should do this in the on-prem AD.

All available language codes are listed here. And keep in mind, if your preferred language is not set, it will default to English.

Use Powershell to remove aliases from O365 users

First blog of the new year! Let me start off by wishing everyone a great 2016!

A quick blog this time. One of my clients sold a part of their company and needed to hand over the domain they currently use in Office 365. So, for all users I needed to remove the alias ending on this domain.

Of course, PowerShell is the tool for the job.

We need to remove the alias from the EmailAddresses property of the users, using the set-mailbox cmdlet. In full:

So yet again, be it Office 365, Azure, or on-prem: PowerShell is the way to go!

stopped-extension-dll-exception when running DirSync

Today I ran into a problem at a costumer. They are running an Exchange 2013 server in a hybrid configuration with O365. Part of the users are on the local Exchange server, but the main part of the users use O365 for their mailbox needs.

Some new mailboxes were needed, so I created the users in Active Directory and ran the enable-remotemailbox cmdlet to provision their mailboxes. Next step is to assign a license in O365, so I kicked of DirSync with the start-onlinecoexistencesync cmdlet and reverted to the O365 portal to license my new users…. But they didn’t show up.

I checked the MIIS client to see that the export to Azure AD failed with the ‘stopped-extension-dll-exception’ error.

After some research, I found that this can be related to the execution policy in PowerShell. For DirSync to run successfully, it turns out the PoSH execution policy should be set to ‘unrestricted’. Earlier this week, a GPO was activated at this costumer to enable PowerShell remoting, including the option to set the execution policy to ‘ remote signed’. After creating a deny for this policy for the server running DirSync and manually setting the execution policy back to ‘unrestricted’, DirSync worked again and my newly created users started showing up in the O365 portal.

Wise lesson: for DirSync to run successfully, the execution policy for PowerShell on the server running DirSync needs to be set to ‘unrestricted’. Pretty weird, as in IMHO ‘remote signed’ is the preferred and most secure setting. It is strange, at least, that Microsoft’s own products don’t work in this scenario. I haven’t tried this with the newer AADSync yet, so maybe this flaw was fixed in the newer releases.

There are a few issues on the O365 support pages regarding this issue, some of which stating that even if the execution policy is set to ‘unrestricted’ via GPO DirSync won’t work; the GPO must set the execution policy to undefined and the execution policy on the server needs to be set manually. However, only some of the people responding could confirm this, so your mileage may vary…

Managing O365 groups with PowerShell

One of the much appreciated features in Office 365 are the new Office 365 Groups.

An Office 365 group provides a way to collaborate on a project with co-workers. When created, the Office 365 system creates a shared mailbox, shared calendar, a Sharepoint teamsite and a OneNote notebook for the team to use. When allowed by their tenant administrator, users can create a new Office 365 group themselves, without the need to contact their IT department.

When looking at these functionalities for our internal network, we decided they might come in handy for certain projects. To keep things as standard as possible, we needed a way to automate the creation of these groups as much as possible. And when you talk automation, you talk Powershell.

It turns out you can manage new Office 365 groups through Powershell without hassle. In Powershell, these groups are referred to as ‘unified groups’. As you know, there are only three commands you know to learn Powershell: get-command, get-help and get-member. Let’s use these commands to check out what we can do with these groups in Powershell.

Ofcourse, we need to log on to our O365 tenant with Powershell first. After that, we’ll need to find out which commands are available.

As you can see, there are multiple cmdlets to add, remove and manage new Office 365 groups. I would like to start out with creating a new group, so I’ll need some info on that.

To get some pointers on the use of this cmdlet, we can ask for some examples.

So, let’s create a new group! Because I don’t want my colleagues to be able to see this group, I’ll set the accesstype to private.

Office 365 will no create the new group. It takes some time to complete the command, because the system will provision all parts of the group: a shared mailbox, shared calendar, OneNote notebook,

When the group is live, we can see what is stored about the group.

After creating the group, we might want to add some members to it. The new-unifiedgrouplinks is what does just that.

Ofcourse, you can use the get-unifiedgrouplinks cmdlet to retrieve the members or owners of a group. A unifiedgrouplink can be of different types: owner, member or subscriber.

By using this cmdlets, you could automate the creation, management and deletion of Office 365 groups. That way, you can set up all the groups you deploy in exactly the same way and perform these tasks automatically on certain triggers!