Hosts
iSCSI: HVISCSI01..04
FC: HVFC01..04
SMB: HVSMB01..04
Clusters
iSCSI: HVCLU-ISCSI @ 10.10.10.51
FC: HVCLU-FC @ 10.10.10.52
SMB: HVCLU-SMB @ 10.10.10.53
Networks
Mgmt/Cluster: VLAN 10, 10.10.10.0/24, GW 10.10.10.1
Live Migration: VLAN 20, 10.10.20.0/24, (no GW)
Storage (iSCSI/SMB): VLAN 30, 10.10.30.0/24, (no GW)
Witness: \\fs-witness\hvwitness$
iSCSI portal: 10.10.30.10
SMB SOFS shares: \\SOFS01\HVShare1, \\SOFS01\HVShare2 (Continuously Available)
Teaming: Team0 (Switch-Independent, Dynamic), vSwitch: vSwitch-Prod
VMM: Server VMM01, RunAs VMM-SVC (domain acct; local admin on hosts)
# ===== Globals =====
$Hosts_iSCSI = @('HVISCSI01','HVISCSI02','HVISCSI03','HVISCSI04')
$Hosts_FC    = @('HVFC01','HVFC02','HVFC03','HVFC04')
$Hosts_SMB   = @('HVSMB01','HVSMB02','HVSMB03','HVSMB04')
$CluName_iSCSI = 'HVCLU-ISCSI'; $CluIP_iSCSI = '10.10.10.51'
$CluName_FC    = 'HVCLU-FC';    $CluIP_FC    = '10.10.10.52'
$CluName_SMB   = 'HVCLU-SMB';   $CluIP_SMB   = '10.10.10.53'
$VLAN_Mgmt = 10; $Subnet_Mgmt = '10.10.10.0/24'; $GW_Mgmt = '10.10.10.1'
$VLAN_LM   = 20; $Subnet_LM   = '10.10.20.0/24'
$VLAN_Stor = 30; $Subnet_Stor = '10.10.30.0/24'
$TeamName    = 'Team0'
$ProdVSwitch = 'vSwitch-Prod'
$WitnessShare = '\\fs-witness\hvwitness$'
$iSCSIPortal  = '10.10.30.10'
$SMB_Stores   = @('\\SOFS01\HVShare1','\\SOFS01\HVShare2')
$VMMServer = 'VMM01'
$RunAsName = 'VMM-SVC'
# Roles & tools
Install-WindowsFeature Hyper-V, Failover-Clustering, Multipath-IO -IncludeManagementTools
# iSCSI DSM example (harmless if no iSCSI HBA present; adjust for your array if needed)
mpclaim.exe -r -i -a "VEN_MSFT&PROD_iSCSI"
# NIC Team + vSwitch
New-NetLbfoTeam -Name $TeamName -TeamMembers 'NIC1','NIC2' -TeamingMode SwitchIndependent -LoadBalancingAlgorithm Dynamic
New-VMSwitch -Name $ProdVSwitch -NetAdapterName $TeamName -AllowManagementOS $true
# Live Migration tuning
(Get-VMHost).VirtualMachineMigrationPerformanceOption = 'Compression'
Set-VMHost -VirtualMachineMigrationEnabled $true -VirtualMachineMigrationAuthenticationType CredSSP -VirtualMachineMigrationMaximum 4
Set-Service MSiSCSI -StartupType Automatic; Start-Service MSiSCSI
New-IscsiTargetPortal -TargetPortalAddress $iSCSIPortal
Get-IscsiTarget | Connect-IscsiTarget -IsPersistent $true -IsMultipathEnabled $true
Mask same LUNs to all 4 FC hosts (identical LUN IDs).
Confirm Get-Disk shows them on all nodes before clustering.
On SOFS: ensure shares are Continuously Available and grant Full Control to host computer accounts and VMM-SVC.
Test-Cluster -Node $Hosts_iSCSI -Include 'Inventory','Network','Storage'
New-Cluster -Name $CluName_iSCSI -Node $Hosts_iSCSI -StaticAddress $CluIP_iSCSI -NoStorage
Set-ClusterQuorum -FileShareWitness $WitnessShare
# Add & convert all LUNs to CSV
Get-ClusterAvailableDisk | Add-ClusterDisk
Get-ClusterResource | ? ResourceType -eq 'Physical Disk' | % { Add-ClusterSharedVolume -Name $_.Name }
# Optional: tag networks (names must match your cluster networks)
(Get-ClusterNetwork 'StorageNet').Role = 1     # ClusterOnly
(Get-ClusterNetwork 'LiveMigrationNet').Role = 3
(Get-ClusterNetwork 'ManagementNet').Role = 3
Test-Cluster -Node $Hosts_FC -Include 'Inventory','Network','Storage'
New-Cluster -Name $CluName_FC -Node $Hosts_FC -StaticAddress $CluIP_FC -NoStorage
Set-ClusterQuorum -FileShareWitness $WitnessShare
Get-ClusterAvailableDisk | Add-ClusterDisk
Get-ClusterResource | ? ResourceType -eq 'Physical Disk' | % { Add-ClusterSharedVolume -Name $_.Name }
(Get-ClusterNetwork 'StorageNet').Role = 1
(Get-ClusterNetwork 'LiveMigrationNet').Role = 3
(Get-ClusterNetwork 'ManagementNet').Role = 3
Test-Cluster -Node $Hosts_SMB -Include 'Inventory','Network'
New-Cluster -Name $CluName_SMB -Node $Hosts_SMB -StaticAddress $CluIP_SMB -NoStorage
Set-ClusterQuorum -FileShareWitness $WitnessShare
(Get-ClusterNetwork 'StorageNet').Role = 1
(Get-ClusterNetwork 'LiveMigrationNet').Role = 3
(Get-ClusterNetwork 'ManagementNet').Role = 3
Console path: Fabric → Servers → Add Resources → Hyper-V Hosts and Clusters → Windows Server computers in a trusted AD domain → add the hosts (VMM discovers their clusters) → pick Host Group → Finish.
(PowerShell skeleton)
Import-Module VirtualMachineManager
$vmm   = Get-SCVMMServer -ComputerName $VMMServer
$runAs = Get-SCRunAsAccount -VMMServer $vmm | ? {$_.Name -eq $RunAsName}
# Add at least 2 nodes per cluster (discovery will bring in the cluster object)
$Hosts_iSCSI | % { Add-SCVMHost -VMMServer $vmm -ComputerName $_ -Credential $runAs }
$Hosts_FC    | % { Add-SCVMHost -VMMServer $vmm -ComputerName $_ -Credential $runAs }
$Hosts_SMB   | % { Add-SCVMHost -VMMServer $vmm -ComputerName $_ -Credential $runAs }
Add standalone hosts to VMM (Fabric → Add Resources).
Fabric → Create Host Cluster (run 3 times: iSCSI, FC, SMB): pick 4 hosts, set Cluster Name/IP, wizard runs validation, select storage (LUNs for iSCSI/FC → CSV; Shares for SMB), done.
(PowerShell to add hosts is the same as above; the Create Host Cluster wizard is the most reliable path in 2012 R2).
This creates Logical Networks + Sites, IP Pools, Classifications, Uplink Profiles, and a Logical Switch you can apply to each host.
Import-Module VirtualMachineManager
$vmm   = Get-SCVMMServer -ComputerName $VMMServer
# ----- Logical Networks -----
$lnMgmt = New-SCLogicalNetwork -Name 'MgmtNet' -EnableNetworkVirtualization $false -VMHostGroup 'All Hosts'
$lnLM   = New-SCLogicalNetwork -Name 'LiveMigNet' -EnableNetworkVirtualization $false -VMHostGroup 'All Hosts'
$lnStor = New-SCLogicalNetwork -Name 'StorageNet' -EnableNetworkVirtualization $false -VMHostGroup 'All Hosts'
$lnVM   = New-SCLogicalNetwork -Name 'VMNet' -EnableNetworkVirtualization $false -VMHostGroup 'All Hosts'
# ----- Network Sites (VLANs/Subnets) -----
$siteMgmt = New-SCLogicalNetworkDefinition -Name 'Mgmt_Site' -LogicalNetwork $lnMgmt -VMHostGroup 'All Hosts'
New-SCSubnetVLan -LogicalNetworkDefinition $siteMgmt -Subnet $Subnet_Mgmt -VLanID $VLAN_Mgmt
$siteLM = New-SCLogicalNetworkDefinition -Name 'LM_Site' -LogicalNetwork $lnLM -VMHostGroup 'All Hosts'
New-SCSubnetVLan -LogicalNetworkDefinition $siteLM -Subnet $Subnet_LM -VLanID $VLAN_LM
$siteStor = New-SCLogicalNetworkDefinition -Name 'Storage_Site' -LogicalNetwork $lnStor -VMHostGroup 'All Hosts'
New-SCSubnetVLan -LogicalNetworkDefinition $siteStor -Subnet $Subnet_Stor -VLanID $VLAN_Stor
$siteVM = New-SCLogicalNetworkDefinition -Name 'VM_Site' -LogicalNetwork $lnVM -VMHostGroup 'All Hosts'
# Example VM VLAN (adjust or add more as needed)
New-SCSubnetVLan -LogicalNetworkDefinition $siteVM -Subnet '10.10.40.0/24' -VLanID 40
# ----- IP Pools (Mgmt / LM / Storage) -----
# Mgmt pool (with gateway)
$poolMgmt = New-SCStaticIPAddressPool -Name 'MgmtPool' -LogicalNetworkDefinition $siteMgmt `
  -Subnet '10.10.10.0/24' -IPAddressRangeStart '10.10.10.100' -IPAddressRangeEnd '10.10.10.199' `
  -DefaultGateway $GW_Mgmt -DNSServer '10.10.10.11','10.10.10.12'
