Bandwidth management with VMware Mirage

Using Mirage in large, distributed networks or even small ones sometimes can be a bit problematic. This is especially true during times in which layers are updated, machines are migrated and so on.

The reason for this is the limited amount of bandwidth available between the Mirage servers and clients. While Mirage works perfectly fine with slow and somewhat limited network connections it still takes what it gets. This means if you have, for example, a 10 Mbit line and you are updating a Mirage managed end point over this connection it will most certainly congest. Because, as I already said, Mirage will use as much bandwidth as available – like almost every other protocol.

This is the reason why it is recommended to use Quality of Service (QoS) in environments where Mirage will be used, especially when branch offices with limited bandwidth come into play. Configuring the existing QoS solution to work with Mirage most of the time is very easy, because Mirage only uses one port (TCP 8000) for communication between client and server. But often no QoS is implemented and implementing it as part of the Mirage project is most often not possible.

Quality of service
While the new Mirage bandwidth limiting feature works very well and is easy to implement, implementing a proper QoS based on the network infrastructure has still some advantages, for example, allowing Mirage to use more bandwidth if the line utilizatization is low.

Based on this experience in version 5.1 of Mirage a new feature called bandwidth limiting was introduced. With the new bandwidth management features you will be able to limit the bandwidth Mirage uses without the need for 3rd party QoS solutions. You are able to specify the maximum amount of bandwidth (in KB/s) Mirage can use for upload and download operations based on the clients IP subnet or Active Directory site. Actually you set the bandwidth limit from the servers point of view, this means you set the bandwidth limit for outgoing (download from the clients point of view) and incoming (upload from the clients point of view) traffic.

Screenshot 2014-11-03 12.43.23

To set bandwidth limits you create a CSV file that specifies how much bandwidth can be consumed for outgoing respectively for incoming traffic based on the location of the client. The location is identified by either the IP subnet or AD site. Here is an example:

Screenshot 2014-11-03 12.43.33

For more information on how to set up bandwidth rules in the Mirage management console have a look at the official documentation: Managing Bandwidth Limitation Rules.

Now, let’s talk about the priority of the rules. First of all the order of the entries has no effect (besides on exception I will cover in a moment) on which rule is applied to which end point. Have a look at the screenshot above. As you can see you can specify a rule based on:

  • the Active Directory site,
  • the IP (v4) subnet
  • and a single end point (also based on an IP subnet rule).

For each of these rules you can set up a limit for outgoing and incoming traffic. So, to stick to my example, I limited the bandwidth for the AD site “Branch” to 2500 KB/s, the IP subnet to 8000 KB/s and each of the IP addresses to 5000 KB/s. I set each limit to the same value for incoming and outgoing traffic. To keep it simple for now we will only talk about outgoing traffic (client download).

First of all both clients identified by their specific IP address can download with a maximum speed of 5000 KB/s. Theoretically that would allow them to consume 10.000 KB/s in total in the subnet But because the subnet is limited to 8000 KB/s the max. amount of bandwidth the can be consume in total is 8000 KB/s. Still each client itself is limited to 5000 KB/s. Now, because both clients or to be more precise the IP subnet belongs to the Active Directory site “Branch” the bandwidth is further limited to 2500 KB/s. So regardless of the bandwidth limit for the specific device or subnet the Active Directory site rule in this case wins. But the rule does not win because it is listed last or because AD sites have a higher priority instead it is the rules with the most restrictive limit. If I had set a limit of 500 KB/s to the IP then this limit would be enforced and not the subnet or site limit.

As I mentioned before the order of the entries has more or less no effect unless you specify the same rule twice. Then the latter one will be used.

After the priority of the rules is sorted out let’s talk about the limitation of incoming and outgoing traffic. As you can see you can set both limits (upload and download) independent from each other. This means Mirage bandwidth limitations can even be used on asynchronous connections where the upload bandwidth may be lower than the download bandwidth. For rules including only a single device up- and download operations will never run at the same time as the Mirage client is either uploading or downloading. Rules based on AD-sites or subnets will most definitely run up- and download operations at the same time as they will include more than one devices. Please be aware of this fact and plan your bandwidth limits accordingly. Also make sure you understand that you specify the max. amount of bandwidth that Mirage can use.

