MPIO on Hyper-V Server

On the previous version of Windows Server (prior Windows Server 2012) you have to download and install MultiPath I/O (MPIO). Since Windows Server 2012 MPIO is a feature that you can enable. Because it’s a feature that comes with the server, means that you will have the PowerShell cmdlets available.

Use of the MPIO module in Windows PowerShell requires an “elevated” PowerShell window, opened with Administrator privileges.

How to do it


Installing MPIO using the GUI

If you have Hyper-V Servers, you don’t have GUI on the server, but you can do it remotely from other server or from you RSAT installed on Windows 8.1, using the Server Manager Console. Just follow the steps.

1. Open Server Manager Console

2. Browse the Hyper-V Server that you want to enable the MPIO. To do that click on All Servers and then click on the Hyper-V Server.


3. Right-Click on the Hyper-V Server and click on Add Roles and Features

4. Click 4 times Next (to go to features windows)


5. On the Select features window, select Multipath I/O and click next.


6. Click Install to enable the feature.

Installing and Managing MPIO using PowerShell

Enable or Disable the MPIO Feature

If the MPIO feature is not currently installed, use the following command to enable the MPIO feature:

Enable-WindowsOptionalFeature –Online –FeatureName MultiPathIO


To disable the MPIO feature, use the following command

Disable-WindowsOptionalFeature –Online –FeatureName MultiPathIO

Listing commands available in the MPIO module

The commands available in the MPIO module can be listed using get-command as shown below


Full help and example content for the MPIO module is available via the following method:

  • In PowerShell, after importing the MPIO module or using any MPIO cmdlet, updated help can be downloaded from the internet by running the following command:
    • Update-Help

Tips and Tricks

Configuring MPIO using PowerShell

If these steps are performed prior to connecting devices of the desired BusType, you can typically avoid the need for a restart.

  • Install the MPIO feature on a new Windows Server 2012 installation.
  • Configure MPIO to automatically claim all iSCSI devices.
  • Configure the default Load Balance policy for Round Robin.
  • Set the Windows Disk timeout to 60 seconds.

Here is what this script would look like:

# Enable the MPIO Feature

Enable-WindowsOptionalFeature –Online –FeatureName MultiPathIO

# Enable automatic claiming of ISCSI devices for MPIO

Enable-MSDSMAutomaticClaim -BusType iSCSI

# Set the default load balance policy of all newly claimed devices to Round Robin

Set-MSDSMGlobalLoadBalancePolicy -Policy RR

# Set the Windows Disk timeout to 60 seconds

Set-MPIOSetting -NewDiskTimeout 60

Hyper-V Best Practices Analyzer

Sometimes when you deploy an Hyper-V Server you don’t know if you miss any configuration or if you are following the best practices regarding security, configuration or even supportability of Hyper-V Server in case you need some help from Microsoft Support. To help us Microsoft has created a few rules to help us improve our environments — these are referred to as best practices. However, it is not easy to know all of them and to make sure your Hyper-V servers are compliant with all of these practices.

To make this job easier, Windows Server comes with the Best Practices Analyzer (BPA). It has a set of best practices and rules which it will compare against all the components of your server and it will then generate a report with all the problems that are found during the scan. The report will provide helpful details such as problems, impact, and resolutions for possible issues.

Windows Server comes with best practices for almost all the roles as well as a specific one only for Hyper-V with all the practices to analyze your host server, configuration, and virtual machines.

The Hyper-V Best Practices Analyzer works only with the pre-installed Hyper-V Role. Make sure that Hyper-V is installed and as a best practice, run the BPA after every server installation and configuration is performed.

How to do it

By following these steps, you will see how to run the best practices analyzer for Hyper-V and explore its results:

1. Open the Server Manager from the Windows Taskbar.

2. From the Server Manager window, click on Hyper-V on the pane on the left-hand side. Then use the scroll bar on the right-hand side to scroll down until the best practices analyzer option can be seen.

3. Under Best Practices Analyzer, navigate to Tasks | Start BPA Scan, as shown in the following screenshot:


4. In the Select Servers window, select the Hyper-V servers that you want to scan and click on Start Scan.

5. The scan will start on all the selected servers. When the scan has finished, the BPA results will be shown in Server Manager, under Best Practices Analyzer.

6. When completed, the scan results will be listed in three columns—Server Name, Severity, and Title. Use the filters above each column to organize the information based on your queries.

