Hyper-V Configuration Report

Some time ago I was searching for a PowerShell Hyper-V configuration report to easily get important information about settings impacting the Hyper-V hosts performance and functionality, but i never managed to find one that was suiting my needs so i decide to create one my self.

The script is made to target multiple hosts and create a report for each host. It gathers information by invoking an script block on each host and returning a HTML fragment to combine into a report on the machine where the script i started from, then saves it as a HTML report into the specified folder.

The report collects information mainly about the host storage and network, but also essential Hyper-V information for the VM switch and live migration settings.

GitHub Download

TechNet Download

Below is some screenshots from a sample report and a full list of the information collected

Storage:

snip_20160908215147

Network:

snip_20160908215320

Operating System
OS, Version

Computer System
Manufacturer, Model, Total Memory GB, NumberOfProccessors, NumberOfLogicalProcessors, SerialNumber.

Volumes
FileSystemLabel, Drive, Path, FileSystem, HealthStatus, Size GB, Free GB, Procent Free.

MPIO
VendorId, ProductId, IsMultipathed, BusType, PathVerificationState.

MPIO Disk Info
Name, DsmName, NumberPaths.

FiberChannel Adapters
Manufacturer, Model, Active, DriverVersion, FirmwareVersion, NodeWWN, Port WWN.

Network Adapters
Name, InterfaceDescription, MacAddress, LinkSpeed, MediaConnectionState, DriverVersion, MtuSize.

IP Configuration
InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer.

DNS Enabled Adapters
InterfaceAlias, RegisterThisConnectionsAddress, Suffix.

NIC LbfoTeam
Name, Members, TeamingMode, LoadBalancingAlgorithm.

RSS Adapters
Name, Enabled, Profile, NumberOfReceiveQueues, BaseProcessorNumber, MaxProcessorNumber, MaxProcessors, BaseProcessorGroup.

VMQ Adapters
Name, Enabled, NumberOfReceiveQueues, BaseProcessorNumber, MaxProcessorNumber, MaxProcessors, BaseProcessorGroup.

RDMA Adapters
Name, Enabled, MaxInboundReadLimit, MaxOutboundReadLimit, MaxQueuePairCount.

Live Migration Settings
VirtualMachineMigrationEnabled, MaximumVMMigrations, MaximumStorageMigrations, AuthenticationType, PerformanceOption, UseAnyNetworkForMigration, VMMigrationNetwork.

VM Switch
Name, NetAdapterInterfaceDescription, SwitchType, AllowManagementOS, AvailableVMQueues, IovEnabled, Extensions.

VMs
Name, State, Generation, Status, Version, IntegrationServicesState, Path.

Installed Programs
Name, Vendor, Version.

Adding shared VHDX using PowerShell

Right now it is only possible to add a shared vhdx to virtual machines through service templates in SCVMM or on the individual Hyper-V host through Hyper-V Manager.
As the majority is not using service templates in the daily the most common way is to add shared vhdx through Hyper-V Manager.

To make this easier and/or for automating it through some self-service portal I have created a PowerShell script that can be run on the VMM server to do the job based on data from VMM.
The script requires an array of the virtual machine names, the size of the VHDX, and some credentials. The script will generate a VHDX disk file name base on the VM name concatenated into a string splitted with “-” and add “_SharedDisk” plus a number based on the number of shared disk from the first VM, example: “VM1-VM2_SharedDisk1.vhdx”. It will then create the VHDX on the first VM Hyper-V Host, in the same folder as the first VM is stored. Afterward it invokes the command on each Hyper-V host for the virtual machines to add it as a shared disk to all the virtual machines.

################################################################
#   Author: Andreas Sobczyk, CloudMechanic.net
#
#   Add Shared VHDX to VMs from SCVMM without service templates.
################################################################
$ErrorActionPreference = "Stop"

$VMNames = @("VM1","VM2")
$size = 2GB
$creds = Get-Credential

#Getting VMs
$VMs = @()
foreach($VMname in $VMNames){
$VMs += Get-SCVirtualMachine -Name $VMname
}

#region Creating Disk Name
$VM1SharedDisks = $VMs.Get(0).VirtualDiskDrives | ? {$_.HasSharedStorage -eq $true }

$DiskNumber = 1
$DiskNumberReady = $false
do{
if(($VM1SharedDisks.VirtualHardDisk.Name -like "*DISK$DiskNumber*")){
$DiskNumber+=1
}else{
$DiskNumberReady = $true
}
}

While($DiskNumberReady -ne $true)

$DiskName = ($vms -join "-")+"_SharedDisk"+$DiskNumber
#endregion


$Diskpath = $VMs.Get(0).Location+"\$DiskName.VHDX"
$DiskSharepath = "\\"+($VMs.Get(0).VMhost.name)+"\"+$Diskpath.Replace(":","$")

#Create VHDX on the first VMs host
$return1 = Invoke-Command -ComputerName $VMs.get(0).VMHost.Name -Credential $creds -ArgumentList $Diskpath,$size -ScriptBlock{
PARAM (
$Diskpath,
$Size
)
$ErrorActionPreference = "Stop"

Try{
New-VHD -Path $Diskpath -Dynamic -SizeBytes $size | Out-Null

$status = "Success"
}

Catch{
if($_.Exception.Message -like "*Update-ClusterVirtualMachineConfiguration*"){
$status = "Success"
}else{
$ErrorMessage = $_.Exception.Message
$Status = "Failed"
}
}

Finally{
$return1 = @($Status, $ErrorMessage)
$return1
}
}

if($Return1.Get(0) -ne "Success"){
Write-Error -Message $Return1.Get(1)
}


#Adding Shared VHDX to VMs
foreach($VM in $VMs){
$return2 = Invoke-Command -ComputerName $VM.VMHost.Name -Credential $creds -ArgumentList $Diskpath,($VM.Name) -ScriptBlock{
PARAM (
$Diskpath,
$VMname
)
$ErrorActionPreference = "Stop"

Try{
Add-VMHardDiskDrive -VMName $VMname -Path $Diskpath –ShareVirtualDisk | Out-Null

$status = "Success"
}

Catch{
if($_.Exception.Message -like "*Update-ClusterVirtualMachineConfiguration*"){
$status = "Success"
}else{
$ErrorMessage = $_.Exception.Message
$Status = "Failed"
}
}

Finally{
$return2 = @($Status, $ErrorMessage)
$return2
}
}
if($Return2.Get(0) -ne "Success"){
Write-Error -Message $Return2.Get(1)
}
}

Download Link