HVDRS
1.6.1
Hyper-V Distributed Resource Scheduler — VM Happiness-based compute and storage load balancing for Failover Clusters, with affinity/anti-affinity rule enforcement
Minimum PowerShell version
5.1
Installation Options
Owners
Copyright
(c) 2026 Jason Huebel. Licensed under the MIT License.
Package Details
Author(s)
- Jason Huebel
Tags
Hyper-V HyperV DRS FailoverCluster LoadBalancing VirtualMachine VM LiveMigration StorageMigration CSV ClusterSharedVolume Affinity WindowsServer Automation
Functions
Invoke-HvDRS Get-HvDRSCluster Enable-HvDRSMaintenance Disable-HvDRSMaintenance Get-HvDRSMaintenanceStatus Enter-HvDRSNodeMaintenance Exit-HvDRSNodeMaintenance Get-HvDRSNodeMaintenanceStatus Add-HvDRSAffinityRule Get-HvDRSAffinityRule Remove-HvDRSAffinityRule Set-HvDRSAffinityRule Test-HvDRSAffinityCompliance Test-HvDRSStorageAffinityCompliance Add-HvDRSGroup Get-HvDRSGroup Remove-HvDRSGroup Set-HvDRSGroup Set-HvDRSVMAutomationLevel Get-HvDRSVMAutomationLevel Remove-HvDRSVMAutomationLevel Get-HvDRSCapacityForecast Invoke-HvStorageDRS
Dependencies
This module has no dependencies.
Release Notes
## 1.6.1
- Fixed latent bugs, of the same class fixed in 1.5.1, that only surfaced under
Set-StrictMode (which the publish pipeline enables) and were caught while
preparing this release:
- Invoke-HvStorageDRS and Test-HvDRSStorageAffinityCompliance both piped
Get-AffinityRuleSet's output directly into Where-Object to filter storage
rule types. When no rules are configured at all, this threw under strict
mode — PowerShell enumerates the ",@()" empty-result wrapper as a single
pipeline item when piped directly (rather than assigned to a variable
first), so the Where-Object script block's $_.Type access failed. Both
call sites now capture into a variable before filtering.
- Get-HvDRSVMAutomationLevel's no-"-VMName" branch returned an empty result
without the leading-comma protection Get-AffinityRuleSet and similar
loaders use, so it collapsed to $null (and threw on .Count) when no
overrides were configured for a cluster.
- Get-HvDRSCapacityForecast's -RemoveNode path could return $null for
VMPlacements/NodeImpact instead of an empty array when a node has no VMs
or a cluster has only one remaining node.
No production behavior changes for callers who already handled populated
results correctly — these only affected the zero-result / no-rules-configured
edge cases under strict-mode callers.
## 1.6.0
- Added -TrendWindow / -HistoryPath to Invoke-HvDRS: optional rolling-average
smoothing of node CPU/network utilization and VM CPU/memory-pressure across
consecutive passes, so a single transient spike doesn't trigger a migration.
Disabled by default (-TrendWindow 1) — zero behavior change unless opted in.
- Added Enter-HvDRSNodeMaintenance / Exit-HvDRSNodeMaintenance /
Get-HvDRSNodeMaintenanceStatus: happiness-aware node evacuation (a Hyper-V
analog of vSphere's "Enter Maintenance Mode") that live-migrates every VM off
a node using the same Network-Aware/memory-reserve/affinity-rule destination
selection as Invoke-HvDRS, then pauses the node — or refuses to pause it if
any VM couldn't be placed.
- Added VM/Host/CSV Groups (Add/Get/Remove/Set-HvDRSGroup) and new
-VMGroups/-HostGroups/-CSVGroups parameters on Add/Set-HvDRSAffinityRule:
reusable named groups that affinity rules can reference instead of listing
members directly. Group membership resolves dynamically at rule-load time —
editing a group takes effect immediately, with no rule re-save needed.
- Added per-VM automation-level overrides (Set/Get/Remove-HvDRSVMAutomationLevel):
pin specific VMs to Manual so Invoke-HvDRS/Invoke-HvStorageDRS keep scoring
and recommending them but never execute a migration/move for them.
- Added Get-HvDRSCapacityForecast: read-only what-if capacity analysis —
simulate draining a node (-RemoveNode) to check whether every VM on it has a
valid destination, or simulate adding a hypothetical node (-AddNode) to see
which currently-unhappy VMs it could absorb.
- Added -WebhookUrl / -WriteEventLog to Invoke-HvDRS and Invoke-HvStorageDRS:
optional JSON webhook POST and/or Windows Application event log entry
summarizing each pass. A notification failure is logged as a warning and
never fails an otherwise-successful pass.
- Added -PassThru to Invoke-HvStorageDRS (previously compute-only), and
extended the optional ProPack VMM PRO Tips integration to cover storage DRS
recommendations (ConvertTo-HvDrsStorageProTip, Resolve-VmmStorageIdentity,
Invoke-HvDrsStorageProTipProbe, and a parallel monitor/rule pair in the
Management Pack) — previously compute-only.
- Fixed a latent bug in Invoke-HvStorageDRS where its Format-Table calls were
never piped to Out-Host, so capturing its return value (now needed by
-PassThru) leaked PowerShell formatting objects onto the output stream. Same
class of bug already fixed for Invoke-HvDRS in 1.5.0.
- Moved all documentation except README.md into a new docs/ folder
(docs/INSTALL.md, docs/USAGE.md, docs/TESTS.md, docs/PUBLISH.md) and added
docs/ARCHITECTURE.md, a new technical design reference.
## 1.5.1
- Fixed three latent bugs where a zero-match result collapsed to $null instead
of an empty array/collection at a function or switch-expression output
boundary: Find-MigrationCandidates (no migrations recommended),
Get-HvDRSAffinityRule (no rules match a filter), and an internal switch-to-
variable assignment in the same function. These were silently tolerated by
PowerShell's default null.Count convenience behavior but threw under
Set-StrictMode, which the publish pipeline enables — surfaced while
preparing this release. No behavior change for non-strict-mode callers.
## 1.5.0
- Added -PassThru to Invoke-HvDRS: emits each migration recommendation as a structured
object (ClusterName, VMName, VMId, SourceNode, DestinationNode, scores, ComplianceReason)
in addition to the existing console output, for programmatic consumers. Fully additive
and backward compatible — omitting the switch preserves prior behavior.
- Fixed internal Format-Table calls leaking formatting objects onto the function's output
stream when callers capture Invoke-HvDRS's return value; they now render to the console
only via Out-Host.
## 1.4.0
- Added Get-HvDRSCluster: lightweight, read-only discovery of cluster nodes, VMs, and
Cluster Shared Volumes, with no performance-counter collection and no migrations proposed
## 1.3.0
- CRITICAL FIX: the module manifest was missing RootModule, so Import-Module HVDRS
never loaded HVDRS.psm1 and exported zero functions in every prior published
version. RootModule = 'HVDRS.psm1' is now set and the module works correctly.
- Fixed Get-AffinityRuleSet returning $null instead of an empty array on a fresh
rules store, which broke adding the very first affinity rule
- Added storage-specific affinity/anti-affinity rules: VmVmCsvAffinity, VmVmCsvAntiAffinity,
VmCsvAffinity, VmCsvAntiAffinity
- Add-HvDRSAffinityRule / Set-HvDRSAffinityRule accept -CSVs (and -AddCSVs/-RemoveCSVs)
- Invoke-HvStorageDRS now loads storage rules, runs a compliance pass ahead of the
happiness pass, and applies soft-rule penalties / compliance bonuses to candidate scoring
- Added Test-HvDRSStorageAffinityCompliance for live VM-to-CSV placement auditing
## 1.2.1
- Documentation only: promoted PowerShell Gallery install to the recommended option in INSTALL.md
- Updated README Quick Start to use Install-Module instead of Copy-Item
## 1.2.0
- Added per-cluster scoping for affinity/anti-affinity rules
- Rules stored in shared JSON file are now filtered by ClusterName at load time
- Add-HvDRSAffinityRule, Get-HvDRSAffinityRule, Remove-HvDRSAffinityRule all accept -ClusterName
- Same rule name may now exist independently across different clusters
## 1.1.0
- Added Storage DRS (Invoke-HvStorageDRS): CSV space and latency happiness scoring,
greedy storage migration planner, Move-VMStorage execution
- Added affinity/anti-affinity rules (VmVmAffinity, VmVmAntiAffinity, VmHostAffinity,
VmHostAntiAffinity) with hard (enforced) and soft enforcement modes
- Added two-pass migration planner: compliance pass fixes hard violations first,
happiness pass applies rule impact scoring
- Added Test-HvDRSAffinityCompliance for live placement auditing
## 1.0.0
- Initial release: VM Happiness scoring, compute DRS, Network-Aware destination
filtering, aggression levels 1–5, maintenance mode
FileList
- HVDRS.nuspec
- LICENSE
- HVDRS.psd1
- docs\TESTS.md
- docs\ARCHITECTURE.md
- Functions\Public\Invoke-HvStorageDRS.ps1
- Functions\Public\Groups.ps1
- Functions\Public\Get-HvDRSCapacityForecast.ps1
- Functions\Public\AffinityRules.ps1
- Functions\Private\Test-AffinityCompliance.ps1
- Functions\Private\Merge-HvDRSTrendSnapshot.ps1
- Functions\Private\Measure-CsvHappiness.ps1
- Functions\Private\Get-StorageSnapshot.ps1
- Functions\Private\Get-StorageMigrationRuleImpact.ps1
- Functions\Private\Get-MigrationRuleImpact.ps1
- Functions\Private\Get-HvDRSGroupSet.ps1
- Functions\Private\Get-HvDRSDataRoot.ps1
- Functions\Private\Get-HvDRSAutomationOverrideSet.ps1
- Functions\Private\Get-ClusterSnapshot.ps1
- Functions\Private\Get-ClusterInventory.ps1
- Functions\Private\Get-AffinityRuleSet.ps1
- Functions\Private\Find-StorageMigrationCandidates.ps1
- Functions\Private\Find-MigrationCandidates.ps1
- Functions\Private\Find-EvacuationDestination.ps1
- README.md
- HVDRS.psm1
- docs\USAGE.md
- docs\INSTALL.md
- Functions\Public\Maintenance.ps1
- Functions\Public\Invoke-HvDRS.ps1
- Functions\Public\Get-HvDRSCluster.ps1
- Functions\Public\AutomationOverrides.ps1
- Functions\Private\Test-StorageAffinityCompliance.ps1
- Functions\Private\Send-HvDRSNotification.ps1
- Functions\Private\Measure-VmHappiness.ps1