While the priority of the rules and the maximum amount of used bandwidth are the basics you need to know to work properly with the Mirage bandwidth limiting feature the following facts are also very helpful and good to know:

  • As soon as you import new rules they will take effect immediately. No restart of the Mirage server services or the clients are necessary.
  • Mirage will not guarantee fairness between clients but from personal testing it looks like that bandwidth is divided equally under full load.
  • If a Mirage client is configured as branch reflector all bandwidth limitations still apply. Layers downloads to the reflector will be limited by the rules applied to it.
  • Bandwidth limits do not apply to transfers between branch reflectors and clients. So clients that download their layer from a branch reflector will not be limited in any way.
  • The auto update feature of Mirage clients are also affected by the configured bandwidth limits.
  • Bandwidth limits will be divided between servers proportionally to the number of connected clients and each server gets a fair share of bandwidth. This means, for example, if you have five servers and a bandwidth limit of 5000 KB/s set for a subnet each server will get 1000 KB/s under full load. Also, for example, if you have two servers with a limit of 5000 KB/s set for a subnet and three clients connect to the first server and two to the second server the first server will get 3000 KB/s of bandwidth and the second one 2000 KB/s.
  • And of course bandwidth rules can be imported and exported using the Mirage server CLI using the getBandwidthRules and setBandwidthRules option.

Thats about it. How do you like the new feature? Anything missing in regards to bandwidth management you may want to see in future version of Mirage?

How to disable the Horizon Mirage client upgrade balloon

When updating the Mirage server infrastructure to a newer version all Mirage clients are automatically updated the next time they connect to the upgraded Mirage server. During the client update the user gets notified that the client is being upgraded.


While this notification is somewhat non-disrupting sometimes it needs to be deactivated. Of course this is possible with only a minor change to the Mirage desktop service configuration file located here:

C:\Program Files\Wanova\Mirage Service\Wanova.Desktop.Service.exe.config

Open this XML file in your favourite editor and change the following setting from

<add key="showUpgradeBalloon" value="true"/>


<add key="showUpgradeBalloon" value="false"/>

Most customers change this key while deploying the Mirage client using a post-install script. But what to do when Mirage is already up and running, the Mirage clients are deployed and you are planning an upgrade?

Thats even easier. You can centrally change this setting by updating your CVD policy. Here is how:

  1. Export your CVD policy using the Mirage management console
  2. Add the text outlined below inside the configuration tags
  3. Import your CVD policy using the Mirage management console
  4. Save the policy as new (minor) version
  5. Assign the updated CVD policy to all your clients

The following parameter has to be added inside the configuration tags:

<Config Name="showUpgradeBalloon" Value="false" />

Please be aware that this entry is case sensitive.

After you edited your CVD policy the XML file should look similar to this example:

<?xml version="1.0" encoding="utf-8"?>
<DesktopPolicy xmlns:xsi="" xmlns:xsd="">
<UploadChangesIntervalMs>3600000</UploadChangesIntervalMs> <FullUploadChangesIntervalSeconds>0</FullUploadChangesIntervalSeconds>
<Config Name="showUpgradeBalloon" Value="false" />
<Directory path="%anyvolume%" recursive="true" filter="*.vmdk" />
<Directory path="%anyvolume%" recursive="true" filter="*.vmem" />
<Directory path="%anyvolume%" recursive="true" filter="*.vmsn" />
<Directory path="%anyvolume%" recursive="true" filter="*.vmss" />
<Directory path="%anyvolume%" recursive="true" filter="*.vhd" />
<Directory path="%anyvolume%" recursive="true" filter="*.vfd" />

VMware Horizon Mirage client disk space requirements

Lately the question comes up how much disk space the Mirage client does require?

The VMware Horizon Mirage Installation Guide states: At least 5GB of free space

These 5GB of space are required for normal operation. Normal operation in Mirage terms are centralization and steady state uploads. For both operations the 5GB are required for VSS snapshots, manifest files and other Mirage data.

When it comes to base layer and app layer deployments the required disk space is higher of course. The reason is that you need space to save the data which is contained in the base layer or the app layer.

For example: You want to deploy Office 2013 as an app layer. Office 2013 requires around 3GB of disk space. In this case you need to have at least 8GB free disk space on the client to successfully deploy this application (layer).

5GB for the Mirage client + 3GB for Office 2013 = 8GB total required disk space

If Mirage is used for Windows 7 migrations the required disk space growth even further. When a Windows 7 migration is done with Mirage as first step the Windows 7 base layer and optionally some application layers (this is a new feature in Mirage 4.3) are downloaded to the client.

Example: Your Windows 7 base layer has around 25GB. Then you need at least 30GB of free space on the clients hard drive.

5GB for the Mirage client + 25GB for the Windows 7 base layer = 30GB total required disk space

If you deploy an application layer the same time you do the migration you require additional free disk space in the size of the application layer.

Another example: Your Windows 7 base layer has 25GB and you deploy Office 2013, which requires 3GB disk space, in the same process. Then you need 33GB of free disk space.

