PowerShell Guide: S2D Node – ASHCI-K47 Series

Updated: 2020-03-13.

The following is the PowerShell and sometimes Command based steps we use to set up our ASHCI-K47 cluster nodes.

Note that some steps are optional depending on the environment the node is going in to.

# Set the Console Title
$host.UI.RawUI.WindowTitle = "Kepler-47B Node 1 Setup Shell"
$host.UI.RawUI.WindowTitle = "Kepler-47B Node 2 Setup Shell"

# Variables - These need to be copy and pasted in after a reboot!
$Kepler47BNode1 = "Kepler-47B-01"
$Kepler47BNode2 = "Kepler-47B-02"
$S2DClusterName = "2018-05-01 Kepler-47B S2D"
$DomainName = "DOMAIN.COM"
$DomainAdminName = "DOMAIN\Admin"
$OUPath = "OU=2018-02-08 Kepler-47A Cluster,OU=S2D-Clusters,OU=Main-Office,DC=DC=DOMAIN,DC=Com"

# BIOS REV:

gwmi win32_ComputerSystem | Select Manufacturer,Model
Get-WmiObject win32_bios

# BIOS Name Settings
Import the .Reg

# SERVER NAME

Rename-Computer -NewName $Kepler47BNode1 -Restart
Rename-Computer -NewName $Kepler47BNode2 -Restart

# Check Server Name

HostName

# JOIN DOMAIN

Add-Computer -Domain $DomainName -Credential $DomainAdminName -OUPath $OUPath -Restart

# DRIVERS - Need Intel and Mellanox at the minimum

gwmi Win32_SystemDriver | select name,@{n="version";e={(gi $_.pathname).VersionInfo.FileVersion}}
gwmi Win32_PnPSignedDriver | select devicename,driverversion

Get-WmiObject Win32_PNPEntity | Where Status -ne "OK" | Select Name,Status
Get-WmiObject Win32_PNPEntity | Where Status -ne "OK" | FL

# POWER OPTION - Set MAX

POWERCFG.EXE /S SCHEME_MIN

# Configure Active memory dump
Set-ItemProperty –Path HKLM:\System\CurrentControlSet\Control\CrashControl –Name CrashDumpEnabled –value 1
Set-ItemProperty –Path HKLM:\System\CurrentControlSet\Control\CrashControl –Name FilterPages –value 1

# Check Active Memory Dump
Get-ItemProperty –Path HKLM:\System\CurrentControlSet\Control\CrashControl –Name CrashDumpEnabled
Get-ItemProperty –Path HKLM:\System\CurrentControlSet\Control\CrashControl –Name FilterPages

# Set it back to Automatic memory dump (default)
Set-ItemProperty –Path HKLM:\System\CurrentControlSet\Control\CrashControl –Name CrashDumpEnabled –value 7
Remove-ItemProperty –Path HKLM:\System\CurrentControlSet\Control\CrashControl –Name FilterPages –value 1

# INSTALL WINDOWS FEATURES

Install-WindowsFeature Hyper-V,Data-Center-Bridging,Failover-Clustering,RSAT-Clustering-Powershell,Hyper-V-PowerShell,Storage-Replica -IncludeAllSubFeature -IncludeManagementTools -Source D:\Sources\SXS -Restart

# Without Storage Replica
Install-WindowsFeature Hyper-V,Data-Center-Bridging,Failover-Clustering,RSAT-Clustering-Powershell,Hyper-V-PowerShell -IncludeAllSubFeature -IncludeManagementTools -Source D:\Sources\SXS -Restart

# Verify Features
Get-WindowsFeature | where {$_.installed -eq $true} | select DisplayName, Name, Installed

# ENABLE Enhanced Session Mode
Set-VMhost -EnableEnhancedSessionMode $TRUE

# NETWORKING

netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow

# NETWORKING SETUP - ADAPTER NAME

Get-NetAdapter | Sort MacAddress | Select Name,InterfaceDescription,MacAddress,LinkSpeed
Get-NetAdapter | Sort MacAddress | Select Name,InterfaceDescription,MacAddress

