[{"data":1,"prerenderedAt":3401},["ShallowReactive",2],{"post:\u002F2025\u002F07\u002F09\u002Fpowershell-hyper-v-script-a-failover-cluster-deployment-end-to-end\u002F":3},{"post":4,"newer":3349,"older":3359,"related":3371,"series":3399},{"id":5,"title":6,"body":7,"canonical":3330,"categories":3331,"date":3334,"description":3335,"extension":3336,"featured":3337,"hero":3338,"image":3338,"meta":3339,"navigation":811,"path":3340,"readingTime":527,"seo":3341,"series":3338,"seriesOrder":3338,"sites":3342,"source":3338,"stem":3343,"tags":3344,"updated":3338,"url":3347,"__hash__":3348},"blog\u002Fblog\u002F2025\u002F07\u002F09\u002Fpowershell-hyper-v-script-a-failover-cluster-deployment-end-to-end.md","PowerShell: Hyper-V – Script a Failover Cluster Deployment End to End",{"type":8,"value":9,"toc":3322},"minimark",[10,14,19,72,76,313,317,320,411,414,477,480,488,492,3178,3182,3259,3263,3318],[11,12,13],"p",{},"I keep coming back to the same complaint about Hyper-V failover clustering: every guide walks you through the wizard, but almost nothing hands you a script you can run twice and trust to produce the same cluster both times. This is the script I use to stand up a new Hyper-V cluster of two or more nodes, from feature installation through validation, quorum, a working Cluster Shared Volume (or a Storage Spaces Direct pool) and a pinned Live Migration network. Every stage checks whether its work is already done, so a run that dies halfway can simply be started again.",[15,16,18],"h2",{"id":17},"requirements","Requirements",[20,21,22,26,34,45,51,58,69],"ul",{},[23,24,25],"li",{},"Windows Server 2019 or later on every node, domain joined. Storage Spaces Direct needs Datacenter edition on every node; a SAN-backed cluster does not.",[23,27,28,29,33],{},"Run it from a management server or workstation, not from one of the nodes: the script restarts nodes after installing Hyper-V. Microsoft recommends the management machine run the same Windows version as the nodes (a down-level machine may leave you needing ",[30,31,32],"code",{},"Update-ClusterFunctionalLevel"," afterwards), with the Hyper-V and Failover Clustering RSAT modules installed.",[23,35,36,37,40,41,44],{},"Run it in a local elevated session on that machine, not inside ",[30,38,39],{},"Enter-PSSession",". ",[30,42,43],{},"New-Cluster"," cannot run in a remote session without CredSSP, and the S2D steps are documented as local-session only.",[23,46,47,48,50],{},"Local administrator on every node, and Create Computer Objects on the target OU (or a pre-staged Cluster Name Object), because ",[30,49,43],{}," registers the CNO in Active Directory.",[23,52,53,54,57],{},"WinRM reachable on every node (",[30,55,56],{},"Enable-PSRemoting"," if it is not already on).",[23,59,60,61],{},"Storage, one of:\n",[20,62,63,66],{},[23,64,65],{},"A shared LUN presented to every node (iSCSI, Fibre Channel or SAS), initialized as GPT and formatted NTFS. Microsoft's CSV guidance is NTFS for SAN volumes; ReFS on a SAN runs the CSV in redirected mode, sending all writes through the coordinator node.",[23,67,68],{},"Local drives for Storage Spaces Direct: empty (no partitions), identical in count and type on every node, and SSDs with power-loss protection.",[23,70,71],{},"A free static IP on the management subnet for the cluster name, and, for a two-node cluster, an Azure storage account (Standard general-purpose v2) or an SMB share for the witness.",[15,73,75],{"id":74},"parameters","Parameters",[77,78,79,98],"table",{},[80,81,82],"thead",{},[83,84,85,89,92,95],"tr",{},[86,87,88],"th",{},"Name",[86,90,91],{},"Type",[86,93,94],{},"Required",[86,96,97],{},"Description",[99,100,101,125,139,153,173,192,210,239,253,267,281,295],"tbody",{},[83,102,103,109,115,118],{},[104,105,106],"td",{},[30,107,108],{},"NodeNames",[104,110,111,112],{},"string",[113,114],"span",{},[104,116,117],{},"Yes",[104,119,120,121,124],{},"Hostnames of the Hyper-V hosts to cluster (2 to 64; 2 to 16 with ",[30,122,123],{},"-StorageSpacesDirect",").",[83,126,127,132,134,136],{},[104,128,129],{},[30,130,131],{},"ClusterName",[104,133,111],{},[104,135,117],{},[104,137,138],{},"NetBIOS name for the Cluster Name Object, 15 characters or fewer.",[83,140,141,146,148,150],{},[104,142,143],{},[30,144,145],{},"ClusterIPAddress",[104,147,111],{},[104,149,117],{},[104,151,152],{},"Static IPv4 address for the cluster network name.",[83,154,155,160,163,166],{},[104,156,157],{},[30,158,159],{},"SharedDiskNumber",[104,161,162],{},"int",[104,164,165],{},"No",[104,167,168,169,172],{},"Number of the shared LUN, as ",[30,170,171],{},"Get-ClusterAvailableDisk"," reports it, to add as a CSV. Omit to skip SAN storage.",[83,174,175,180,183,185],{},[104,176,177],{},[30,178,179],{},"StorageSpacesDirect",[104,181,182],{},"switch",[104,184,165],{},[104,186,187,188,191],{},"Validate with the S2D test set and run ",[30,189,190],{},"Enable-ClusterStorageSpacesDirect"," instead of adding a SAN disk.",[83,193,194,199,201,203],{},[104,195,196],{},[30,197,198],{},"LiveMigrationSubnet",[104,200,111],{},[104,202,165],{},[104,204,205,206,209],{},"CIDR of the cluster network Live Migration must use, for example ",[30,207,208],{},"10.10.40.0\u002F24",". Every other cluster network is excluded.",[83,211,212,217,219,221],{},[104,213,214],{},[30,215,216],{},"MigrationPerformanceOption",[104,218,111],{},[104,220,165],{},[104,222,223,226,227,230,231,234,235,238],{},[30,224,225],{},"TCPIP",", ",[30,228,229],{},"Compression"," or ",[30,232,233],{},"SMB",", applied to every node with ",[30,236,237],{},"Set-VMHost",". Omit to leave the default (Compression).",[83,240,241,246,248,250],{},[104,242,243],{},[30,244,245],{},"CloudWitnessAccountName",[104,247,111],{},[104,249,165],{},[104,251,252],{},"Azure storage account for a cloud witness.",[83,254,255,260,262,264],{},[104,256,257],{},[30,258,259],{},"CloudWitnessAccessKey",[104,261,111],{},[104,263,165],{},[104,265,266],{},"Access key for that storage account (use the primary key the first time).",[83,268,269,274,276,278],{},[104,270,271],{},[30,272,273],{},"FileShareWitness",[104,275,111],{},[104,277,165],{},[104,279,280],{},"UNC path of a file share witness, used when no cloud witness is given.",[83,282,283,288,290,292],{},[104,284,285],{},[30,286,287],{},"ReportFolder",[104,289,111],{},[104,291,165],{},[104,293,294],{},"Folder for the validation report. Defaults to the current directory.",[83,296,297,302,304,306],{},[104,298,299],{},[30,300,301],{},"SkipValidation",[104,303,182],{},[104,305,165],{},[104,307,308,309,312],{},"Skips ",[30,310,311],{},"Test-Cluster",". Only for a lab rebuild of nodes you validated already; production clusters should never skip it.",[15,314,316],{"id":315},"usage","Usage",[11,318,319],{},"Build a two-node SAN-backed cluster with a CSV, a cloud witness and a dedicated Live Migration subnet.",[321,322,327],"pre",{"className":323,"code":324,"language":325,"meta":326,"style":326},"language-powershell shiki shiki-themes github-dark",".\\New-HyperVCluster.ps1 -NodeNames 'hv-node01', 'hv-node02' -ClusterName 'hv-clu01' -ClusterIPAddress '10.10.10.50' -SharedDiskNumber 2 -LiveMigrationSubnet '10.10.40.0\u002F24' -CloudWitnessAccountName '\u003Cstorageaccount>' -CloudWitnessAccessKey '\u003Caccess-key>' -Verbose\n","powershell","",[30,328,329],{"__ignoreMap":326},[113,330,333,337,341,345,348,352,355,358,360,363,366,368,371,374,376,379,382,384,387,390,392,395,398,400,403,406,408],{"class":331,"line":332},"line",1,[113,334,336],{"class":335},"s95oV",".",[113,338,340],{"class":339},"sDLfK","\\New-HyperVCluster.ps1",[113,342,344],{"class":343},"snl16"," -",[113,346,347],{"class":335},"NodeNames ",[113,349,351],{"class":350},"sU2Wk","'hv-node01'",[113,353,354],{"class":343},",",[113,356,357],{"class":350}," 'hv-node02'",[113,359,344],{"class":343},[113,361,362],{"class":335},"ClusterName ",[113,364,365],{"class":350},"'hv-clu01'",[113,367,344],{"class":343},[113,369,370],{"class":335},"ClusterIPAddress ",[113,372,373],{"class":350},"'10.10.10.50'",[113,375,344],{"class":343},[113,377,378],{"class":335},"SharedDiskNumber ",[113,380,381],{"class":339},"2",[113,383,344],{"class":343},[113,385,386],{"class":335},"LiveMigrationSubnet ",[113,388,389],{"class":350},"'10.10.40.0\u002F24'",[113,391,344],{"class":343},[113,393,394],{"class":335},"CloudWitnessAccountName ",[113,396,397],{"class":350},"'\u003Cstorageaccount>'",[113,399,344],{"class":343},[113,401,402],{"class":335},"CloudWitnessAccessKey ",[113,404,405],{"class":350},"'\u003Caccess-key>'",[113,407,344],{"class":343},[113,409,410],{"class":335},"Verbose\n",[11,412,413],{},"Build a two-node Storage Spaces Direct cluster that uses SMB for Live Migration and a file share witness on a NAS.",[321,415,417],{"className":323,"code":416,"language":325,"meta":326,"style":326},".\\New-HyperVCluster.ps1 -NodeNames 'hv-node03', 'hv-node04' -ClusterName 'hv-clu02' -ClusterIPAddress '10.10.10.51' -StorageSpacesDirect -LiveMigrationSubnet '10.10.41.0\u002F24' -MigrationPerformanceOption SMB -FileShareWitness '\\\\nas01\\witness-hv-clu02'\n",[30,418,419],{"__ignoreMap":326},[113,420,421,423,425,427,429,432,434,437,439,441,444,446,448,451,453,456,459,461,464,466,469,471,474],{"class":331,"line":332},[113,422,336],{"class":335},[113,424,340],{"class":339},[113,426,344],{"class":343},[113,428,347],{"class":335},[113,430,431],{"class":350},"'hv-node03'",[113,433,354],{"class":343},[113,435,436],{"class":350}," 'hv-node04'",[113,438,344],{"class":343},[113,440,362],{"class":335},[113,442,443],{"class":350},"'hv-clu02'",[113,445,344],{"class":343},[113,447,370],{"class":335},[113,449,450],{"class":350},"'10.10.10.51'",[113,452,344],{"class":343},[113,454,455],{"class":335},"StorageSpacesDirect ",[113,457,458],{"class":343},"-",[113,460,386],{"class":335},[113,462,463],{"class":350},"'10.10.41.0\u002F24'",[113,465,344],{"class":343},[113,467,468],{"class":335},"MigrationPerformanceOption SMB ",[113,470,458],{"class":343},[113,472,473],{"class":335},"FileShareWitness ",[113,475,476],{"class":350},"'\\\\nas01\\witness-hv-clu02'\n",[11,478,479],{},"The run ends with a summary object you can paste into the change record.",[321,481,486],{"className":482,"code":484,"language":485,"meta":326},[483],"language-text","Cluster       : hv-clu01\nNodes         : hv-node01 (Up), hv-node02 (Up)\nQuorum        : Cloud Witness\nCSVs          : Cluster Disk 1 -> C:\\ClusterStorage\\Volume1\nLiveMigration : Cluster Network 3 (10.10.40.0)\nReport        : C:\\Build\\Validate-hv-clu01-20250709-1402.htm\n","text",[30,487,484],{"__ignoreMap":326},[15,489,491],{"id":490},"script","Script",[321,493,495],{"className":323,"code":494,"language":325,"meta":326,"style":326},"\u003C#\n.SYNOPSIS\n    Builds a Hyper-V failover cluster end to end: features, validation, cluster, quorum, storage and Live Migration network.\n.DESCRIPTION\n    Installs Hyper-V, Failover Clustering and their PowerShell modules on every node (restarting nodes that\n    need it), runs cluster validation, creates the cluster without claiming storage, configures a cloud or\n    file share witness, then either adds a shared SAN disk as a Cluster Shared Volume or enables Storage\n    Spaces Direct. Finally it restricts Live Migration to one cluster network by setting\n    MigrationExcludeNetworks on the Virtual Machine resource type. Each stage checks for existing work, so\n    the script can be re-run after a failure.\n.PARAMETER NodeNames\n    Hostnames of the Hyper-V hosts to cluster (2 to 64; 2 to 16 with -StorageSpacesDirect).\n.PARAMETER ClusterName\n    NetBIOS name for the Cluster Name Object, 15 characters or fewer.\n.PARAMETER ClusterIPAddress\n    Static IPv4 address for the cluster network name.\n.PARAMETER SharedDiskNumber\n    Number of the shared LUN, as Get-ClusterAvailableDisk reports it, to add as a CSV.\n.PARAMETER StorageSpacesDirect\n    Validate with the S2D test set and run Enable-ClusterStorageSpacesDirect instead of adding a SAN disk.\n.PARAMETER LiveMigrationSubnet\n    CIDR of the cluster network Live Migration must use. Every other cluster network is excluded.\n.PARAMETER MigrationPerformanceOption\n    TCPIP, Compression or SMB, applied to every node with Set-VMHost.\n.PARAMETER CloudWitnessAccountName\n    Azure storage account for a cloud witness.\n.PARAMETER CloudWitnessAccessKey\n    Access key for that storage account.\n.PARAMETER FileShareWitness\n    UNC path of a file share witness, used when no cloud witness is given.\n.PARAMETER ReportFolder\n    Folder for the validation report. Defaults to the current directory.\n.PARAMETER SkipValidation\n    Skips Test-Cluster. Not recommended outside of a lab rebuild.\n.EXAMPLE\n    .\\New-HyperVCluster.ps1 -NodeNames 'hv-node01', 'hv-node02' -ClusterName 'hv-clu01' -ClusterIPAddress '10.10.10.50' -SharedDiskNumber 2 -CloudWitnessAccountName '\u003Cstorageaccount>' -CloudWitnessAccessKey '\u003Caccess-key>'\n.NOTES\n    Author  : Thomas Lasswell (https:\u002F\u002Fwww.techcolumnist.com)\n    Version : 1.0 (2025-07-09)\n    Requires: Windows Server 2019+ nodes, FailoverClusters and Hyper-V modules on the machine running it,\n              WinRM to every node, rights to create the cluster computer object\n#>\n\n[CmdletBinding()]\nparam (\n    [Parameter(Mandatory = $true)]\n    [ValidateCount(2, 64)]\n    [string[]]$NodeNames,\n\n    [Parameter(Mandatory = $true)]\n    [ValidateLength(1, 15)]\n    [string]$ClusterName,\n\n    [Parameter(Mandatory = $true)]\n    [string]$ClusterIPAddress,\n\n    [Parameter(Mandatory = $false)]\n    [int]$SharedDiskNumber,\n\n    [switch]$StorageSpacesDirect,\n\n    [Parameter(Mandatory = $false)]\n    [string]$LiveMigrationSubnet,\n\n    [Parameter(Mandatory = $false)]\n    [ValidateSet('TCPIP', 'Compression', 'SMB')]\n    [string]$MigrationPerformanceOption,\n\n    [Parameter(Mandatory = $false)]\n    [string]$CloudWitnessAccountName,\n\n    [Parameter(Mandatory = $false)]\n    [string]$CloudWitnessAccessKey,\n\n    [Parameter(Mandatory = $false)]\n    [string]$FileShareWitness,\n\n    [Parameter(Mandatory = $false)]\n    [string]$ReportFolder = (Get-Location).Path,\n\n    [switch]$SkipValidation\n)\n\n$ErrorActionPreference = 'Stop'\n\n# A failover cluster supports up to 64 nodes, but Storage Spaces Direct supports at most 16 servers.\nif ($StorageSpacesDirect -and $NodeNames.Count -gt 16) {\n    throw \"Storage Spaces Direct supports at most 16 nodes; $($NodeNames.Count) were given.\"\n}\n\n$featureNames = @('Hyper-V', 'Failover-Clustering', 'Hyper-V-PowerShell', 'RSAT-Clustering-PowerShell')\n\n# A new cluster name can take a while to resolve in DNS, so talk to the cluster through its first node.\n$clusterTarget = $NodeNames[0]\n\n# Stage 1: install roles and features, restarting any node that needs it.\nforeach ($node in $NodeNames) {\n    Write-Verbose \"Checking Hyper-V and clustering features on $node\"\n\n    $installResult = Invoke-Command -ComputerName $node -ScriptBlock {\n        $missing = Get-WindowsFeature -Name $using:featureNames |\n            Where-Object { $_.InstallState -ne 'Installed' }\n\n        if ($missing) {\n            Install-WindowsFeature -Name $missing.Name -IncludeManagementTools\n        }\n    }\n\n    if ($installResult -and \"$($installResult.RestartNeeded)\" -eq 'Yes') {\n        Write-Verbose \"Restarting $node to finish the feature installation\"\n        Restart-Computer -ComputerName $node -Wait -For PowerShell -Timeout 1800 -Force\n    }\n}\n\n# Stage 2: validate the nodes.\n$reportFile = $null\n\nif (-not $SkipValidation) {\n    $reportName = Join-Path -Path $ReportFolder -ChildPath ('Validate-{0}-{1:yyyyMMdd-HHmm}' -f $ClusterName, (Get-Date))\n\n    $testParameters = @{\n        Node            = $NodeNames\n        ReportName      = $reportName\n        WarningVariable = 'validationWarnings'\n    }\n\n    if ($StorageSpacesDirect) {\n        $testParameters['Include'] = 'Storage Spaces Direct', 'Inventory', 'Network', 'System Configuration'\n    }\n\n    Write-Verbose \"Running Test-Cluster against $($NodeNames -join ', ')\"\n    $validationOutput = Test-Cluster @testParameters\n    $reportFile = $validationOutput | Where-Object { $_ -is [System.IO.FileInfo] } | Select-Object -First 1\n\n    if ($validationWarnings) {\n        Write-Warning \"Validation returned $($validationWarnings.Count) warning(s). Read $($reportFile.FullName) before you put workloads on this cluster.\"\n    }\n}\n\n# Stage 3: create the cluster without letting it claim any disks.\n$existingCluster = Get-Cluster -Name $clusterTarget -ErrorAction SilentlyContinue\n\nif (-not $existingCluster) {\n    Write-Verbose \"Creating cluster $ClusterName at $ClusterIPAddress\"\n    New-Cluster -Name $ClusterName -Node $NodeNames -StaticAddress $ClusterIPAddress -NoStorage | Out-Null\n} elseif ($existingCluster.Name -ne $ClusterName) {\n    throw \"$clusterTarget already belongs to cluster $($existingCluster.Name), not $ClusterName.\"\n} else {\n    Write-Verbose \"Cluster $ClusterName already exists, skipping creation\"\n}\n\n# Stage 4: configure the quorum witness.\nif ($CloudWitnessAccountName) {\n    Write-Verbose \"Configuring a cloud witness in storage account $CloudWitnessAccountName\"\n    Set-ClusterQuorum -Cluster $clusterTarget -CloudWitness -AccountName $CloudWitnessAccountName -AccessKey $CloudWitnessAccessKey | Out-Null\n} elseif ($FileShareWitness) {\n    Write-Verbose \"Configuring a file share witness at $FileShareWitness\"\n    Set-ClusterQuorum -Cluster $clusterTarget -FileShareWitness $FileShareWitness | Out-Null\n} elseif ($NodeNames.Count -eq 2) {\n    Write-Warning 'Two-node cluster with no witness: if either node goes offline, the other cannot keep quorum. Add a cloud or file share witness.'\n}\n\n# Stage 5: storage, either Storage Spaces Direct or a shared SAN disk as a CSV.\nif ($StorageSpacesDirect) {\n    $existingPool = Get-StoragePool -CimSession $clusterTarget -IsPrimordial $false -ErrorAction SilentlyContinue\n\n    if (-not $existingPool) {\n        Write-Verbose 'Enabling Storage Spaces Direct'\n        Enable-ClusterStorageSpacesDirect -CimSession $clusterTarget -Confirm:$false | Out-Null\n    } else {\n        Write-Verbose \"Storage pool $($existingPool.FriendlyName) already exists, skipping S2D enablement\"\n    }\n} elseif ($PSBoundParameters.ContainsKey('SharedDiskNumber')) {\n    $availableDisk = Get-ClusterAvailableDisk -Cluster $clusterTarget |\n        Where-Object { $_.Number -eq $SharedDiskNumber }\n\n    if ($availableDisk) {\n        Write-Verbose \"Adding disk $SharedDiskNumber to the cluster and converting it to a CSV\"\n        $clusterDisk = $availableDisk | Add-ClusterDisk\n        Add-ClusterSharedVolume -Cluster $clusterTarget -Name $clusterDisk.Name | Out-Null\n    } else {\n        Write-Warning \"Disk $SharedDiskNumber is not an available cluster disk. It may already be a CSV, or it is not presented to every node.\"\n    }\n}\n\n# Stage 6: restrict Live Migration to one cluster network.\n$liveMigrationNetwork = $null\n\nif ($LiveMigrationSubnet) {\n    $subnetAddress = ($LiveMigrationSubnet -split '\u002F')[0]\n    $clusterNetworks = Get-ClusterNetwork -Cluster $clusterTarget\n    $liveMigrationNetwork = $clusterNetworks | Where-Object { $_.Address -eq $subnetAddress }\n\n    if ($liveMigrationNetwork) {\n        $excludedIds = ($clusterNetworks | Where-Object { $_.Id -ne $liveMigrationNetwork.Id }).Id -join ';'\n        Write-Verbose \"Restricting Live Migration to $($liveMigrationNetwork.Name)\"\n\n        Get-ClusterResourceType -Cluster $clusterTarget -Name 'Virtual Machine' |\n            Set-ClusterParameter -Name MigrationExcludeNetworks -Value $excludedIds\n    } else {\n        Write-Warning \"No cluster network matches $LiveMigrationSubnet. Live Migration keeps the default network order.\"\n    }\n}\n\nif ($MigrationPerformanceOption) {\n    Write-Verbose \"Setting the Live Migration performance option to $MigrationPerformanceOption on every node\"\n    Set-VMHost -ComputerName $NodeNames -VirtualMachineMigrationPerformanceOption $MigrationPerformanceOption\n}\n\n# Summarize the result.\n$csvs = Get-ClusterSharedVolume -Cluster $clusterTarget -ErrorAction SilentlyContinue\n\n[PSCustomObject]@{\n    Cluster       = (Get-Cluster -Name $clusterTarget).Name\n    Nodes         = (Get-ClusterNode -Cluster $clusterTarget | ForEach-Object { \"$($_.Name) ($($_.State))\" }) -join ', '\n    Quorum        = (Get-ClusterQuorum -Cluster $clusterTarget).QuorumResource.Name\n    CSVs          = ($csvs | ForEach-Object { \"$($_.Name) -> $($_.SharedVolumeInfo.FriendlyVolumeName)\" }) -join '; '\n    LiveMigration = if ($liveMigrationNetwork) { \"$($liveMigrationNetwork.Name) ($($liveMigrationNetwork.Address))\" } else { 'Default' }\n    Report        = if ($reportFile) { $reportFile.FullName } else { 'Validation skipped' }\n}\n",[30,496,497,503,511,517,525,531,537,543,549,555,561,572,578,588,594,604,610,620,626,636,642,652,658,668,674,684,690,700,706,716,722,732,738,748,754,762,768,776,782,788,794,800,806,813,825,834,859,878,891,896,913,933,945,950,967,979,984,1002,1014,1019,1031,1036,1053,1065,1070,1087,1112,1124,1129,1146,1158,1163,1180,1192,1197,1214,1226,1231,1248,1272,1277,1287,1293,1298,1309,1314,1320,1344,1367,1373,1378,1411,1416,1422,1439,1444,1450,1465,1480,1485,1506,1531,1555,1560,1569,1585,1591,1597,1602,1636,1650,1683,1688,1693,1698,1704,1715,1720,1733,1773,1778,1791,1802,1813,1824,1829,1834,1842,1874,1879,1884,1909,1923,1969,1974,1982,2015,2020,2025,2030,2036,2057,2062,2074,2093,2124,2141,2171,2182,2195,2200,2205,2211,2219,2232,2262,2272,2285,2303,2321,2330,2335,2340,2346,2353,2381,2386,2398,2406,2428,2438,2458,2463,2484,2501,2519,2524,2532,2546,2562,2581,2590,2603,2608,2613,2618,2624,2634,2639,2647,2671,2687,2714,2719,2727,2760,2779,2784,2805,2821,2830,2844,2849,2854,2859,2867,2881,2897,2902,2907,2913,2932,2937,2953,2971,3032,3050,3102,3151,3173],{"__ignoreMap":326},[113,498,499],{"class":331,"line":332},[113,500,502],{"class":501},"sAwPA","\u003C#\n",[113,504,506,508],{"class":331,"line":505},2,[113,507,336],{"class":339},[113,509,510],{"class":343},"SYNOPSIS\n",[113,512,514],{"class":331,"line":513},3,[113,515,516],{"class":501},"    Builds a Hyper-V failover cluster end to end: features, validation, cluster, quorum, storage and Live Migration network.\n",[113,518,520,522],{"class":331,"line":519},4,[113,521,336],{"class":339},[113,523,524],{"class":343},"DESCRIPTION\n",[113,526,528],{"class":331,"line":527},5,[113,529,530],{"class":501},"    Installs Hyper-V, Failover Clustering and their PowerShell modules on every node (restarting nodes that\n",[113,532,534],{"class":331,"line":533},6,[113,535,536],{"class":501},"    need it), runs cluster validation, creates the cluster without claiming storage, configures a cloud or\n",[113,538,540],{"class":331,"line":539},7,[113,541,542],{"class":501},"    file share witness, then either adds a shared SAN disk as a Cluster Shared Volume or enables Storage\n",[113,544,546],{"class":331,"line":545},8,[113,547,548],{"class":501},"    Spaces Direct. Finally it restricts Live Migration to one cluster network by setting\n",[113,550,552],{"class":331,"line":551},9,[113,553,554],{"class":501},"    MigrationExcludeNetworks on the Virtual Machine resource type. Each stage checks for existing work, so\n",[113,556,558],{"class":331,"line":557},10,[113,559,560],{"class":501},"    the script can be re-run after a failure.\n",[113,562,564,566,569],{"class":331,"line":563},11,[113,565,336],{"class":339},[113,567,568],{"class":343},"PARAMETER",[113,570,571],{"class":343}," NodeNames\n",[113,573,575],{"class":331,"line":574},12,[113,576,577],{"class":501},"    Hostnames of the Hyper-V hosts to cluster (2 to 64; 2 to 16 with -StorageSpacesDirect).\n",[113,579,581,583,585],{"class":331,"line":580},13,[113,582,336],{"class":339},[113,584,568],{"class":343},[113,586,587],{"class":343}," ClusterName\n",[113,589,591],{"class":331,"line":590},14,[113,592,593],{"class":501},"    NetBIOS name for the Cluster Name Object, 15 characters or fewer.\n",[113,595,597,599,601],{"class":331,"line":596},15,[113,598,336],{"class":339},[113,600,568],{"class":343},[113,602,603],{"class":343}," ClusterIPAddress\n",[113,605,607],{"class":331,"line":606},16,[113,608,609],{"class":501},"    Static IPv4 address for the cluster network name.\n",[113,611,613,615,617],{"class":331,"line":612},17,[113,614,336],{"class":339},[113,616,568],{"class":343},[113,618,619],{"class":343}," SharedDiskNumber\n",[113,621,623],{"class":331,"line":622},18,[113,624,625],{"class":501},"    Number of the shared LUN, as Get-ClusterAvailableDisk reports it, to add as a CSV.\n",[113,627,629,631,633],{"class":331,"line":628},19,[113,630,336],{"class":339},[113,632,568],{"class":343},[113,634,635],{"class":343}," StorageSpacesDirect\n",[113,637,639],{"class":331,"line":638},20,[113,640,641],{"class":501},"    Validate with the S2D test set and run Enable-ClusterStorageSpacesDirect instead of adding a SAN disk.\n",[113,643,645,647,649],{"class":331,"line":644},21,[113,646,336],{"class":339},[113,648,568],{"class":343},[113,650,651],{"class":343}," LiveMigrationSubnet\n",[113,653,655],{"class":331,"line":654},22,[113,656,657],{"class":501},"    CIDR of the cluster network Live Migration must use. Every other cluster network is excluded.\n",[113,659,661,663,665],{"class":331,"line":660},23,[113,662,336],{"class":339},[113,664,568],{"class":343},[113,666,667],{"class":343}," MigrationPerformanceOption\n",[113,669,671],{"class":331,"line":670},24,[113,672,673],{"class":501},"    TCPIP, Compression or SMB, applied to every node with Set-VMHost.\n",[113,675,677,679,681],{"class":331,"line":676},25,[113,678,336],{"class":339},[113,680,568],{"class":343},[113,682,683],{"class":343}," CloudWitnessAccountName\n",[113,685,687],{"class":331,"line":686},26,[113,688,689],{"class":501},"    Azure storage account for a cloud witness.\n",[113,691,693,695,697],{"class":331,"line":692},27,[113,694,336],{"class":339},[113,696,568],{"class":343},[113,698,699],{"class":343}," CloudWitnessAccessKey\n",[113,701,703],{"class":331,"line":702},28,[113,704,705],{"class":501},"    Access key for that storage account.\n",[113,707,709,711,713],{"class":331,"line":708},29,[113,710,336],{"class":339},[113,712,568],{"class":343},[113,714,715],{"class":343}," FileShareWitness\n",[113,717,719],{"class":331,"line":718},30,[113,720,721],{"class":501},"    UNC path of a file share witness, used when no cloud witness is given.\n",[113,723,725,727,729],{"class":331,"line":724},31,[113,726,336],{"class":339},[113,728,568],{"class":343},[113,730,731],{"class":343}," ReportFolder\n",[113,733,735],{"class":331,"line":734},32,[113,736,737],{"class":501},"    Folder for the validation report. Defaults to the current directory.\n",[113,739,741,743,745],{"class":331,"line":740},33,[113,742,336],{"class":339},[113,744,568],{"class":343},[113,746,747],{"class":343}," SkipValidation\n",[113,749,751],{"class":331,"line":750},34,[113,752,753],{"class":501},"    Skips Test-Cluster. Not recommended outside of a lab rebuild.\n",[113,755,757,759],{"class":331,"line":756},35,[113,758,336],{"class":339},[113,760,761],{"class":343},"EXAMPLE\n",[113,763,765],{"class":331,"line":764},36,[113,766,767],{"class":501},"    .\\New-HyperVCluster.ps1 -NodeNames 'hv-node01', 'hv-node02' -ClusterName 'hv-clu01' -ClusterIPAddress '10.10.10.50' -SharedDiskNumber 2 -CloudWitnessAccountName '\u003Cstorageaccount>' -CloudWitnessAccessKey '\u003Caccess-key>'\n",[113,769,771,773],{"class":331,"line":770},37,[113,772,336],{"class":339},[113,774,775],{"class":343},"NOTES\n",[113,777,779],{"class":331,"line":778},38,[113,780,781],{"class":501},"    Author  : Thomas Lasswell (https:\u002F\u002Fwww.techcolumnist.com)\n",[113,783,785],{"class":331,"line":784},39,[113,786,787],{"class":501},"    Version : 1.0 (2025-07-09)\n",[113,789,791],{"class":331,"line":790},40,[113,792,793],{"class":501},"    Requires: Windows Server 2019+ nodes, FailoverClusters and Hyper-V modules on the machine running it,\n",[113,795,797],{"class":331,"line":796},41,[113,798,799],{"class":501},"              WinRM to every node, rights to create the cluster computer object\n",[113,801,803],{"class":331,"line":802},42,[113,804,805],{"class":501},"#>\n",[113,807,809],{"class":331,"line":808},43,[113,810,812],{"emptyLinePlaceholder":811},true,"\n",[113,814,816,819,822],{"class":331,"line":815},44,[113,817,818],{"class":335},"[",[113,820,821],{"class":339},"CmdletBinding",[113,823,824],{"class":335},"()]\n",[113,826,828,831],{"class":331,"line":827},45,[113,829,830],{"class":343},"param",[113,832,833],{"class":335}," (\n",[113,835,837,840,843,846,850,853,856],{"class":331,"line":836},46,[113,838,839],{"class":335},"    [",[113,841,842],{"class":339},"Parameter",[113,844,845],{"class":335},"(",[113,847,849],{"class":848},"s9osk","Mandatory",[113,851,852],{"class":343}," =",[113,854,855],{"class":339}," $true",[113,857,858],{"class":335},")]\n",[113,860,862,864,867,869,871,873,876],{"class":331,"line":861},47,[113,863,839],{"class":335},[113,865,866],{"class":339},"ValidateCount",[113,868,845],{"class":335},[113,870,381],{"class":339},[113,872,354],{"class":343},[113,874,875],{"class":339}," 64",[113,877,858],{"class":335},[113,879,881,883,885,888],{"class":331,"line":880},48,[113,882,839],{"class":335},[113,884,111],{"class":343},[113,886,887],{"class":335},"[]]$NodeNames",[113,889,890],{"class":343},",\n",[113,892,894],{"class":331,"line":893},49,[113,895,812],{"emptyLinePlaceholder":811},[113,897,899,901,903,905,907,909,911],{"class":331,"line":898},50,[113,900,839],{"class":335},[113,902,842],{"class":339},[113,904,845],{"class":335},[113,906,849],{"class":848},[113,908,852],{"class":343},[113,910,855],{"class":339},[113,912,858],{"class":335},[113,914,916,918,921,923,926,928,931],{"class":331,"line":915},51,[113,917,839],{"class":335},[113,919,920],{"class":339},"ValidateLength",[113,922,845],{"class":335},[113,924,925],{"class":339},"1",[113,927,354],{"class":343},[113,929,930],{"class":339}," 15",[113,932,858],{"class":335},[113,934,936,938,940,943],{"class":331,"line":935},52,[113,937,839],{"class":335},[113,939,111],{"class":343},[113,941,942],{"class":335},"]$ClusterName",[113,944,890],{"class":343},[113,946,948],{"class":331,"line":947},53,[113,949,812],{"emptyLinePlaceholder":811},[113,951,953,955,957,959,961,963,965],{"class":331,"line":952},54,[113,954,839],{"class":335},[113,956,842],{"class":339},[113,958,845],{"class":335},[113,960,849],{"class":848},[113,962,852],{"class":343},[113,964,855],{"class":339},[113,966,858],{"class":335},[113,968,970,972,974,977],{"class":331,"line":969},55,[113,971,839],{"class":335},[113,973,111],{"class":343},[113,975,976],{"class":335},"]$ClusterIPAddress",[113,978,890],{"class":343},[113,980,982],{"class":331,"line":981},56,[113,983,812],{"emptyLinePlaceholder":811},[113,985,987,989,991,993,995,997,1000],{"class":331,"line":986},57,[113,988,839],{"class":335},[113,990,842],{"class":339},[113,992,845],{"class":335},[113,994,849],{"class":848},[113,996,852],{"class":343},[113,998,999],{"class":339}," $false",[113,1001,858],{"class":335},[113,1003,1005,1007,1009,1012],{"class":331,"line":1004},58,[113,1006,839],{"class":335},[113,1008,162],{"class":343},[113,1010,1011],{"class":335},"]$SharedDiskNumber",[113,1013,890],{"class":343},[113,1015,1017],{"class":331,"line":1016},59,[113,1018,812],{"emptyLinePlaceholder":811},[113,1020,1022,1024,1026,1029],{"class":331,"line":1021},60,[113,1023,839],{"class":335},[113,1025,182],{"class":343},[113,1027,1028],{"class":335},"]$StorageSpacesDirect",[113,1030,890],{"class":343},[113,1032,1034],{"class":331,"line":1033},61,[113,1035,812],{"emptyLinePlaceholder":811},[113,1037,1039,1041,1043,1045,1047,1049,1051],{"class":331,"line":1038},62,[113,1040,839],{"class":335},[113,1042,842],{"class":339},[113,1044,845],{"class":335},[113,1046,849],{"class":848},[113,1048,852],{"class":343},[113,1050,999],{"class":339},[113,1052,858],{"class":335},[113,1054,1056,1058,1060,1063],{"class":331,"line":1055},63,[113,1057,839],{"class":335},[113,1059,111],{"class":343},[113,1061,1062],{"class":335},"]$LiveMigrationSubnet",[113,1064,890],{"class":343},[113,1066,1068],{"class":331,"line":1067},64,[113,1069,812],{"emptyLinePlaceholder":811},[113,1071,1073,1075,1077,1079,1081,1083,1085],{"class":331,"line":1072},65,[113,1074,839],{"class":335},[113,1076,842],{"class":339},[113,1078,845],{"class":335},[113,1080,849],{"class":848},[113,1082,852],{"class":343},[113,1084,999],{"class":339},[113,1086,858],{"class":335},[113,1088,1090,1092,1095,1097,1100,1102,1105,1107,1110],{"class":331,"line":1089},66,[113,1091,839],{"class":335},[113,1093,1094],{"class":339},"ValidateSet",[113,1096,845],{"class":335},[113,1098,1099],{"class":350},"'TCPIP'",[113,1101,354],{"class":343},[113,1103,1104],{"class":350}," 'Compression'",[113,1106,354],{"class":343},[113,1108,1109],{"class":350}," 'SMB'",[113,1111,858],{"class":335},[113,1113,1115,1117,1119,1122],{"class":331,"line":1114},67,[113,1116,839],{"class":335},[113,1118,111],{"class":343},[113,1120,1121],{"class":335},"]$MigrationPerformanceOption",[113,1123,890],{"class":343},[113,1125,1127],{"class":331,"line":1126},68,[113,1128,812],{"emptyLinePlaceholder":811},[113,1130,1132,1134,1136,1138,1140,1142,1144],{"class":331,"line":1131},69,[113,1133,839],{"class":335},[113,1135,842],{"class":339},[113,1137,845],{"class":335},[113,1139,849],{"class":848},[113,1141,852],{"class":343},[113,1143,999],{"class":339},[113,1145,858],{"class":335},[113,1147,1149,1151,1153,1156],{"class":331,"line":1148},70,[113,1150,839],{"class":335},[113,1152,111],{"class":343},[113,1154,1155],{"class":335},"]$CloudWitnessAccountName",[113,1157,890],{"class":343},[113,1159,1161],{"class":331,"line":1160},71,[113,1162,812],{"emptyLinePlaceholder":811},[113,1164,1166,1168,1170,1172,1174,1176,1178],{"class":331,"line":1165},72,[113,1167,839],{"class":335},[113,1169,842],{"class":339},[113,1171,845],{"class":335},[113,1173,849],{"class":848},[113,1175,852],{"class":343},[113,1177,999],{"class":339},[113,1179,858],{"class":335},[113,1181,1183,1185,1187,1190],{"class":331,"line":1182},73,[113,1184,839],{"class":335},[113,1186,111],{"class":343},[113,1188,1189],{"class":335},"]$CloudWitnessAccessKey",[113,1191,890],{"class":343},[113,1193,1195],{"class":331,"line":1194},74,[113,1196,812],{"emptyLinePlaceholder":811},[113,1198,1200,1202,1204,1206,1208,1210,1212],{"class":331,"line":1199},75,[113,1201,839],{"class":335},[113,1203,842],{"class":339},[113,1205,845],{"class":335},[113,1207,849],{"class":848},[113,1209,852],{"class":343},[113,1211,999],{"class":339},[113,1213,858],{"class":335},[113,1215,1217,1219,1221,1224],{"class":331,"line":1216},76,[113,1218,839],{"class":335},[113,1220,111],{"class":343},[113,1222,1223],{"class":335},"]$FileShareWitness",[113,1225,890],{"class":343},[113,1227,1229],{"class":331,"line":1228},77,[113,1230,812],{"emptyLinePlaceholder":811},[113,1232,1234,1236,1238,1240,1242,1244,1246],{"class":331,"line":1233},78,[113,1235,839],{"class":335},[113,1237,842],{"class":339},[113,1239,845],{"class":335},[113,1241,849],{"class":848},[113,1243,852],{"class":343},[113,1245,999],{"class":339},[113,1247,858],{"class":335},[113,1249,1251,1253,1255,1258,1261,1264,1267,1270],{"class":331,"line":1250},79,[113,1252,839],{"class":335},[113,1254,111],{"class":343},[113,1256,1257],{"class":335},"]$ReportFolder ",[113,1259,1260],{"class":343},"=",[113,1262,1263],{"class":335}," (",[113,1265,1266],{"class":339},"Get-Location",[113,1268,1269],{"class":335},").Path",[113,1271,890],{"class":343},[113,1273,1275],{"class":331,"line":1274},80,[113,1276,812],{"emptyLinePlaceholder":811},[113,1278,1280,1282,1284],{"class":331,"line":1279},81,[113,1281,839],{"class":335},[113,1283,182],{"class":343},[113,1285,1286],{"class":335},"]$SkipValidation\n",[113,1288,1290],{"class":331,"line":1289},82,[113,1291,1292],{"class":335},")\n",[113,1294,1296],{"class":331,"line":1295},83,[113,1297,812],{"emptyLinePlaceholder":811},[113,1299,1301,1304,1306],{"class":331,"line":1300},84,[113,1302,1303],{"class":339},"$ErrorActionPreference",[113,1305,852],{"class":343},[113,1307,1308],{"class":350}," 'Stop'\n",[113,1310,1312],{"class":331,"line":1311},85,[113,1313,812],{"emptyLinePlaceholder":811},[113,1315,1317],{"class":331,"line":1316},86,[113,1318,1319],{"class":501},"# A failover cluster supports up to 64 nodes, but Storage Spaces Direct supports at most 16 servers.\n",[113,1321,1323,1326,1329,1332,1335,1338,1341],{"class":331,"line":1322},87,[113,1324,1325],{"class":343},"if",[113,1327,1328],{"class":335}," ($StorageSpacesDirect ",[113,1330,1331],{"class":343},"-and",[113,1333,1334],{"class":335}," $NodeNames.Count ",[113,1336,1337],{"class":343},"-gt",[113,1339,1340],{"class":339}," 16",[113,1342,1343],{"class":335},") {\n",[113,1345,1347,1350,1353,1356,1358,1361,1364],{"class":331,"line":1346},88,[113,1348,1349],{"class":343},"    throw",[113,1351,1352],{"class":350}," \"Storage Spaces Direct supports at most 16 nodes; ",[113,1354,1355],{"class":343},"$",[113,1357,845],{"class":350},[113,1359,1360],{"class":335},"$NodeNames.Count",[113,1362,1363],{"class":350},")",[113,1365,1366],{"class":350}," were given.\"\n",[113,1368,1370],{"class":331,"line":1369},89,[113,1371,1372],{"class":335},"}\n",[113,1374,1376],{"class":331,"line":1375},90,[113,1377,812],{"emptyLinePlaceholder":811},[113,1379,1381,1384,1386,1389,1391,1394,1396,1399,1401,1404,1406,1409],{"class":331,"line":1380},91,[113,1382,1383],{"class":335},"$featureNames ",[113,1385,1260],{"class":343},[113,1387,1388],{"class":343}," @",[113,1390,845],{"class":335},[113,1392,1393],{"class":350},"'Hyper-V'",[113,1395,354],{"class":343},[113,1397,1398],{"class":350}," 'Failover-Clustering'",[113,1400,354],{"class":343},[113,1402,1403],{"class":350}," 'Hyper-V-PowerShell'",[113,1405,354],{"class":343},[113,1407,1408],{"class":350}," 'RSAT-Clustering-PowerShell'",[113,1410,1292],{"class":335},[113,1412,1414],{"class":331,"line":1413},92,[113,1415,812],{"emptyLinePlaceholder":811},[113,1417,1419],{"class":331,"line":1418},93,[113,1420,1421],{"class":501},"# A new cluster name can take a while to resolve in DNS, so talk to the cluster through its first node.\n",[113,1423,1425,1428,1430,1433,1436],{"class":331,"line":1424},94,[113,1426,1427],{"class":335},"$clusterTarget ",[113,1429,1260],{"class":343},[113,1431,1432],{"class":335}," $NodeNames[",[113,1434,1435],{"class":339},"0",[113,1437,1438],{"class":335},"]\n",[113,1440,1442],{"class":331,"line":1441},95,[113,1443,812],{"emptyLinePlaceholder":811},[113,1445,1447],{"class":331,"line":1446},96,[113,1448,1449],{"class":501},"# Stage 1: install roles and features, restarting any node that needs it.\n",[113,1451,1453,1456,1459,1462],{"class":331,"line":1452},97,[113,1454,1455],{"class":343},"foreach",[113,1457,1458],{"class":335}," ($node ",[113,1460,1461],{"class":343},"in",[113,1463,1464],{"class":335}," $NodeNames) {\n",[113,1466,1468,1471,1474,1477],{"class":331,"line":1467},98,[113,1469,1470],{"class":339},"    Write-Verbose",[113,1472,1473],{"class":350}," \"Checking Hyper-V and clustering features on ",[113,1475,1476],{"class":335},"$node",[113,1478,1479],{"class":350},"\"\n",[113,1481,1483],{"class":331,"line":1482},99,[113,1484,812],{"emptyLinePlaceholder":811},[113,1486,1488,1491,1493,1496,1498,1501,1503],{"class":331,"line":1487},100,[113,1489,1490],{"class":335},"    $installResult ",[113,1492,1260],{"class":343},[113,1494,1495],{"class":339}," Invoke-Command",[113,1497,344],{"class":343},[113,1499,1500],{"class":335},"ComputerName $node ",[113,1502,458],{"class":343},[113,1504,1505],{"class":335},"ScriptBlock {\n",[113,1507,1509,1512,1514,1517,1519,1522,1525,1528],{"class":331,"line":1508},101,[113,1510,1511],{"class":335},"        $missing ",[113,1513,1260],{"class":343},[113,1515,1516],{"class":339}," Get-WindowsFeature",[113,1518,344],{"class":343},[113,1520,1521],{"class":335},"Name $",[113,1523,1524],{"class":343},"using",[113,1526,1527],{"class":335},":featureNames ",[113,1529,1530],{"class":343},"|\n",[113,1532,1534,1537,1540,1543,1546,1549,1552],{"class":331,"line":1533},102,[113,1535,1536],{"class":339},"            Where-Object",[113,1538,1539],{"class":335}," { ",[113,1541,1542],{"class":339},"$_",[113,1544,1545],{"class":335},".InstallState ",[113,1547,1548],{"class":343},"-ne",[113,1550,1551],{"class":350}," 'Installed'",[113,1553,1554],{"class":335}," }\n",[113,1556,1558],{"class":331,"line":1557},103,[113,1559,812],{"emptyLinePlaceholder":811},[113,1561,1563,1566],{"class":331,"line":1562},104,[113,1564,1565],{"class":343},"        if",[113,1567,1568],{"class":335}," ($missing) {\n",[113,1570,1572,1575,1577,1580,1582],{"class":331,"line":1571},105,[113,1573,1574],{"class":339},"            Install-WindowsFeature",[113,1576,344],{"class":343},[113,1578,1579],{"class":335},"Name $missing.Name ",[113,1581,458],{"class":343},[113,1583,1584],{"class":335},"IncludeManagementTools\n",[113,1586,1588],{"class":331,"line":1587},106,[113,1589,1590],{"class":335},"        }\n",[113,1592,1594],{"class":331,"line":1593},107,[113,1595,1596],{"class":335},"    }\n",[113,1598,1600],{"class":331,"line":1599},108,[113,1601,812],{"emptyLinePlaceholder":811},[113,1603,1605,1608,1611,1613,1616,1618,1620,1623,1625,1628,1631,1634],{"class":331,"line":1604},109,[113,1606,1607],{"class":343},"    if",[113,1609,1610],{"class":335}," ($installResult ",[113,1612,1331],{"class":343},[113,1614,1615],{"class":350}," \"",[113,1617,1355],{"class":343},[113,1619,845],{"class":350},[113,1621,1622],{"class":335},"$installResult.RestartNeeded",[113,1624,1363],{"class":350},[113,1626,1627],{"class":350},"\"",[113,1629,1630],{"class":343}," -eq",[113,1632,1633],{"class":350}," 'Yes'",[113,1635,1343],{"class":335},[113,1637,1639,1642,1645,1647],{"class":331,"line":1638},110,[113,1640,1641],{"class":339},"        Write-Verbose",[113,1643,1644],{"class":350}," \"Restarting ",[113,1646,1476],{"class":335},[113,1648,1649],{"class":350}," to finish the feature installation\"\n",[113,1651,1653,1656,1658,1660,1662,1665,1667,1670,1672,1675,1678,1680],{"class":331,"line":1652},111,[113,1654,1655],{"class":339},"        Restart-Computer",[113,1657,344],{"class":343},[113,1659,1500],{"class":335},[113,1661,458],{"class":343},[113,1663,1664],{"class":335},"Wait ",[113,1666,458],{"class":343},[113,1668,1669],{"class":335},"For PowerShell ",[113,1671,458],{"class":343},[113,1673,1674],{"class":335},"Timeout ",[113,1676,1677],{"class":339},"1800",[113,1679,344],{"class":343},[113,1681,1682],{"class":335},"Force\n",[113,1684,1686],{"class":331,"line":1685},112,[113,1687,1596],{"class":335},[113,1689,1691],{"class":331,"line":1690},113,[113,1692,1372],{"class":335},[113,1694,1696],{"class":331,"line":1695},114,[113,1697,812],{"emptyLinePlaceholder":811},[113,1699,1701],{"class":331,"line":1700},115,[113,1702,1703],{"class":501},"# Stage 2: validate the nodes.\n",[113,1705,1707,1710,1712],{"class":331,"line":1706},116,[113,1708,1709],{"class":335},"$reportFile ",[113,1711,1260],{"class":343},[113,1713,1714],{"class":339}," $null\n",[113,1716,1718],{"class":331,"line":1717},117,[113,1719,812],{"emptyLinePlaceholder":811},[113,1721,1723,1725,1727,1730],{"class":331,"line":1722},118,[113,1724,1325],{"class":343},[113,1726,1263],{"class":335},[113,1728,1729],{"class":343},"-not",[113,1731,1732],{"class":335}," $SkipValidation) {\n",[113,1734,1736,1739,1741,1744,1746,1749,1751,1754,1757,1760,1763,1765,1767,1770],{"class":331,"line":1735},119,[113,1737,1738],{"class":335},"    $reportName ",[113,1740,1260],{"class":343},[113,1742,1743],{"class":339}," Join-Path",[113,1745,344],{"class":343},[113,1747,1748],{"class":335},"Path $ReportFolder ",[113,1750,458],{"class":343},[113,1752,1753],{"class":335},"ChildPath (",[113,1755,1756],{"class":350},"'Validate-{0}-{1:yyyyMMdd-HHmm}'",[113,1758,1759],{"class":343}," -f",[113,1761,1762],{"class":335}," $ClusterName",[113,1764,354],{"class":343},[113,1766,1263],{"class":335},[113,1768,1769],{"class":339},"Get-Date",[113,1771,1772],{"class":335},"))\n",[113,1774,1776],{"class":331,"line":1775},120,[113,1777,812],{"emptyLinePlaceholder":811},[113,1779,1781,1784,1786,1788],{"class":331,"line":1780},121,[113,1782,1783],{"class":335},"    $testParameters ",[113,1785,1260],{"class":343},[113,1787,1388],{"class":343},[113,1789,1790],{"class":335},"{\n",[113,1792,1794,1797,1799],{"class":331,"line":1793},122,[113,1795,1796],{"class":335},"        Node            ",[113,1798,1260],{"class":343},[113,1800,1801],{"class":335}," $NodeNames\n",[113,1803,1805,1808,1810],{"class":331,"line":1804},123,[113,1806,1807],{"class":335},"        ReportName      ",[113,1809,1260],{"class":343},[113,1811,1812],{"class":335}," $reportName\n",[113,1814,1816,1819,1821],{"class":331,"line":1815},124,[113,1817,1818],{"class":335},"        WarningVariable ",[113,1820,1260],{"class":343},[113,1822,1823],{"class":350}," 'validationWarnings'\n",[113,1825,1827],{"class":331,"line":1826},125,[113,1828,1596],{"class":335},[113,1830,1832],{"class":331,"line":1831},126,[113,1833,812],{"emptyLinePlaceholder":811},[113,1835,1837,1839],{"class":331,"line":1836},127,[113,1838,1607],{"class":343},[113,1840,1841],{"class":335}," ($StorageSpacesDirect) {\n",[113,1843,1845,1848,1851,1854,1856,1859,1861,1864,1866,1869,1871],{"class":331,"line":1844},128,[113,1846,1847],{"class":335},"        $testParameters[",[113,1849,1850],{"class":350},"'Include'",[113,1852,1853],{"class":335},"] ",[113,1855,1260],{"class":343},[113,1857,1858],{"class":350}," 'Storage Spaces Direct'",[113,1860,354],{"class":343},[113,1862,1863],{"class":350}," 'Inventory'",[113,1865,354],{"class":343},[113,1867,1868],{"class":350}," 'Network'",[113,1870,354],{"class":343},[113,1872,1873],{"class":350}," 'System Configuration'\n",[113,1875,1877],{"class":331,"line":1876},129,[113,1878,1596],{"class":335},[113,1880,1882],{"class":331,"line":1881},130,[113,1883,812],{"emptyLinePlaceholder":811},[113,1885,1887,1889,1892,1894,1896,1899,1902,1905,1907],{"class":331,"line":1886},131,[113,1888,1470],{"class":339},[113,1890,1891],{"class":350}," \"Running Test-Cluster against ",[113,1893,1355],{"class":343},[113,1895,845],{"class":350},[113,1897,1898],{"class":335},"$NodeNames",[113,1900,1901],{"class":343}," -join",[113,1903,1904],{"class":350}," ', '",[113,1906,1363],{"class":350},[113,1908,1479],{"class":350},[113,1910,1912,1915,1917,1920],{"class":331,"line":1911},132,[113,1913,1914],{"class":335},"    $validationOutput ",[113,1916,1260],{"class":343},[113,1918,1919],{"class":339}," Test-Cluster",[113,1921,1922],{"class":335}," @testParameters\n",[113,1924,1926,1929,1931,1934,1937,1940,1942,1944,1947,1950,1953,1956,1958,1961,1963,1966],{"class":331,"line":1925},133,[113,1927,1928],{"class":335},"    $reportFile ",[113,1930,1260],{"class":343},[113,1932,1933],{"class":335}," $validationOutput ",[113,1935,1936],{"class":343},"|",[113,1938,1939],{"class":339}," Where-Object",[113,1941,1539],{"class":335},[113,1943,1542],{"class":339},[113,1945,1946],{"class":343}," -is",[113,1948,1949],{"class":335}," [",[113,1951,1952],{"class":343},"System.IO.FileInfo",[113,1954,1955],{"class":335},"] } ",[113,1957,1936],{"class":343},[113,1959,1960],{"class":339}," Select-Object",[113,1962,344],{"class":343},[113,1964,1965],{"class":335},"First ",[113,1967,1968],{"class":339},"1\n",[113,1970,1972],{"class":331,"line":1971},134,[113,1973,812],{"emptyLinePlaceholder":811},[113,1975,1977,1979],{"class":331,"line":1976},135,[113,1978,1607],{"class":343},[113,1980,1981],{"class":335}," ($validationWarnings) {\n",[113,1983,1985,1988,1991,1993,1995,1998,2000,2003,2005,2007,2010,2012],{"class":331,"line":1984},136,[113,1986,1987],{"class":339},"        Write-Warning",[113,1989,1990],{"class":350}," \"Validation returned ",[113,1992,1355],{"class":343},[113,1994,845],{"class":350},[113,1996,1997],{"class":335},"$validationWarnings.Count",[113,1999,1363],{"class":350},[113,2001,2002],{"class":350}," warning(s). Read ",[113,2004,1355],{"class":343},[113,2006,845],{"class":350},[113,2008,2009],{"class":335},"$reportFile.FullName",[113,2011,1363],{"class":350},[113,2013,2014],{"class":350}," before you put workloads on this cluster.\"\n",[113,2016,2018],{"class":331,"line":2017},137,[113,2019,1596],{"class":335},[113,2021,2023],{"class":331,"line":2022},138,[113,2024,1372],{"class":335},[113,2026,2028],{"class":331,"line":2027},139,[113,2029,812],{"emptyLinePlaceholder":811},[113,2031,2033],{"class":331,"line":2032},140,[113,2034,2035],{"class":501},"# Stage 3: create the cluster without letting it claim any disks.\n",[113,2037,2039,2042,2044,2047,2049,2052,2054],{"class":331,"line":2038},141,[113,2040,2041],{"class":335},"$existingCluster ",[113,2043,1260],{"class":343},[113,2045,2046],{"class":339}," Get-Cluster",[113,2048,344],{"class":343},[113,2050,2051],{"class":335},"Name $clusterTarget ",[113,2053,458],{"class":343},[113,2055,2056],{"class":335},"ErrorAction SilentlyContinue\n",[113,2058,2060],{"class":331,"line":2059},142,[113,2061,812],{"emptyLinePlaceholder":811},[113,2063,2065,2067,2069,2071],{"class":331,"line":2064},143,[113,2066,1325],{"class":343},[113,2068,1263],{"class":335},[113,2070,1729],{"class":343},[113,2072,2073],{"class":335}," $existingCluster) {\n",[113,2075,2077,2079,2082,2085,2088,2091],{"class":331,"line":2076},144,[113,2078,1470],{"class":339},[113,2080,2081],{"class":350}," \"Creating cluster ",[113,2083,2084],{"class":335},"$ClusterName",[113,2086,2087],{"class":350}," at ",[113,2089,2090],{"class":335},"$ClusterIPAddress",[113,2092,1479],{"class":350},[113,2094,2096,2099,2101,2104,2106,2109,2111,2114,2116,2119,2121],{"class":331,"line":2095},145,[113,2097,2098],{"class":339},"    New-Cluster",[113,2100,344],{"class":343},[113,2102,2103],{"class":335},"Name $ClusterName ",[113,2105,458],{"class":343},[113,2107,2108],{"class":335},"Node $NodeNames ",[113,2110,458],{"class":343},[113,2112,2113],{"class":335},"StaticAddress $ClusterIPAddress ",[113,2115,458],{"class":343},[113,2117,2118],{"class":335},"NoStorage ",[113,2120,1936],{"class":343},[113,2122,2123],{"class":339}," Out-Null\n",[113,2125,2127,2130,2133,2136,2138],{"class":331,"line":2126},146,[113,2128,2129],{"class":335},"} ",[113,2131,2132],{"class":343},"elseif",[113,2134,2135],{"class":335}," ($existingCluster.Name ",[113,2137,1548],{"class":343},[113,2139,2140],{"class":335}," $ClusterName) {\n",[113,2142,2144,2146,2148,2151,2154,2156,2158,2161,2163,2166,2168],{"class":331,"line":2143},147,[113,2145,1349],{"class":343},[113,2147,1615],{"class":350},[113,2149,2150],{"class":335},"$clusterTarget",[113,2152,2153],{"class":350}," already belongs to cluster ",[113,2155,1355],{"class":343},[113,2157,845],{"class":350},[113,2159,2160],{"class":335},"$existingCluster.Name",[113,2162,1363],{"class":350},[113,2164,2165],{"class":350},", not ",[113,2167,2084],{"class":335},[113,2169,2170],{"class":350},".\"\n",[113,2172,2174,2176,2179],{"class":331,"line":2173},148,[113,2175,2129],{"class":335},[113,2177,2178],{"class":343},"else",[113,2180,2181],{"class":335}," {\n",[113,2183,2185,2187,2190,2192],{"class":331,"line":2184},149,[113,2186,1470],{"class":339},[113,2188,2189],{"class":350}," \"Cluster ",[113,2191,2084],{"class":335},[113,2193,2194],{"class":350}," already exists, skipping creation\"\n",[113,2196,2198],{"class":331,"line":2197},150,[113,2199,1372],{"class":335},[113,2201,2203],{"class":331,"line":2202},151,[113,2204,812],{"emptyLinePlaceholder":811},[113,2206,2208],{"class":331,"line":2207},152,[113,2209,2210],{"class":501},"# Stage 4: configure the quorum witness.\n",[113,2212,2214,2216],{"class":331,"line":2213},153,[113,2215,1325],{"class":343},[113,2217,2218],{"class":335}," ($CloudWitnessAccountName) {\n",[113,2220,2222,2224,2227,2230],{"class":331,"line":2221},154,[113,2223,1470],{"class":339},[113,2225,2226],{"class":350}," \"Configuring a cloud witness in storage account ",[113,2228,2229],{"class":335},"$CloudWitnessAccountName",[113,2231,1479],{"class":350},[113,2233,2235,2238,2240,2243,2245,2248,2250,2253,2255,2258,2260],{"class":331,"line":2234},155,[113,2236,2237],{"class":339},"    Set-ClusterQuorum",[113,2239,344],{"class":343},[113,2241,2242],{"class":335},"Cluster $clusterTarget ",[113,2244,458],{"class":343},[113,2246,2247],{"class":335},"CloudWitness ",[113,2249,458],{"class":343},[113,2251,2252],{"class":335},"AccountName $CloudWitnessAccountName ",[113,2254,458],{"class":343},[113,2256,2257],{"class":335},"AccessKey $CloudWitnessAccessKey ",[113,2259,1936],{"class":343},[113,2261,2123],{"class":339},[113,2263,2265,2267,2269],{"class":331,"line":2264},156,[113,2266,2129],{"class":335},[113,2268,2132],{"class":343},[113,2270,2271],{"class":335}," ($FileShareWitness) {\n",[113,2273,2275,2277,2280,2283],{"class":331,"line":2274},157,[113,2276,1470],{"class":339},[113,2278,2279],{"class":350}," \"Configuring a file share witness at ",[113,2281,2282],{"class":335},"$FileShareWitness",[113,2284,1479],{"class":350},[113,2286,2288,2290,2292,2294,2296,2299,2301],{"class":331,"line":2287},158,[113,2289,2237],{"class":339},[113,2291,344],{"class":343},[113,2293,2242],{"class":335},[113,2295,458],{"class":343},[113,2297,2298],{"class":335},"FileShareWitness $FileShareWitness ",[113,2300,1936],{"class":343},[113,2302,2123],{"class":339},[113,2304,2306,2308,2310,2313,2316,2319],{"class":331,"line":2305},159,[113,2307,2129],{"class":335},[113,2309,2132],{"class":343},[113,2311,2312],{"class":335}," ($NodeNames.Count ",[113,2314,2315],{"class":343},"-eq",[113,2317,2318],{"class":339}," 2",[113,2320,1343],{"class":335},[113,2322,2324,2327],{"class":331,"line":2323},160,[113,2325,2326],{"class":339},"    Write-Warning",[113,2328,2329],{"class":350}," 'Two-node cluster with no witness: if either node goes offline, the other cannot keep quorum. Add a cloud or file share witness.'\n",[113,2331,2333],{"class":331,"line":2332},161,[113,2334,1372],{"class":335},[113,2336,2338],{"class":331,"line":2337},162,[113,2339,812],{"emptyLinePlaceholder":811},[113,2341,2343],{"class":331,"line":2342},163,[113,2344,2345],{"class":501},"# Stage 5: storage, either Storage Spaces Direct or a shared SAN disk as a CSV.\n",[113,2347,2349,2351],{"class":331,"line":2348},164,[113,2350,1325],{"class":343},[113,2352,1841],{"class":335},[113,2354,2356,2359,2361,2364,2366,2369,2371,2374,2377,2379],{"class":331,"line":2355},165,[113,2357,2358],{"class":335},"    $existingPool ",[113,2360,1260],{"class":343},[113,2362,2363],{"class":339}," Get-StoragePool",[113,2365,344],{"class":343},[113,2367,2368],{"class":335},"CimSession $clusterTarget ",[113,2370,458],{"class":343},[113,2372,2373],{"class":335},"IsPrimordial ",[113,2375,2376],{"class":339},"$false",[113,2378,344],{"class":343},[113,2380,2056],{"class":335},[113,2382,2384],{"class":331,"line":2383},166,[113,2385,812],{"emptyLinePlaceholder":811},[113,2387,2389,2391,2393,2395],{"class":331,"line":2388},167,[113,2390,1607],{"class":343},[113,2392,1263],{"class":335},[113,2394,1729],{"class":343},[113,2396,2397],{"class":335}," $existingPool) {\n",[113,2399,2401,2403],{"class":331,"line":2400},168,[113,2402,1641],{"class":339},[113,2404,2405],{"class":350}," 'Enabling Storage Spaces Direct'\n",[113,2407,2409,2412,2414,2416,2418,2421,2423,2426],{"class":331,"line":2408},169,[113,2410,2411],{"class":339},"        Enable-ClusterStorageSpacesDirect",[113,2413,344],{"class":343},[113,2415,2368],{"class":335},[113,2417,458],{"class":343},[113,2419,2420],{"class":335},"Confirm:",[113,2422,2376],{"class":339},[113,2424,2425],{"class":343}," |",[113,2427,2123],{"class":339},[113,2429,2431,2434,2436],{"class":331,"line":2430},170,[113,2432,2433],{"class":335},"    } ",[113,2435,2178],{"class":343},[113,2437,2181],{"class":335},[113,2439,2441,2443,2446,2448,2450,2453,2455],{"class":331,"line":2440},171,[113,2442,1641],{"class":339},[113,2444,2445],{"class":350}," \"Storage pool ",[113,2447,1355],{"class":343},[113,2449,845],{"class":350},[113,2451,2452],{"class":335},"$existingPool.FriendlyName",[113,2454,1363],{"class":350},[113,2456,2457],{"class":350}," already exists, skipping S2D enablement\"\n",[113,2459,2461],{"class":331,"line":2460},172,[113,2462,1596],{"class":335},[113,2464,2466,2468,2470,2472,2475,2478,2481],{"class":331,"line":2465},173,[113,2467,2129],{"class":335},[113,2469,2132],{"class":343},[113,2471,1263],{"class":335},[113,2473,2474],{"class":339},"$PSBoundParameters",[113,2476,2477],{"class":335},".ContainsKey(",[113,2479,2480],{"class":350},"'SharedDiskNumber'",[113,2482,2483],{"class":335},")) {\n",[113,2485,2487,2490,2492,2495,2497,2499],{"class":331,"line":2486},174,[113,2488,2489],{"class":335},"    $availableDisk ",[113,2491,1260],{"class":343},[113,2493,2494],{"class":339}," Get-ClusterAvailableDisk",[113,2496,344],{"class":343},[113,2498,2242],{"class":335},[113,2500,1530],{"class":343},[113,2502,2504,2507,2509,2511,2514,2516],{"class":331,"line":2503},175,[113,2505,2506],{"class":339},"        Where-Object",[113,2508,1539],{"class":335},[113,2510,1542],{"class":339},[113,2512,2513],{"class":335},".Number ",[113,2515,2315],{"class":343},[113,2517,2518],{"class":335}," $SharedDiskNumber }\n",[113,2520,2522],{"class":331,"line":2521},176,[113,2523,812],{"emptyLinePlaceholder":811},[113,2525,2527,2529],{"class":331,"line":2526},177,[113,2528,1607],{"class":343},[113,2530,2531],{"class":335}," ($availableDisk) {\n",[113,2533,2535,2537,2540,2543],{"class":331,"line":2534},178,[113,2536,1641],{"class":339},[113,2538,2539],{"class":350}," \"Adding disk ",[113,2541,2542],{"class":335},"$SharedDiskNumber",[113,2544,2545],{"class":350}," to the cluster and converting it to a CSV\"\n",[113,2547,2549,2552,2554,2557,2559],{"class":331,"line":2548},179,[113,2550,2551],{"class":335},"        $clusterDisk ",[113,2553,1260],{"class":343},[113,2555,2556],{"class":335}," $availableDisk ",[113,2558,1936],{"class":343},[113,2560,2561],{"class":339}," Add-ClusterDisk\n",[113,2563,2565,2568,2570,2572,2574,2577,2579],{"class":331,"line":2564},180,[113,2566,2567],{"class":339},"        Add-ClusterSharedVolume",[113,2569,344],{"class":343},[113,2571,2242],{"class":335},[113,2573,458],{"class":343},[113,2575,2576],{"class":335},"Name $clusterDisk.Name ",[113,2578,1936],{"class":343},[113,2580,2123],{"class":339},[113,2582,2584,2586,2588],{"class":331,"line":2583},181,[113,2585,2433],{"class":335},[113,2587,2178],{"class":343},[113,2589,2181],{"class":335},[113,2591,2593,2595,2598,2600],{"class":331,"line":2592},182,[113,2594,1987],{"class":339},[113,2596,2597],{"class":350}," \"Disk ",[113,2599,2542],{"class":335},[113,2601,2602],{"class":350}," is not an available cluster disk. It may already be a CSV, or it is not presented to every node.\"\n",[113,2604,2606],{"class":331,"line":2605},183,[113,2607,1596],{"class":335},[113,2609,2611],{"class":331,"line":2610},184,[113,2612,1372],{"class":335},[113,2614,2616],{"class":331,"line":2615},185,[113,2617,812],{"emptyLinePlaceholder":811},[113,2619,2621],{"class":331,"line":2620},186,[113,2622,2623],{"class":501},"# Stage 6: restrict Live Migration to one cluster network.\n",[113,2625,2627,2630,2632],{"class":331,"line":2626},187,[113,2628,2629],{"class":335},"$liveMigrationNetwork ",[113,2631,1260],{"class":343},[113,2633,1714],{"class":339},[113,2635,2637],{"class":331,"line":2636},188,[113,2638,812],{"emptyLinePlaceholder":811},[113,2640,2642,2644],{"class":331,"line":2641},189,[113,2643,1325],{"class":343},[113,2645,2646],{"class":335}," ($LiveMigrationSubnet) {\n",[113,2648,2650,2653,2655,2658,2661,2664,2667,2669],{"class":331,"line":2649},190,[113,2651,2652],{"class":335},"    $subnetAddress ",[113,2654,1260],{"class":343},[113,2656,2657],{"class":335}," ($LiveMigrationSubnet ",[113,2659,2660],{"class":343},"-split",[113,2662,2663],{"class":350}," '\u002F'",[113,2665,2666],{"class":335},")[",[113,2668,1435],{"class":339},[113,2670,1438],{"class":335},[113,2672,2674,2677,2679,2682,2684],{"class":331,"line":2673},191,[113,2675,2676],{"class":335},"    $clusterNetworks ",[113,2678,1260],{"class":343},[113,2680,2681],{"class":339}," Get-ClusterNetwork",[113,2683,344],{"class":343},[113,2685,2686],{"class":335},"Cluster $clusterTarget\n",[113,2688,2690,2693,2695,2698,2700,2702,2704,2706,2709,2711],{"class":331,"line":2689},192,[113,2691,2692],{"class":335},"    $liveMigrationNetwork ",[113,2694,1260],{"class":343},[113,2696,2697],{"class":335}," $clusterNetworks ",[113,2699,1936],{"class":343},[113,2701,1939],{"class":339},[113,2703,1539],{"class":335},[113,2705,1542],{"class":339},[113,2707,2708],{"class":335},".Address ",[113,2710,2315],{"class":343},[113,2712,2713],{"class":335}," $subnetAddress }\n",[113,2715,2717],{"class":331,"line":2716},193,[113,2718,812],{"emptyLinePlaceholder":811},[113,2720,2722,2724],{"class":331,"line":2721},194,[113,2723,1607],{"class":343},[113,2725,2726],{"class":335}," ($liveMigrationNetwork) {\n",[113,2728,2730,2733,2735,2738,2740,2742,2744,2746,2749,2751,2754,2757],{"class":331,"line":2729},195,[113,2731,2732],{"class":335},"        $excludedIds ",[113,2734,1260],{"class":343},[113,2736,2737],{"class":335}," ($clusterNetworks ",[113,2739,1936],{"class":343},[113,2741,1939],{"class":339},[113,2743,1539],{"class":335},[113,2745,1542],{"class":339},[113,2747,2748],{"class":335},".Id ",[113,2750,1548],{"class":343},[113,2752,2753],{"class":335}," $liveMigrationNetwork.Id }).Id ",[113,2755,2756],{"class":343},"-join",[113,2758,2759],{"class":350}," ';'\n",[113,2761,2763,2765,2768,2770,2772,2775,2777],{"class":331,"line":2762},196,[113,2764,1641],{"class":339},[113,2766,2767],{"class":350}," \"Restricting Live Migration to ",[113,2769,1355],{"class":343},[113,2771,845],{"class":350},[113,2773,2774],{"class":335},"$liveMigrationNetwork.Name",[113,2776,1363],{"class":350},[113,2778,1479],{"class":350},[113,2780,2782],{"class":331,"line":2781},197,[113,2783,812],{"emptyLinePlaceholder":811},[113,2785,2787,2790,2792,2794,2796,2799,2802],{"class":331,"line":2786},198,[113,2788,2789],{"class":339},"        Get-ClusterResourceType",[113,2791,344],{"class":343},[113,2793,2242],{"class":335},[113,2795,458],{"class":343},[113,2797,2798],{"class":335},"Name ",[113,2800,2801],{"class":350},"'Virtual Machine'",[113,2803,2804],{"class":343}," |\n",[113,2806,2808,2811,2813,2816,2818],{"class":331,"line":2807},199,[113,2809,2810],{"class":339},"            Set-ClusterParameter",[113,2812,344],{"class":343},[113,2814,2815],{"class":335},"Name MigrationExcludeNetworks ",[113,2817,458],{"class":343},[113,2819,2820],{"class":335},"Value $excludedIds\n",[113,2822,2824,2826,2828],{"class":331,"line":2823},200,[113,2825,2433],{"class":335},[113,2827,2178],{"class":343},[113,2829,2181],{"class":335},[113,2831,2833,2835,2838,2841],{"class":331,"line":2832},201,[113,2834,1987],{"class":339},[113,2836,2837],{"class":350}," \"No cluster network matches ",[113,2839,2840],{"class":335},"$LiveMigrationSubnet",[113,2842,2843],{"class":350},". Live Migration keeps the default network order.\"\n",[113,2845,2847],{"class":331,"line":2846},202,[113,2848,1596],{"class":335},[113,2850,2852],{"class":331,"line":2851},203,[113,2853,1372],{"class":335},[113,2855,2857],{"class":331,"line":2856},204,[113,2858,812],{"emptyLinePlaceholder":811},[113,2860,2862,2864],{"class":331,"line":2861},205,[113,2863,1325],{"class":343},[113,2865,2866],{"class":335}," ($MigrationPerformanceOption) {\n",[113,2868,2870,2872,2875,2878],{"class":331,"line":2869},206,[113,2871,1470],{"class":339},[113,2873,2874],{"class":350}," \"Setting the Live Migration performance option to ",[113,2876,2877],{"class":335},"$MigrationPerformanceOption",[113,2879,2880],{"class":350}," on every node\"\n",[113,2882,2884,2887,2889,2892,2894],{"class":331,"line":2883},207,[113,2885,2886],{"class":339},"    Set-VMHost",[113,2888,344],{"class":343},[113,2890,2891],{"class":335},"ComputerName $NodeNames ",[113,2893,458],{"class":343},[113,2895,2896],{"class":335},"VirtualMachineMigrationPerformanceOption $MigrationPerformanceOption\n",[113,2898,2900],{"class":331,"line":2899},208,[113,2901,1372],{"class":335},[113,2903,2905],{"class":331,"line":2904},209,[113,2906,812],{"emptyLinePlaceholder":811},[113,2908,2910],{"class":331,"line":2909},210,[113,2911,2912],{"class":501},"# Summarize the result.\n",[113,2914,2916,2919,2921,2924,2926,2928,2930],{"class":331,"line":2915},211,[113,2917,2918],{"class":335},"$csvs ",[113,2920,1260],{"class":343},[113,2922,2923],{"class":339}," Get-ClusterSharedVolume",[113,2925,344],{"class":343},[113,2927,2242],{"class":335},[113,2929,458],{"class":343},[113,2931,2056],{"class":335},[113,2933,2935],{"class":331,"line":2934},212,[113,2936,812],{"emptyLinePlaceholder":811},[113,2938,2940,2942,2945,2948,2951],{"class":331,"line":2939},213,[113,2941,818],{"class":335},[113,2943,2944],{"class":343},"PSCustomObject",[113,2946,2947],{"class":335},"]",[113,2949,2950],{"class":343},"@",[113,2952,1790],{"class":335},[113,2954,2956,2959,2961,2963,2966,2968],{"class":331,"line":2955},214,[113,2957,2958],{"class":335},"    Cluster       ",[113,2960,1260],{"class":343},[113,2962,1263],{"class":335},[113,2964,2965],{"class":339},"Get-Cluster",[113,2967,344],{"class":343},[113,2969,2970],{"class":335},"Name $clusterTarget).Name\n",[113,2972,2974,2977,2979,2981,2984,2986,2988,2990,2993,2995,2997,2999,3001,3003,3006,3008,3010,3012,3014,3016,3019,3021,3024,3027,3029],{"class":331,"line":2973},215,[113,2975,2976],{"class":335},"    Nodes         ",[113,2978,1260],{"class":343},[113,2980,1263],{"class":335},[113,2982,2983],{"class":339},"Get-ClusterNode",[113,2985,344],{"class":343},[113,2987,2242],{"class":335},[113,2989,1936],{"class":343},[113,2991,2992],{"class":339}," ForEach-Object",[113,2994,1539],{"class":335},[113,2996,1627],{"class":350},[113,2998,1355],{"class":343},[113,3000,845],{"class":350},[113,3002,1542],{"class":339},[113,3004,3005],{"class":335},".Name",[113,3007,1363],{"class":350},[113,3009,1263],{"class":350},[113,3011,1355],{"class":343},[113,3013,845],{"class":350},[113,3015,1542],{"class":339},[113,3017,3018],{"class":335},".State",[113,3020,1363],{"class":350},[113,3022,3023],{"class":350},")\"",[113,3025,3026],{"class":335}," }) ",[113,3028,2756],{"class":343},[113,3030,3031],{"class":350}," ', '\n",[113,3033,3035,3038,3040,3042,3045,3047],{"class":331,"line":3034},216,[113,3036,3037],{"class":335},"    Quorum        ",[113,3039,1260],{"class":343},[113,3041,1263],{"class":335},[113,3043,3044],{"class":339},"Get-ClusterQuorum",[113,3046,344],{"class":343},[113,3048,3049],{"class":335},"Cluster $clusterTarget).QuorumResource.Name\n",[113,3051,3053,3056,3058,3061,3063,3065,3067,3069,3071,3073,3075,3077,3079,3082,3084,3086,3088,3091,3093,3095,3097,3099],{"class":331,"line":3052},217,[113,3054,3055],{"class":335},"    CSVs          ",[113,3057,1260],{"class":343},[113,3059,3060],{"class":335}," ($csvs ",[113,3062,1936],{"class":343},[113,3064,2992],{"class":339},[113,3066,1539],{"class":335},[113,3068,1627],{"class":350},[113,3070,1355],{"class":343},[113,3072,845],{"class":350},[113,3074,1542],{"class":339},[113,3076,3005],{"class":335},[113,3078,1363],{"class":350},[113,3080,3081],{"class":350}," -> ",[113,3083,1355],{"class":343},[113,3085,845],{"class":350},[113,3087,1542],{"class":339},[113,3089,3090],{"class":335},".SharedVolumeInfo.FriendlyVolumeName",[113,3092,1363],{"class":350},[113,3094,1627],{"class":350},[113,3096,3026],{"class":335},[113,3098,2756],{"class":343},[113,3100,3101],{"class":350}," '; '\n",[113,3103,3105,3108,3110,3113,3116,3118,3120,3122,3124,3126,3128,3130,3132,3135,3137,3139,3142,3144,3146,3149],{"class":331,"line":3104},218,[113,3106,3107],{"class":335},"    LiveMigration ",[113,3109,1260],{"class":343},[113,3111,3112],{"class":343}," if",[113,3114,3115],{"class":335}," ($liveMigrationNetwork) { ",[113,3117,1627],{"class":350},[113,3119,1355],{"class":343},[113,3121,845],{"class":350},[113,3123,2774],{"class":335},[113,3125,1363],{"class":350},[113,3127,1263],{"class":350},[113,3129,1355],{"class":343},[113,3131,845],{"class":350},[113,3133,3134],{"class":335},"$liveMigrationNetwork.Address",[113,3136,1363],{"class":350},[113,3138,3023],{"class":350},[113,3140,3141],{"class":335}," } ",[113,3143,2178],{"class":343},[113,3145,1539],{"class":335},[113,3147,3148],{"class":350},"'Default'",[113,3150,1554],{"class":335},[113,3152,3154,3157,3159,3161,3164,3166,3168,3171],{"class":331,"line":3153},219,[113,3155,3156],{"class":335},"    Report        ",[113,3158,1260],{"class":343},[113,3160,3112],{"class":343},[113,3162,3163],{"class":335}," ($reportFile) { $reportFile.FullName } ",[113,3165,2178],{"class":343},[113,3167,1539],{"class":335},[113,3169,3170],{"class":350},"'Validation skipped'",[113,3172,1554],{"class":335},[113,3174,3176],{"class":331,"line":3175},220,[113,3177,1372],{"class":335},[15,3179,3181],{"id":3180},"notes","Notes",[20,3183,3184,3193,3199,3202,3212,3223,3230],{},[23,3185,3186,3189,3190,3192],{},[30,3187,3188],{},"-NoStorage"," is intentional. Letting cluster creation claim every eligible disk has burned me before on hosts where a local RAID volume happened to look cluster-eligible; adding the CSV disk explicitly by number avoids that. Microsoft's S2D deployment guide uses ",[30,3191,3188],{}," for the same reason and then enables S2D as a separate step.",[23,3194,3195,3196,3198],{},"Read the validation report even when the script finishes cleanly. ",[30,3197,311],{}," returns the report file plus warnings; a warning-only report still deserves a look before anything production lands on the cluster, and Microsoft's S2D hardware requirements state that the fully configured cluster must pass all validation tests.",[23,3200,3201],{},"For S2D, the drives must have no partitions or the pool will not claim them. Microsoft's deployment article has a disk-cleaning script; run it only after triple-checking the server list, because it wipes every non-boot drive.",[23,3203,3204,3207,3208,3211],{},[30,3205,3206],{},"MigrationExcludeNetworks"," wants cluster network IDs, semicolon separated, no spaces. The Failover Cluster Manager equivalent is Networks > Live Migration Settings. Do not use ",[30,3209,3210],{},"Set-VMMigrationNetwork"," for this on a cluster: that cmdlet is for live migration between non-clustered hosts, and the cluster setting is what governs migrations between nodes.",[23,3213,3214,3215,3218,3219,3222],{},"Kerberos versus CredSSP only matters for moves the cluster does not broker, such as shared-nothing moves to hosts outside the cluster. Kerberos needs constrained delegation (",[30,3216,3217],{},"cifs"," and ",[30,3220,3221],{},"Microsoft Virtual System Migration Service",") on each host's computer account. Windows Server 2025 enables Credential Guard by default on domain members, which breaks CredSSP-based live migration, so plan on Kerberos constrained delegation there.",[23,3224,3225,3226,3229],{},"The cloud witness does not keep your access key: the cluster generates a SAS token from it. When you rotate storage keys, switch every cluster that uses the account to the secondary key first, then regenerate the primary. The nodes need outbound HTTPS (443) to ",[30,3227,3228],{},"*.core.windows.net",", through WinHTTP proxy settings if a proxy is involved.",[23,3231,3232,3233,3236,3237,3240,3241,3248,3249,3252,3253,3255,3256,3258],{},"A file share witness can live on a non-domain device (a NAS, or a router with USB storage) from Windows Server 2019 on. Pass ",[30,3234,3235],{},"-Credential"," to ",[30,3238,3239],{},"Set-ClusterQuorum"," in that case, as Microsoft's ",[3242,3243,3247],"a",{"href":3244,"rel":3245},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows-server\u002Ffailover-clustering\u002Fdeploy-quorum-witness",[3246],"nofollow","Deploy a quorum witness"," guide shows (",[30,3250,3251],{},"Set-ClusterQuorum -Cluster \u003CClusterName> -FileShareWitness \\\\server\\share -Credential (Get-Credential)",", with a local account on the device). The ",[30,3254,3239],{}," cmdlet reference doesn't list ",[30,3257,3235],{}," among its parameters, so go by the deployment guide for this one. The script's plain call assumes a domain share that grants the CNO Change and Read.",[15,3260,3262],{"id":3261},"source","Source",[20,3264,3265,3280,3286,3293,3300,3310],{},[23,3266,3267,226,3271,3218,3275,3279],{},[3242,3268,311],{"href":3269,"rel":3270},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002Ffailoverclusters\u002Ftest-cluster",[3246],[3242,3272,43],{"href":3273,"rel":3274},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002Ffailoverclusters\u002Fnew-cluster",[3246],[3242,3276,3239],{"href":3277,"rel":3278},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002Ffailoverclusters\u002Fset-clusterquorum",[3246]," cmdlet references",[23,3281,3282],{},[3242,3283,3285],{"href":3244,"rel":3284},[3246],"Deploy a quorum witness for a failover cluster",[23,3287,3288],{},[3242,3289,3292],{"href":3290,"rel":3291},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows-server\u002Fstorage\u002Fstorage-spaces\u002Fdeploy-storage-spaces-direct",[3246],"Deploy Storage Spaces Direct on Windows Server",[23,3294,3295],{},[3242,3296,3299],{"href":3297,"rel":3298},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows-server\u002Ffailover-clustering\u002Ffailover-cluster-csvs",[3246],"Use Cluster Shared Volumes in a failover cluster",[23,3301,3302,3307,3308,1363],{},[3242,3303,3306],{"href":3304,"rel":3305},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows-server\u002Ffailover-clustering\u002Fconfigure-live-migration-smb-bandwidth",[3246],"Control Live Migration SMB bandwidth cluster-wide"," (Live Migration network selection with ",[30,3309,3206],{},[23,3311,3312,3317],{},[3242,3313,3316],{"href":3314,"rel":3315},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows-server\u002Fvirtualization\u002Fhyper-v\u002Fdeploy\u002Fset-up-hosts-for-live-migration-without-failover-clustering",[3246],"Set up hosts for live migration without Failover Clustering"," (authentication options and the Windows Server 2025 CredSSP change)",[3319,3320,3321],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":326,"searchDepth":505,"depth":505,"links":3323},[3324,3325,3326,3327,3328,3329],{"id":17,"depth":505,"text":18},{"id":74,"depth":505,"text":75},{"id":315,"depth":505,"text":316},{"id":490,"depth":505,"text":491},{"id":3180,"depth":505,"text":3181},{"id":3261,"depth":505,"text":3262},"techcolumnist",[3332,3333],"ps","scripts","2025-07-09T14:00:00Z","A re-runnable script that installs Hyper-V and clustering, validates the nodes, builds the cluster, sets a quorum witness, adds CSV or S2D storage and pins Live Migration.","md",false,null,{},"\u002Fblog\u002F2025\u002F07\u002F09\u002Fpowershell-hyper-v-script-a-failover-cluster-deployment-end-to-end",{"title":6,"description":3335},[3330],"blog\u002F2025\u002F07\u002F09\u002Fpowershell-hyper-v-script-a-failover-cluster-deployment-end-to-end",[325,3345,3346],"hyper-v","cluster","\u002F2025\u002F07\u002F09\u002Fpowershell-hyper-v-script-a-failover-cluster-deployment-end-to-end\u002F","niv3_S1AFaeu5ZRMorOJHvUEtN5OxJ8-HeuBNuaSRXM",{"title":3350,"description":3351,"date":3352,"url":3353,"categories":3354,"tags":3355,"image":3338,"readingTime":519,"canonical":3330,"sites":3358,"series":3338,"seriesOrder":3338},"PowerShell: Windows 11 – Debloat a Golden Image Before Sysprep","A PowerShell script that removes consumer AppX packages for all users and from provisioning, sets consumer-experience policies, and keeps Sysprep from failing.","2025-07-16T14:00:00Z","\u002F2025\u002F07\u002F16\u002Fpowershell-windows-11-debloat-a-golden-image-before-sysprep\u002F",[3332,3333],[325,3356,3357],"windows-11","debloat",[3330],{"title":3360,"description":3361,"date":3362,"url":3363,"categories":3364,"tags":3366,"image":3367,"readingTime":557,"canonical":3368,"sites":3369,"series":3370,"seriesOrder":551},"Service Knowledge & Configuration: Building a system of record that helps","Building a service knowledge and configuration system of record that actually helps, after eight weeks on the pillars of modern ITSM.","2025-07-02T16:19:15Z","\u002F2025\u002F07\u002F02\u002Fservice-knowledge-configuration-building-a-system-of-record-that-helps\u002F",[3365],"business",[],"\u002Fuploads\u002F2025\u002F07\u002FChatGPT-Image-Jul-2-2025-12_18_41-PM.png","lasswell",[3368,3330],"itsm-in-practice",[3372,3380,3390],{"title":3373,"description":3374,"date":3375,"url":3376,"categories":3377,"tags":3378,"image":3338,"readingTime":519,"canonical":3330,"sites":3379,"series":3338,"seriesOrder":3338},"PowerShell: Hyper-V – Automate VM Checkpoints Before Patch Tuesday","A script that takes dated production checkpoints of running Hyper-V VMs on hosts or a whole cluster before patching, prunes its own old ones and plugs into CAU.","2025-10-15T14:00:00Z","\u002F2025\u002F10\u002F15\u002Fpowershell-hyper-v-automate-vm-checkpoints-before-patch-tuesday\u002F",[3332,3333],[325,3345,3346],[3330],{"title":3381,"description":3382,"date":3383,"url":3384,"categories":3385,"tags":3386,"image":3338,"readingTime":527,"canonical":3330,"sites":3389,"series":3338,"seriesOrder":3338},"PowerShell: Active Directory – Report Group Membership Sprawl","Rank AD security groups by nesting depth, transitive member count, ownership and staleness for an access review, plus a per-user Kerberos token size estimate.","2025-12-03T14:00:00Z","\u002F2025\u002F12\u002F03\u002Fpowershell-active-directory-report-group-membership-sprawl\u002F",[3332,3333],[325,3387,3388],"active-directory","reporting",[3330],{"title":3391,"description":3392,"date":3393,"url":3394,"categories":3395,"tags":3396,"image":3338,"readingTime":519,"canonical":3330,"sites":3398,"series":3338,"seriesOrder":3338},"PowerShell: Windows Server – Disable SMBv1 Fleet-Wide and Verify","A script that audits SMBv1 access (event 3000), disables the SMBv1 server and optional feature across Windows servers, and reports which ones still need a restart.","2025-11-26T14:00:00Z","\u002F2025\u002F11\u002F26\u002Fpowershell-windows-server-disable-smbv1-fleet-wide-and-verify-it-stuck\u002F",[3332,3333],[325,3397],"windows",[3330],{"doc":3338,"posts":3400},[],1790052512859]