5GB for the Mirage client + 25GB for the Windows 7 base layer + 3GB for Office 2013 = 33GB total required disk space

After the Migration you are able to free a lot of disk space because, if the migration was successful, you can delete the Windows.old folder. The Windows.old folder is created during the migration process and contains a complete copy of the old Windows installation. The deletion of this folder can be easily automated, just follow the instructions in this knowledge base article: Removing the Windows.Old directory after User Profile or Windows 7 Migration with VMware Horizon Mirage

And now the disk space requirements for a restore operation. As a rule of thumb for a restore operation (e.g. disaster recovery, revert to old Windows version, hardware migration) you need as much disk space as it was occupied on the original system. This equates to the total size of the CVD which can be found in the CVD properties in the Mirage management console.


Example: So if your system drive contained 80GB of data you need 80GB free space in addition to the 5GB for the Mirage client.

5GB for the Mirage client + 80GB total CVD size = 85GB total free required disk space

Lastly we need to have a look at the disk space requirements for the driver library. The free disk space required for the driver library on the end point depends on the number of drivers you import and assign to a device using the driver profile/library.

For example if you download the Lenovo Windows 7 driver pack for the ThinkPad T430/T530 series and import it into the driver library as is you require around 1.5GB of free disk space. Incase of a Windows 7 migration using a base layer in the size of 25GB and a driver profile containing 1.5GB of drivers you required 26.5GB of free disk space plus the 5GB for the Mirage client.

5GB for the Mirage client + 25GB for the Windows 7 base layer + 1.5GB for the driver profile = 31,5GB total required disk space

The driver library ist applied automatically on operations such as centralization, migration, hardware migration and restore, base layer update and of course if you use the “Set driver library” option. So you should add the driver library every time you do a free disk space calculation like you would do for the 5GB required by the Mirage client.

If for some reason or another you end up not having enough free disk space on the client an event is logged in the Mirage management console.

As you can see the event log even shows you how many free space you have and how many is actually required to successfully finish the current operation.

All listed disk space requirements in this article are not exact and just estimates. The actual disk space required may vary based on the deduplication functionalities in Mirage. Anyway the numbers outline in this article should give you a good idea about the required disk space and most of the time the required disk space will be less.


“Please contact technical support” event in the VMware Horizon Mirage Event Log

In the latest release of Horizon Mirage 4.3 a bug was discovered that might cause upload failures. These upload issues are logged in the Mirage event log with the remark to “Please contact technical support”.

This problem may appear if you updated you Mirage environment from an older release (4.0.2, 4.2.2, 4.2.3) to the latest 4.3 release. Only if you upgraded your environment you may be affected by this problem, new installation based on 4.3 are not affected.

As always our Mirage engineering team solved this issue right away and released a specialized version of the Mirage server tools which allow to fix the upload problems. Inside the download package a PDF called “Fixing potential upload problems in Horizon Mirage” is included which specifies the steps to solve the upload failures as mentioned below:

  1. Upgrade to Mirage 4.3
  2. Download the attached server tools (available in the Mirage download “Tools” section).
  3. Extract the tools in a new folder, not overwriting the installed Mirage binaries.
  4. Run the server tool “LegacyCvdIntegrityCheck”

Wanova.Server.Tools.exe LegacyCvdIntegrityCheck

Usage: LegacyCvdIntegrityCheck
-serverAddress [Management Server Address]
-concurrentScans [number of concurrent integrity scans. Recommended 1-5]
-scanMode [Optional. FixForUpload (Default), CheckOnly, FixForRestore, ProactiveFixForRestore, ProactiveFixForUpload]

Example: Wanova.Server.Tools.exe LegacyCvdIntegrityCheck -serverAddress localhost -concurrentScans 2

If you have any further questions about this tool or bug please contact VMware Technical support or your local VMware rep.


How to customize USMT in Horizon Mirage

When doing a Windows 7 migration using Horizon Mirage the User State Migration Tool from Microsoft is used to migrate user settings and data as well as operating system settings.

USMT by itself already supports a lot of settings and additionally Mirage adds support for even more settings which are automatically migrated. Have a look at my previous article to get to know about the settings which are migrated out of the box.

Still in most cases USMT inside Mirage needs to be modified as additional application, user or operating system settings and data need to be transferred during the migration. For example you may want to migrate Google Chrome, Mozilla Firefox or SAP GUI settings.

Extending USMT is just a matter of creating additional XML files which contain the information on what additional settings should be migrated. This can be done manually by following the USMT user guide custom XML examples or using a nice tool called USMT XML Builder GUI.