# Live Migration pool (no gateway)
$poolLM = New-SCStaticIPAddressPool -Name 'LMPool' -LogicalNetworkDefinition $siteLM `
  -Subnet '10.10.20.0/24' -IPAddressRangeStart '10.10.20.100' -IPAddressRangeEnd '10.10.20.199'
# Storage pool (no gateway)
$poolStor = New-SCStaticIPAddressPool -Name 'StoragePool' -LogicalNetworkDefinition $siteStor `
  -Subnet '10.10.30.0/24' -IPAddressRangeStart '10.10.30.100' -IPAddressRangeEnd '10.10.30.199'
# ----- Port Classifications -----
$pcHost = New-SCPortClassification -Name 'Host Mgmt'
$pcVM   = New-SCPortClassification -Name 'VM Prod'
# ----- Uplink Port Profile (binds LNets to the team) -----
$upl = New-SCNativeUplinkPortProfile -Name 'UPP-Team0' -LogicalNetwork $lnMgmt,$lnLM,$lnStor,$lnVM `
       -LoadBalancingAlgorithm Dynamic -TeamingMode SwitchIndependent
# ----- Logical Switch -----
$ls = New-SCLogicalSwitch -Name 'LS-Prod' -UplinkPortProfile $upl -MinimumBandwidthMode Weight
# (Console) Apply Logical Switch:
# Host -> Properties -> Virtual Switches -> New Virtual Switch (Logical) -> choose LS-Prod + UPP-Team0
Storage in VMM
iSCSI/FC: Fabric → Storage → Providers → add SMI-S provider; classify tiers (Gold/ Silver). Allocate LUNs to each cluster → they appear as CSV under the cluster in VMM.
SMB: Fabric → Storage → File Servers → add SOFS01 → add HVShare1/2 → assign access to the SMB cluster hosts.
# Create a test VM on CSV (iSCSI/FC cluster example)
New-VM -Name 'TestVM01' -MemoryStartupBytes 2GB -Generation 2 `
  -Path 'C:\ClusterStorage\Volume1\VMs\TestVM01' -SwitchName $ProdVSwitch