7. Click on one of the results to see the information provided by BPA. The following screenshot shows an example of a warning scan result and its description:


8. Open the results and analyze the problem, impact, and resolution for each server.

9. Use the filter at the top to find only warnings and errors.

10. After identifying the results, you can apply the resolutions provided by the Hyper-V BPA.

BPA on PowerShell

All of Windows Best Practices are available through PowerShell as well. You can scan, filter, get the results, and extract reports using the PowerShell commandlets. To start a scan using the Hyper-V BPA, type the following command:

Invoke-BpaModel –BestPracticesModelId Microsoft/Windows/Hyper-V

After invoking the Hyper-V BPA, you can use the Get-BPAResult command to analyze the results. The following command shows the BPA scan results:

Get-BpaResult –BestPracticesModelId Microsoft/Windows/Hyper-V

The following screenshot is an example of how the Get-BPAResult output could look:


If you want to filter only the warnings and the errors by using PowerShell, you can also use the following command:

Get-BpaResult -BestPracticesModelId Microsoft/Windows/Hyper-V | Where-Object {$_.Severity –eq “Warning” –or $_.Severity –eq “Error”}


The Best Practice Analyzer for Hyper-V has 74 scans to identify which settings are not configured, based on the Microsoft documentation and practices. It is enabled automatically when the Hyper-V role is installed.

When BPA scans the servers, it shows the results for every scan, providing helpful details about what was scanned, the impact, and even how to resolve any problems it finds. It will also give you the option to apply the necessary changes for your server in compliance with the best practices.

BPA is available through Server Manager and can be used at any time. The recommendation is to scan every server after their final configurations and also on a monthly basis after that.

Hyper-V BPA will also display information about Microsoft Support. If the server has a configuration that is not supported by Microsoft, it will inform you of this through the reports.

After running and applying the recommended settings, you can then be sure that your servers have all the best practices, currently recommended by Microsoft.


Tips and Tricks

Using PowerShell to create HTML reports with the BPA results to improve the PowerShell results it is possible to produce a BPA HTML report using the following command. This following script uses the previous Get-BpaResult filter example to show only the warning and the error results:

$head = ‘<style>