Get-NetAdapter |? Name -NotLike vEthernet* |? InterfaceDescription -Like Intel*tion | Rename-NetAdapter -NewName SvSwith-01
Get-NetAdapter |? Name -NotLike vEthernet* |? InterfaceDescription -Like Intel*LM | Rename-NetAdapter -NewName SvSwith-02

# NODE 1 and 2
Get-Netadapter |? Name -Like Ethernet* |? InterfaceDescription -like Mellanox*#2 | Rename-NetAdapter -NewName EW-LM-101
Get-Netadapter |? Name -Like Ethernet* |? InterfaceDescription -like Mellanox*Adapter | Rename-NetAdapter -NewName EW-LM-102

# NODE 2 if the above is reversed
Get-Netadapter |? Name -Like Ethernet* |? InterfaceDescription -like Mellanox*Adapter | Rename-NetAdapter -NewName EW-LM-101
Get-Netadapter |? Name -Like Ethernet* |? InterfaceDescription -like Mellanox*#2 | Rename-NetAdapter -NewName EW-LM-102

# NETWORKING SETUP - VLAN

Set-NetAdapter -Name EW-LM-101 -VlanID 101 -Confirm:$False
Set-NetAdapter -Name EW-LM-102 -VlanID 102 -Confirm:$False

Get-NetAdapterAdvancedProperty |? DisplayName -Like VLAN* | Select Name,DisplayName,DisplayValue

# NETWORKING SETUP - JUMBO FRAMES

Get-NetAdapterAdvancedProperty -Name EW-LM* -RegistryKeyword "*jumbopacket" | Set-NetAdapterAdvancedProperty -RegistryValue 9014

Get-NetAdapterAdvancedProperty -Name * -RegistryKeyword "*jumbopacket" | Sort Name

# RDMA

Get-NetAdapter *EW-LM* | Enable-NetAdapterRDMA
Get-NetAdapterRDMA

# TEAMING and IP ADDRESS ASSIGNMENT

Set-DNSClient -InterfaceAlias EW* -RegisterThisConnectionsAddress $False

New-NetLbfoTeam -Name SvSwitch -TeamMembers SVS* -Confirm:$False
New-VMSwitch -Name vSwitch -NetAdapterName SvSwitch -AllowManagementOS 1

New-NetIPAddress -InterfaceAlias "vEthernet (Management-0)" -IPAddress 10.10.0.5 -PrefixLength 24 -Type Unicast | Out-Null
Set-DnsClientServerAddress -InterfaceAlias "vEthernet (Management-0)" -ServerAddresses 10.10.0.20 | Out-Null

New-NetIPAddress -InterfaceAlias "vEthernet (Cluster-100)" -IPAddress 10.10.100.5 -PrefixLength 24 -Type Unicast | Out-Null

# NODE 1 East-West and Live Migration Subnets
New-NetIPAddress -InterfaceAlias "EW-LM-101" -IPAddress 10.101.100.10 -PrefixLength 24 -Type Unicast | Out-Null
New-NetIPAddress -InterfaceAlias "EW-LM-102" -IPAddress 10.102.100.10 -PrefixLength 24 -Type Unicast | Out-Null

# NODE 2 East-West and Live Migration Subnets
New-NetIPAddress -InterfaceAlias "EW-LM-101" -IPAddress 10.101.100.20 -PrefixLength 24 -Type Unicast | Out-Null
New-NetIPAddress -InterfaceAlias "EW-LM-102" -IPAddress 10.102.100.20 -PrefixLength 24 -Type Unicast | Out-Null

# REMOVE If Necessary
Remove-NetIPAddress -InterfaceAlias "EW-LM-101" -IPAddress 10.101.100.100 -PrefixLength 24 -Type Unicast -Confirm:$False | Out-Null
Remove-NetIPAddress -InterfaceAlias "EW-LM-102" -IPAddress 10.102.100.100 -PrefixLength 24 -Type Unicast -Confirm:$False | Out-Null