After the XML file with the needed settings is created (in my example it is called ThinApp.xml) it needs to be copied into the USMT x86 and x64 folder. To get these folders you have to download USMT and update it. I covered how this can be done in my prevoius article on how to import USMT into Mirage.


When the USMT folder is prepared an the custom XML files are added we need to customize the USMT script inside Mirage. During the USMT stage Mirage launches a script called “Launch_USMT.cmd” which is located in the Mirage Client folder under ” C:Program FilesWanovaMirage Service”. This file needs to be copied to the root of the USMT folder.


After this is done the script needs to be adjusted to include the newly created custom XML file. For this just open the “Launch_USMT.cmd” in a text editor of your choice and modify the variable USMT_MIG_XML to include the custom XML file.


For each new XML file the following parameter needs to be appended to the variable:


Of course you have to change the name of the XML to the appropriate one. After you changed the variable it should be look similar to following example:


set USMT_MIG_XML=/i:%USMT_LOCATION%MigApp.xml /i:%USMT_LOCATION%MigDocs.xml /i:%WallpaperFile_XML_PATH% /i:%KeyboardLayout_XML_PATH% /i:%MigRegionalSettings_XML_PATH% /i:%DefaultPrinter_XML_PATH% /i:%Win7CustomSettings_XML_PATH%


set USMT_MIG_XML=/i:%USMT_LOCATION%MigApp.xml /i:%USMT_LOCATION%MigDocs.xml /i:%WallpaperFile_XML_PATH% /i:%KeyboardLayout_XML_PATH% /i:%MigRegionalSettings_XML_PATH% /i:%DefaultPrinter_XML_PATH% /i:%Win7CustomSettings_XML_PATH% /i:%USMT_LOCATION%ThinApp.xml

After the variable is changed and the updated script is saved the USMT folder needs to be imported to Mirage again.


From now on the customized USMT is used for any migration task.

Install Horizon Mirage silently

Testing different versions and new versions of a software product in a lab environment can be very cumbersome if you always have to install servers and clients manually. If you think further automating the installation process of Mirage server components also helps you to dynamically scale your Mirage deployment.

For this reasons I always try to automate the installation process of each product I have running in the lab. While this is most often very easy und nicely documented by the vendors (e.g. VMware Tools or the View Connection Server) this isn’t the case for the Mirage server components.

In the following article I cover how to install each Mirage component silently, beginning with the Mirage client. Please make sure you change the file name for each installer accordingly to the Mirage version and bitness you are using.

Software Prerequisites
Every Mirage component (client, server, console and file portal) requires Microsoft .NET Framework 3.5 SP1 to be installed. Please make sure .NET Framework is installed before trying to install any Mirage component silently.
The /qr parameter
Please make sure you use the /qr parameter to install the Mirage server components silently. Every other MSI unattended parameter like /qb or /qn will fail or prompt to accept the licensing agreement.

Mirage client

The unattended installation of the Mirage client is documented in the official VMware Horizon Mirage Administration Guide on page 52. Also my colleague Kim Nis Neuhauss wrote a detailed article about the different deployment methods of the Mirage client.

The installation of the client is really straight forward.

MirageClient.x64.59447.msi SERVERIP=MirageServer:Port USESSLTRANSPORT=true /quiet

You just have to specify the SERVERIP parameter which should contain the FQDN and the port of your Mirage server and if you use SSL instead of TCP for communcation you have to add the USESSLTRANSPORT=true parameter.

Installing the Mirage servers components isn’t that easy as the parameters aren’t documented but it is of course possible!

Mirage management server

[yellow_box]The unattended installation of the Server components assumes that you already have a supported SQL server up and running on which the Mirage database will be installed on. Please make sure the account which is used for the unattended installation has the appropriate permissions on the SQL server instance.[/yellow_box]

To install the Mirage management server silently you have specifiy some of the following parameters:

Parameter Value Required Description
DBSERVER ServerName Yes This presents the FQDN of the SQL box on which you want to store the Mirage database
DBSERVERINSTANCE InstanceName No This is the name of the SQL instance in which you want to store the database. This parameter is only required if have a dedicated SQL instance of your server (i.e. for SQL Express
SERVICEACCOUNTMODE localsystem | CustomUser Yes Specifies wether you want to use the local system account (localsystem) or a dedicated service account (CustomUser) for the Mirage service.
SERVICEACCOUNT Domain\Username No Needs to be specified if CustomUser is choosen as SERVICEACCOUNTMODE.
SERVICEPASSWORD Password No Needs to be specified if CustomUser is choosen as SERVICEACCOUNTMODE.
ADMINGROUPACCOUNT Domain\Groupname Yes Name of the Active Directory group which will be appointed as Mirage administrators.
AFFECTSTORAGE 1 No Specifies if you want create a new storage areas (1) or let the installer decide (0) if it wants to create a new or use an existing one.
WORKDIR C:\PathToMirageStorage No If AFFECTSTORAGE is set this parameter specifies the path to the storage area.

For a new single-server installation using a local SQL Express installation and the storage area on an additional drive called E: you would use the following installation parameters: DBSERVER=localhost DBSERVERINSTANCE=SQLEXPRESS SERVICEACCOUNTMODE=localsystem ADMINGROUPACCOUNT="HorizonFluxMirage Admins" AFFECTSTORAGE=1 WORKDIR="E:\MirageStorage"

To install a multi-server setup with a dedicated service account and SQL server you would use something like this: SERVICEACCOUNTMODE=CustomUser SERVICEACCOUNT=HorizonFluxMirageService SERVICEPASSWORD=TopSecretPassword ADMINGROUPACCOUNT="HorizonFluxMirage Admins" AFFECTSTORAGE=1 WORKDIR="\\\MirageStorage" /qr

Mirage server

To do an unattended installation of the Mirage server some of the following parameters must be specified:

Parameter Value Required Description
DBSERVER ServerName Yes This presents the FQDN of the SQL box the Mirage database is stored on
DBSERVERINSTANCE InstanceName No This is the name of the SQL instance in which the Mirage database is stored. This parameter is only required if have a dedicated SQL instance of your server (i.e. for SQL Express
SERVICEACCOUNTMODE localsystem | CustomUser Yes Specifies wether you want to use the local system account (localsystem) or a dedicated service account (CustomUser) for the Mirage service.
SERVICEACCOUNT Domain\Username No Needs to be specified if CustomUser is choosen as SERVICEACCOUNTMODE.
SERVICEPASSWORD Password No Needs to be specified if CustomUser is choosen as SERVICEACCOUNTMODE.
AFFECTCACHE 1 No Specifies if you want create a new local cache area (1) or let the installer decide (0) if it wants to create a new or use an existing one.
CACHEDIR C:\Program Files\Wanova Mirage\LocalCache No If AFFECTCACHE is set this parameter specifies the path to the local cache area.
CHUNKCACHESIZE 102400 No If AFFECTCACHE is set this parameter specifies the size (in megabyte) of the local cache area.

For a single-server installation using a local SQL Express installation, a local system account and a 20GB local cache in the default location the following parameters will suffice:

msiexec /i mirage.server.x64.59447.msi DBSERVER=localhost DBSERVERINSTANCE=SQLEXPRESS SERVICEACCOUNTMODE=localsystem AFFECTCACHE=1 CHUNKCACHESIZE=20480 /qr

For a multi-server installation with a dedicated SQL server and service account and also a dedicated local cache drive the following installer switches would the job: SERVICEACCOUNTMODE=CustomUser SERVICEACCOUNT=HorizonFluxMirageService SERVICEPASSWORD=TopSecretPassword AFFECTCACHE=1 CACHEDIR=E:\MirageCache CHUNKCACHESIZE=102400 /qr

Mirage WebAccess

To install the Mirage WebAccess feature (also known as File Portal) you frist have to install the Microsoft Internet Information Service (IIS) with some additionally features. This can be done using the Server Manager or using two simple PowerShell commands. For a detailed description of what IIS features are needed and how to install them using PowerShell have a look at the following of my articles: Install Horizon Mirage prerequisites via PowerShell.

After you installed the required software components you can install the file portal silently using some of the following commands:

Parameter Value Required Description
ADMIN_VIRTUAL_DIR_VAL VirtualDirectoryName No The folder on which the admin file portal should be reachable, i.e. http://mirage/VirtualDirectoryName
MGMTSERVER ServerName Yes This presents the FQDN of the Mirage management server.
VIRTUAL_DIR_VAL VirtualDirectoryName No The folder on which the file portal should be reachable, i.e. http://mirage/VirtualDirectoryName

To install the File Portal on the same machine as the Management Server using all default setting the following command can be used:

mirage.WebAccess.x64.59447.msi MGMTSERVER=localhost /qr

To install the File Portal on a dedicated machine using different virtual directory names you could use the following command:

mirage.WebAccess.x64.59447.msi ADMIN_VIRTUAL_DIR_VAL=AdminWeb VIRTUAL_DIR_VAL=Web /qr

Mirage management console

To install the Mirage management console silently you don’t have to provide any additional parameters beside /quiet. /quiet
These unattended installation commands for the server components and the console are not officially documented and therefore most likely not supported by VMware. Please test this in a development environment before using on production systems.