BODY{font-family:Verdana; background-color:lightblue;} TABLE{border-width: 1px;border-style: solid;border-color: black;bordercollapse: collapse;} TH{font-size:1.3em; border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:#FFCCCC} TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:yellow}


$header = “<H1>Hyper-V BPA Errors and Warnings Results</H1>”

$title = “Hyper-V BPA”

Get-BpaResult -BestPracticesModelId Microsoft/Windows/Hyper-V | Where-Object {$_.Severity -eq “Error” -or $_.Severity -eq “Warning”} | ConvertTo-HTML -head $head -body $header -title $title |

Out-File report.htm .report.htm

The following screenshot shows the output file that is created after running the script:


How to delegate access in Hyper-V

In some medium/large organizations, it is common practice to have different access levels for systems, such as administrator, help desk, support and auditor. When implementing virtual machine using Hyper-V Servers, it is also important to reflect these access levels as well.

Since Hyper-V 2012 makes this task easier when you need to specify particular users or groups to be Hyper-V Administrators, but you also might face scenarios where different levels are required. During the task, to add advanced permissions to a user, you will need to use groups (and recommended). You can create and use local groups or Active Directory groups.

NOTE: Make sure you have created them before you start.

How to do it

The following steps show how to delegate control for a user by using the local Hyper-V Administrators group and by using Authorization Manager (AzMan) for advanced delegations:

1. To add users or groups as members of the local Hyper-V Administrators, open the Start menu and type computer. From Search Results, click on Computer Management.

2. In the Computer Management console, expand System Tools > Local Users and Groups and click on Groups.

3. In the group list, double-click on the Hyper-V Administrators group, as shown in the following screenshot:


4. In the Hyper-V Administrators Properties window, click on Add, type the groups or users you want to add into the group, and click on OK twice.

5. To add advanced permissions for a group in Hyper-V, open the Start menu and type AzMan.msc to open the Authorization Manager console.

6. In the Authorization Manager console, right-click on Authorization Manager and select Open Authorization Store.

7. In the Open Authorization Store option, under Store Name, type the path C:ProgramDataMicrosoftWindowsHyper-VInitialStore.xml and click on OK.

8. Under the Authorization Manager console, expand Hyper-V services > Definitions, right-click on Role Definitions, and select New Role Definition.

9. In the New Role Definition window, specify the name of the role you want to use.

10. Then, under Description, specify the role description and click on OK. Role Definitions will be listed as shown in the following screenshot:


11. In the Authorization Manager console, right-click on Task Definitions and select New Task Definition.

12. In the New Task Definition window, under Name, specify the task name.

13. Then, under Description, add a description for your task and click on OK. The tasks will be listed in the right-hand pane, as shown in the following screenshot:


14. To add a definition into a task, click on Task Definition and double-click on a task.

15. Click on the Definition tab and select Add.

16. In the Add Definition window, select the Operations tab.

17. Select the operations you want from the list, as shown in the following screenshot, and click on OK:


18. To add a Task Definition into a Role Definition, click on Role Definitions and select the role you want to change.

19. In the Role Definition properties, click on the Definition tab.

20. Under the Definition tab, click on Add.

21. In the Add Definition window, select the Tasks tab, select the tasks you want to link to the Role Definition, and click on OK.

22. To assign a role, right-click on Role Assignments and select New Role Assignment.

23. In the Add Role window, select the Role Definition you want to add, and click on OK.

24. To assign a user or a group to a role, right-click on the group you want, select Assign Users and Groups, and click on From Windows and Active Directory…, as shown in the following screenshot:


25. In the Select Users or Groups window, enter the object names and click on OK.

After that, you can log in to Hyper-V as a user who is member of a group that was assigned to a role, to check the permissions that have been added.

IMPORTANT: In Windows Server 2008, 2008 R2 and 2008 R2 SP1, there is no local group to administer Hyper-V. Normally, to be able to manage Hyper-V, users are added into the local administrator group.


Since Windows Server 2012, during Hyper-V installation, a new group is created, named Hyper-V Administrators. When a user is added to this group, they can do anything regarding Hyper-V, but they don’t have any other rights on the local server.

Even with the local Hyper-V group, sometimes different access levels are required. For those scenarios, you have to use Authorization Manager (AzMan). AzMan is a framework that is used to manage the authorization policy that allows applications to perform access control. Hyper-V uses AzMan to grant access based on roles and tasks. Hyper-V authorization policies are stored in a file named InitialStore.xml, located by the path C:ProgramDataMicrosoftWindowsHyper-V. Once loaded through AzMan, you can create and delete the access policies or apply them to groups and users.

The first things to be created on AzMan are Role Definitions. These are roles that are used to receive access policies named Operations. Hyper-V has 34 operations used to grant permissions, such as to create virtual machines, allow virtual machine snapshots, and stop virtual machines. Applying these policies to many groups can be a tough job, that’s why AzMan uses Task Definitions.

Tasks Definitions can group operations in common, so that you can apply them to more than one Role Definition, making the modifications easier to make.

Using the operations and tasks, you can grant only the necessary access for users to access Hyper-V with more security and control.

Performing daily task with PowerShell to manage Hyper-V Server

As a virtualization administrator, you will come across a lot of scenarios where you will need to create, modify, move, export, and other tasks to manage your virtual machines every day. In some examples, you will need to change a few small and easy settings, which can be done via a graphical interface. However, you will also get cases where lots of virtual machines will need some advanced configuration or some settings that take a long time to complete.

It’s a fact that PowerShell is a handy and strong ally in all these examples, and this recipe will show some examples of how to perform daily tasks such as disk, network, memory, export, and virtual machine manipulation using a couple of small and simple PowerShell commandlets.

You can even perform this tasks on several Hyper-V Servers remotely without the need of login on the servers. To know how to do it, visit my previous post Managing Hyper-V Server remotely through PowerShell

NOTE: Make sure that you have a PowerShell window opened as administrator before you start.

How to do it

These tasks show lots of handy examples of daily tasks that can be used to help you administer your Hyper-V servers, such as creating and changing VHDs, virtual switches, VM tasks, migrations, and much more.

1. Let’s start with a simple command New-VHD, to create a virtual hard disk for a VM. Type the following command to create a 20GB VHDX file named NewDisk on the H: partition.

New-VHD -SizeBytes 20GB –Path H:NewDisk.vhdx

2. To add the created VHDX file to a VM, use the command Add-VMHardDiskDrive, as shown here:

Add-VMHardDiskDrive -VMName NewVM -Path H:Hyper-VNewDisk.vhdx

3. To create a new virtual switch, you can use the New-VMSwitch command. The following example creates an external switch and binds it to a network adapter called Ethernet Connection.

New-VMSwitch “External Switch” –NetAdapterName “Ethernet Connection” –AllowManagementOS $true

4. To add a network adapter to a VM, use the Add-VMNetworkAdapter command. The next command adds a network adapter named Prod NIC to all the virtual machines that start with Prod.

Add-VMNetworkAdapter -VMName Prod* -Name “Prod NIC”

5. Use the Connect-VMNetworkAdapter to add VMs to a virtual switch. The following command gets all the VMs starting with TestVM and adds to a switch called Private Switch.

Connect-VMNetworkAdapter -VMName TestVM* -SwitchName ‘Private Switch’

6. To add a legacy network adapter to a virtual machine, you can also use the Add-VMNetworkAdapter with the IsLegacy switch. The following example shows the usage of this command. This gets all the VMs starting with NewVM and adds a legacy network named BootableNIC.

Get-VM NewVM* | Add-VMNetworkAdapter -IsLegacy $true –Name BootableNIC

7. You can use the Set-VMNetworkAdapter to change the virtual machine network adapter settings. The first command below is changing the maximum and minimum bandwidth configuration to all virtual machine starting with VMTest. The second command enables Mac address spoofing to all VMs that end with NLB.

Set-VMNetworkAdapter -VMName VMTest* -MaximumBandwidth 100MB -MinimumBandwidthAbsolute 20MB

Set-VMNetworkAdapter -VMName *NLB -MacAddressSpoofing On

8. To add Fibre Channel HBAs to virtual machines you can use the Add-VMFibreChannelHBA as the next example:

Add-VMFibreChannelHba -VMName NewVM -SanName VMProd

9. You can also use basic tasks such as starting and stopping virtual machines using the Start-VM and Stop-VM commands, as shown in the following two examples:

Start-VM -Name SPVM*

Stop-VM -Name TestVM -TurnOff

10. To create virtual machine snapshots you can use the tricky command Checkpoint-VM. The next example creates a snapshot called PreMigrationSnapshot to all the VMs starting with ProdServer.

Checkpoint-VM -Name ProdServer* -SnapshotName PreMigrationSnapshot

11. To create a virtual machine from a snapshot you can use the Export-VMSnapshot command as follows:

Export-VMSnapshot -Name ‘PosUpdates’ -VMName NewVM -Path H:NewVMfromSnapshot

12. In the case of a server migration, you can use the Export-VM command to export VMs to a local folder. The following command shows a handy example of all the virtual machines being exported to a local drive in their own folders.

Get-VM | Export-VM -Path H:ExportedVMs

13. To move the virtual machine storage, use the Move-VMStorage command, specifying the destination path that you want to move the VM storage to, as shown in the following example:

Move-VMStorage NewVM -DestinationStoragePath H:NewVM

14. For moving all the storage from local VMs to a new storage, by creating a folder for each migrated VM, you can use the next example:

Get-VM | %{ Move-VMStorage $_.Name “H:Hyper-V$($_.Name)” }

15. Use the Set-VM to change the VM settings. In the next example, all servers starting with VMSharePoint are having their dynamic memory enabled with the minimum, maximum, and startup values being configured. There’s also a command which only changes the memory settings, called Set-VMMemory. The second example does exactly the same thing as the first, just using different commands.

Set-VM -Name VMSharePoint* -DynamicMemory -MemoryMinimumBytes 8GB -MemoryMaximumBytes 12GB -MemoryStartupBytes 10GB

Set-VMMemory -VMName VMSharePoint* -DynamicMemoryEnabled $true -MaximumBytes 12GB -MinimumBytes 8GB -StartupBytes 10GB



From simple tasks, such as starting a VM, to advanced ones, such as moving all virtual machine storage to a new location, it is much easier to use PowerShell rather than the GUI interface. From the 164 Hyper-V commandlets, you have seen examples of the following type (you can find all commandlets here):

  • Add-VMFibreChannelHba
  • Add-VMHardDiskDrive
  • Add-VMNetworkAdapter
  • New-VMSwitch
  • Connect-VMNetworkAdapter
  • New-VHD
  • Checkpoint-VM
  • Export-VMSnapshot
  • Move-VMStorage
  • Set-VM
  • Set-VMMemory
  • Set-VMNetworkAdapter
  • Start-VM
  • Stop-VM

These are the normal commands used day-to-day in order to create disks and networks, change VM settings, start VMs, add fibre channels adapters, create snapshots, migrate VMs, and other tasks that can be easily done via PowerShell.

You might encounter other tasks that will require different commands, but with this start, you can have an idea of commands and the things you can do via PowerShell.

Tips and Tricks

Switch Whatif

If you are not sure whether a commandlet will work or what the result will be, you can test it before you run it. The new switch Whatif added at the end of the command PowerShell can tell you whether it’s going to work or not.

The following screenshot shows a command that uses the whatif option and when executed, PowerShell explains that it will not work and why. After fixing it, you can try using the whatif command again. For the Export-VM command, you will see the What if: Export-VM will export the virtual machine “NewVM1” message.


Using PowerShell ISE for advanced script editing

For advanced and big scripts, you can use a very interesting tool named PowerShell ISE.

It offers a GUI PowerShell window with colors, line count, command predict, error verification, and a debugging option, making your scripting experience easier and faster.

The next screenshot shows an example of a script being written by PowerShell ISE with a window showing the command prediction feature, and the command column in the pane on the right-hand side.


Managing Hyper-V Server remotely through PowerShell

Working with PowerShell can be very common for daily tasks and Hyper-V Server management. However, as there is more than one server to be managed, sometimes it can be difficult to log on and run the PowerShell scripts (most of the time the same one) on different computers.

One of the benefits that PowerShell offers is the remote option that allows you to connect to multiple servers, enabling a single PowerShell window to administer as many servers as you need.

The PowerShell remote connection uses port 80, HTTP. Although the local firewall exception is created by default when it’s enabled, make sure that any other firewall has the exception to allow communication between your servers.

How to do it

These tasks will show you how to enable the PowerShell Remoting feature to manage your Hyper-V Servers remotely using PowerShell.

1. Open a PowerShell window as an administrator from the server for which you want to enable the PowerShell Remoting.

2. Type the Enable-PSRemoting commandlet to enable PowerShell Remoting.

3. The system will prompt you to confirm some settings during the setup. Select A for Yes to All to confirm all of them. Run the Enable-PSRemoting command on all the servers that you want to connect to remotely via PowerShell.

4. In order to connect to another computer in which the PowerShell Remoting is already enabled, type Connect-PSSession Hostname, where hostname is the computer name to which you want to connect.

5. To identify all the commands used to manage the PowerShell sessions, you can create a filter with the command Get-Command *PSSession*. A list of all the PSSession commands will appear, showing you all the available remote connection commands.

6. To identify which command lines from Hyper-V can be used with the remote option computername, use the Get-Command with the following parameter:

Get-Command –Module Hyper-V –ParameterName Computername

7. To use the remote PowerShell connection from PowerShell ISE, click on File and select New Remote PowerShell Tab. A window will prompt you for the computer name to which you want to connect and the username, as shown in the following screenshot. Type the computer name and the username to create the connection and click on Connect. Make sure that the destination computer also has the remoting settings enabled.


8. A new tab with the computer name to which you have connected will appear at the top, identifying all the remote connections that you have through PowerShell ISE. The following screenshot shows an example of a PowerShell ISE window with two tabs. The first one to identify the local connection called PowerShell 1 and the remote computer tab called HVHost.



The process to enable PowerShell involves the creation of a firewall exception, WinRM service configuration, and the creation of a new listener to accept requests from any IP address. PowerShell configures all these settings through a single and easy command—Enable-PSRemoting. By running this command, you will make sure that your computer has all the components enabled and configured to accept and create new remote connections using PowerShell.

Then, we identified the commands which can be used to manage the remote connections. Basically, all the commands that contain PSSession in them. Some examples are as follows:

· Connect-PSSession to create and connect to a remote connection

· Enter-PSSession to connect to an existing remote connection

· Exit-PSSession to leave the current connection

· Get-PSSession to show all existing connections

· New-PSSession to create a new session

Another interesting option that is very important, is to identify which commands support remote connections. All of them use the ComputerName switch. To show how this switch works, see the following example; a command to create a new VM is being used to create a VM on a remote computer named HVHost.

New-VM –Name VM01 –ComputerName HVHost

To identify which commands support the Computername switch, you saw the Get-Command being used with a filter to find all the commandlets. After these steps, your servers will be ready to receive and create remote connections through PowerShell.