Get-NetIPAddress |? AddressFamily -Like IPv4 |? InterfaceAlias -NotLike "lo*" | FT IPAddress,InterfaceAlias

Get-NetIPAddress |? AddressFamily -Like IPv4 | FT IPAddress,InterfaceAlias

# TEST Jumbo Frames
# NODE1
ping 10.101.100.20 -l 9014
ping 10.102.100.20 -l 9014

# NODE2
ping 10.101.100.10 -l 9014
ping 10.102.100.10 -l 9014

# TEST and CLUSTER

Test-Cluster $Kepler47BNode1,$Kepler47BNode2 -Include "Storage Spaces Direct",Inventory,Network,"System Configuration"

New-Cluster 180315-S2DCL -Node $Kepler47BNode1,$Kepler47BNode2 -NoStorage

# Disable NETBIOS
Get-ClusterResource “Cluster IP address” -Cluster 180315-S2DCL | Set-ClusterParameter EnableNetBIOS 0

# NetBIOS over TCP/IP controls for vNics
Get Code:

$vNic = Get-NetAdapter -CimSession $wc -name "vEthernet (Storage1)","vEthernet (Storage2)","vEthernet (Mgmt)"
$wmiNicList = $vNic | % { $thisnic = $_; Get-WmiObject -class win32_networkadapterconfiguration -ComputerName $thisNic.pscomputerName | where {$_.Description -eq $thisnic.InterfaceDescription} }
$wmiNicList | sort PsComputerName, Description | select PSComputerName, Description, tcpIpNetbiosoptions

# CLEAN NODE DISKS ****DANGER DESTRUCTIVE****
# Used when we have had a Storage Spaces Direct cluster set up previously

icm (Get-Cluster -Name $S2DClusterName | Get-ClusterNode) {
Update-StorageProviderCache
Get-StoragePool |? IsPrimordial -eq $false | Set-StoragePool -IsReadOnly:$false -ErrorAction SilentlyContinue
Get-StoragePool |? IsPrimordial -eq $false | Get-VirtualDisk | Remove-VirtualDisk -Confirm:$false -ErrorAction SilentlyContinue
Get-PhysicalDisk | Reset-PhysicalDisk -ErrorAction SilentlyContinue
Get-Disk |? Number -ne $null |? IsBoot -ne $true |? IsSystem -ne $true |? PartitionStyle -ne RAW |% {
$_ | Set-Disk -isoffline:$false
$_ | Set-Disk -isreadonly:$false
$_ | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false
$_ | Set-Disk -isreadonly:$true
$_ | Set-Disk -isoffline:$true
}
Get-Disk |? Number -ne $null |? IsBoot -ne $true |? IsSystem -ne $true |? PartitionStyle -eq RAW | Group -NoElement -Property FriendlyName
} | Sort -Property PsComputerName,Count

# CHECK DISKS
Get-PhysicalDisk | FT FriendlyName,CanPool,MediaType

# Cluster Quorum - Azure CW
Set-ClusterQuorum -CloudWitness -AccountName AzureCloudWitnessAA01 -AccessKey 00gaB00ga

# CLUSTER NETWORK

# NODE1
Get-ClusterNetwork
(Get-ClusterNetwork -Name "Cluster Network 1").Name="EW-LM-102"
(Get-ClusterNetwork -Name "Cluster Network 2").Name="EW-LM-101"
(Get-ClusterNetwork -Name "Cluster Network 3").Name="SvSwitch"

(Get-ClusterNetwork | where-object {$_.Address -eq "10.101.100.10"}).Name = "EW-LM-101"
(Get-ClusterNetwork | where-object {$_.Address -eq "10.102.100.10"}).Name = "EW-LM-102"

# NODE FAIRNESS
(Get-Cluster).AutoBalancerMode = 2
(Get-Cluster).AutoBalancerLevel = 2

# Stand up the S2D CLUSTER with several variations
Enable-ClusterS2D -Confirm:$False