New-VHD -Path 'C:\ClusterStorage\Volume1\VMs\TestVM01\TestVM01.vhdx' -SizeBytes 60GB -Dynamic
Add-VMHardDiskDrive -VMName 'TestVM01' -Path 'C:\ClusterStorage\Volume1\VMs\TestVM01\TestVM01.vhdx'
Start-VM TestVM01
Move-ClusterVirtualMachineRole -Name 'TestVM01' -Node (Get-ClusterNode | ? {$_.State -eq 'Up'} | Select -First 1 -Skip 1).Name
For SMB cluster, place the VM path on \\SOFS01\HVShare1\VMs\... and repeat.
AD permissions: Pre-stage CNOs or grant hosts (or VMM-SVC) Create Computer Objects on the hosts’ OU.
CSV format on 2012 R2: NTFS (don’t use early ReFS for Hyper-V).
AV exclusions: C:\ClusterStorage\, Hyper-V processes, and VM file types.
Live Migration: Compression (default above). Use RDMA/SMB LM only if end-to-end supported.
MPIO: Confirm recommended policy from your storage vendor; verify pathing per node.
SMB shares: Must be Continuously Available; perms to computer accounts + VMM-SVC.
CAU: Use Cluster-Aware Updating (or VMM Servicing) to patch with zero/low downtime.
Recovery: Clear-ClusterDiskReservation -All if disks stuck; remove bad resources and re-add.