Migrating a VMWare SharePoint Dev VM to Azure

My normal SharePoint 2013 development and testing environment is a single VMWare virtual machine. It runs Windows Server 2012 R2 and has installations of SQL Server 2012, SharePoint 2013 and Visual Studio 2013. To accommodate all of this, I have a big beefy desktop machine with 32GB of RAM and a couple of solid state hard drives: one for the host operating system and applications and another one to host the hard drive of the virtual machine.

A pretty typical setup, I think?

If a developer starts work on a SharePoint project they may not have a machine capable of hosting that environment right away. Often it needs to be ordered in for them which may take days or weeks. Likewise, they may be only need access to a development environment temporarily.

In order to provide swifter access to a working environment, I thought it might be interesting to explore converting my existing local SharePoint development VM to run in Azure.

Here are the steps I took to achieve this and what I learnt from doing it.

Stage 1: Create the VHD

VMWare virtual machines use a format of disk (VMDX) which isn’t compatible with Azure. The first step is therefore to convert the disk to the compatible VHD format.

  1. Inside my running VM I’ll download the Microsoft Disk2VHD tool.
  2. Next, I run Disk2VHD and un-tick the “Use VHDX” option in order to make sure we create a VHD disk rather than the newer VHDX format.
  3. In my scenario I want to create the VHD on a disk on the machine hosting the VM. I can do this by specifying the host PC’s IP in the “VHD File name” dialog box then specifying the admin share of the drive in question (f$ below).
  4. The creation of the VHD will take some time so this is an ideal opportunity to grab a nice cup of tea and a biscuit.

(Optional Stage 1.5: Test VHD in Hyper-V)

Before uploading your newly created 100GB+ VHD to Azure and hoping it’ll work, you can try testing it locally. You’ll need a Hyper-V server with enough resources to host it but it should just be a case of creating a new VM with your VHD as the disk.

Note: I haven’t got a Hyper-V host to hand with enough memory so I’m skipping straight to popping my disk into Azure.

Stage 2: Upload the VHD to Azure

Once stage 1 is complete, we should have our VHD ready to upload to Azure.

To proceed you’ll need to ensure you have access to an Azure subscription, a storage account within that subscription and the Azure PowerShell module installed and configured on your local machine.

Once that’s all ready it’s really just a case of running the “Add-AzureVhd” PowerShell command. We have to specify the “FileLocation” parameter and point it at our newly created VHD file as well as the “Destination” parameter.

The destination is the location we want to copy the VHD to. This is made up of the URL for our storage account, the folder within the storage account that the VHD will be stored in and the name we’re going to give the VHD file in Azure. Mine will look a bit like this:

What’s nice about this command is that it does sensible things like create an MD5 hash of your local file then check the file you’ve uploaded has the same hash upon completion. It also supports resuming of your upload should it be interrupted.

When the upload completes you should be able to browse to your Azure storage account, drill down to the vhds container and see your uploaded VHD.

Stage 3: Create a new VM image from the uploaded VHD

Back in the Azure managment portal we need to tell Azure this isn’t just any old VHD, this is something it can use as a template to create new VMs from. We do this by creating an “Image” from the VHD.

  1. Navigate to the “Virtual machines” section, click the “Images” heading then choose the “Create an image” option.
  2. On the “Create an image” screen give your VM a sensible name and description then select the VHD you uploaded earlier. You also need to specify that the VM is running Windows and tick the “I have run sysprep” box (even though we haven’t!)

Stage 4: Create a VM from the image

Having created an image from the uploaded VHD when we now go to create a VM we can drill down into the “My Images” section of the gallery and find our newly created image.

When we create a VM from the image it will take a long time to provision and start up. If you think about it, we’ve effectively pulled the rug out under our VM and moved it from the VMWare virtual hardware to Hyper-V’s. It has to rediscover that hardware and setup drivers to be able to talk to it.

This is another great opportunity for a cup of tea and a biscuit.

Once the VM has completed provisioning you should be able to connect to it over RDP and start using it.

Stage 5: Troubleshooting

VM is unresponsive to Remote Desktop

I’ve had mixed results with this approach. On more than one occassion the VM provisioned and started up fine but I couldn’t connect to it over RDP. I was able to ping it and even connect via PowerShell so I knew it was running, it just wouldn’t allow me to remote into it.

I followed some instructions on re-enabling remote desktop remotely, restarted the terminal services service and eventually it started working but I’m not entirely comfortable not knowing why it stopped in the first place.

Errors in SharePoint

Once connected to my VM the first thing I did was fire up SharePoint Central Admin. It took a while but eventually I was presented with nasty looking IIS / .NET error pages. A little digging revealed that the network card installed when the VM was created in Azure is configured to use DHCP to get both its IP address and DNS.

As my standalone VM is configured to be DNS for itself I simply had to change this to use 127.0.0.1 for DNS and things were happy again.

Stage 6: Using the VM

Whilst it just about works, using the VM on an on-going basis would be pretty painful. It’s hampered by the low disk performance Azure provides. I grabbed a couple of screenshots from the Resource Monitor tool to illustrate this. Of particular interest is the “Response Time” column I’ve highlighted. This shows how long each process is having to wait to get a response from the underlying storage infrastructure.

On the local copy of the VM, hosted on a dedicated SSD response times are generally less than 5 ms:

Local VM hosted on a dedicated SDD.

By way of contrast them same VM hosted in Azure shows response times in the thousands of milliseconds:

Perfmon-disk-performance-AzureVM

VM hosted in Azure on a single disk.

Conclusions

Clearly, this particular VM was originally architected to take advantage of a single, fast SSD. Doing a ‘lift and shift’ to just dumping it in Azure was never going to provide an optimal solution. Having said that, the fact that it works at all and is useful in a pinch is pretty impressive.

The key takeaway from this should be that demanding workloads such as SharePoint can be implemented successfully on the Azure platform however there are a number of very specific considerations which should be taken into account when designing and implementing that underlying infrastructure. Expecting existing VMs to be able to be migrated across and work just as well as they did on-premises is naïve.

I’ll be sure to create a follow up to this post with some lessons I’ve learnt from implementing SharePoint and other demanding workloads in Azure.

Sorting the SharePoint Quick Launch Menu in PowerShell

I recently had to work with a SharePoint site which had accumulated an enormous number of links in its left-hand, (or ‘quick launch’ in SharePoint parlance), menu. Unfortunately, I wasn’t able to activate the ‘SharePoint Publishing Infrastructure’ feature for the site in question, meaning I couldn’t use the automatic sorting functionality. Instead, all I had available in the interface was the clunky list of items with a pull-down menu to specify the position they should appear in.

reorder-quick-launch

Unsorted quick launch and rudimentary sorting interface.

A quick search showed up lots of examples of how to add and remove individual links or how to export /  import via an XML file, but sorting seems not to come up. (Maybe everyone else is better at managing what ends up in their navigation elements?). Regardless, armed with my trusty PowerShell ISE I reckoned I could whip something up to fulfil my requirement.

My plan was simple:

  1. Get the specified site’s quick launch.
  2. Create a sorted copy of the links in the quick launch.
  3. Clear the current quick launch.
  4. Copy back in my sorted list of links.
  5. Treat myself to a nice cup of tea and a biscuit.

Here’s the quick and dirty solution I came up with:

That fixed my immediate problem but when I get five minutes I’ll come back and make a function out of it. I’d like to be able to specify the site and the specific section I want sorted, perhaps with the ability to sort the top-level sections too.