Enable-ClusterS2D -PoolFriendlyName 'S2D' -CollectPerformanceHistory $True

Enable-ClusterStorageSpacesDirect

# STORAGE POOL CSV SETUP FOR PRODUCTION
New-Volume -StoragePoolFriendlyName "S2D*" -FriendlyName "CSV-01-Guest-OS" -FileSystem CSVFS_ReFS -Size 900GB
Rename-Item -Path C:\ClusterStorage\volume1\ -NewName "CSV-01-Guest-OS"

New-Volume -StoragePoolFriendlyName "S2D*" -FriendlyName "CSV-02-Guest-OS" -FileSystem CSVFS_ReFS -Size 900GB
Rename-Item -Path C:\ClusterStorage\volume1\ -NewName "CSV-02-Guest-OS"

New-Volume -StoragePoolFriendlyName "S2D*" -FriendlyName "CSV-03-Guest-Data" -FileSystem CSVFS_ReFS -Size 5TB
Rename-Item -Path C:\ClusterStorage\volume1\ -NewName "CSV-03-Guest-Data"

New-Volume -StoragePoolFriendlyName "S2D*" -FriendlyName "CSV-04-Guest-Data" -FileSystem CSVFS_ReFS -Size 5TB
Rename-Item -Path C:\ClusterStorage\volume1\ -NewName "CSV-04-Guest-Data"

# Set VM Configuration paths
Set-VMHOST –computername $Kepler47BNode1 –virtualharddiskpath 'C:\ClusterStorage\CSV-01-Guest-OS'
Set-VMHOST –computername $Kepler47BNode1 –virtualmachinepath 'C:\ClusterStorage\CSV-03-Guest-Data'
Set-VMHOST –computername $Kepler47BNode2 –virtualharddiskpath 'C:\ClusterStorage\CSV-02-Guest-OS'
Set-VMHOST –computername $Kepler47BNode2 –virtualmachinepath 'C:\ClusterStorage\CSV-04-Guest-Data'

# KCD Kerberos Constrained Delegation
$Domain = "DOMAIN.COM"
$HyvHost = "$Kepler47BNode1"
Get-ADComputer $Kepler47BNode2 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$HyvHost.$Domain", "cifs/$HyvHost.$Domain","Microsoft Virtual System Migration Service/$HyvHost", "cifs/$HyvHost"}
Get-ADComputer S2D-DC01 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$HyvHost.$Domain", "cifs/$HyvHost.$Domain","Microsoft Virtual System Migration Service/$HyvHost", "cifs/$HyvHost"}
Get-ADComputer S2D-DC02 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$HyvHost.$Domain", "cifs/$HyvHost.$Domain","Microsoft Virtual System Migration Service/$HyvHost", "cifs/$HyvHost"}
$HyvHost = "$Kepler47BNode2"
Get-ADComputer $Kepler47BNode1 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$HyvHost.$Domain", "cifs/$HyvHost.$Domain","Microsoft Virtual System Migration Service/$HyvHost", "cifs/$HyvHost"}
Get-ADComputer S2D-DC01 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$HyvHost.$Domain", "cifs/$HyvHost.$Domain","Microsoft Virtual System Migration Service/$HyvHost", "cifs/$HyvHost"}
Get-ADComputer S2D-DC02 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$HyvHost.$Domain", "cifs/$HyvHost.$Domain","Microsoft Virtual System Migration Service/$HyvHost", "cifs/$HyvHost"}

# LIVE MIGRATION SETUP

Enable-VMMigration –Computername $Kepler47BNode1, $Kepler47BNode2
Set-VMHost -MaximumVirtualMachineMigrations 4 –MaximumStorageMigrations 4 –VirtualMachineMigrationPerformanceOption SMB -ComputerName $Kepler47BNode1,$Kepler47BNode2

Set-VMHost –Computername $Kepler47BNode1, $Kepler47BNode2 –VirtualMachineMigrationAuthenticationType Kerberos

Get-ClusterResource | Get-ClusterParameter