Part 3: Deploy a 2 Node Shared SAS 2016 Storage Spaces Cluster

Previous Post in Series:  Part 2: Deploy a Highly Available SCVMM Instance Step-by-Step

Welcome to part 3 of the Server 2016 Features Series.  In this deployment, VM storage will be provided to our Hyper-V cluster by means of Scale-Out file server shares (in advance of creating our Hyper-V cluster). This guide will take you through the deployment and configuration of a 2 node Shared SAS Storage Spaces cluster and the Scale-Out File Server role that sits on it. Here is a breakdown of the tasks that will be covered:

As I tend to spin servers up and down on a fairly regular basis, I’ve created a PowerShell script for doing most of the Post OS Installation tasks.  The script is fairly specific to the hardware I’ve been using recently but as a fair amount of it can be repurposed for any environment, I’ve pasted it below so feel free to make sure of some/all of it.
I’ve added “LAB ONLY” for lines that I wouldn’t use in a production deployment.

The script carries out the following configuration tasks:

  • Allows user to choose which site they’re installing to and picks the correct IP and VLAN information
  • Renames NICs for SMB storage
  • Sets IPs for SMB NICs
  • Sets VLAN for SMB 2 NIC, not required for SMB 1 NIC as native VLAN is used and therefore tagged at the TOR switches
  • Enables Jumbo packets on SMB NICs with a setting of 9000
  • Disables unused 1Gb NICs
  • Disables “Register in DNS” for relevant NICs
  • Creates a LACP team using the 10Gb Intel NICs to be used for management
  • Sets VLAN for the new Management team
  • Configures IP and DNS settings on Management NIC
  • Sets local administrator password to never expire – LAB ONLY
  • Enables remote desktop
  • Sets Windows Time service to Automatic Start
  • Disables Windows Firewall – LAB ONLY
  • Installs required Windows Features to suit server role
  • Disables Trim/UNMAP on server
  • Enables MPIO claim settings for SAS
  • Configures Chelsio offload settings
  • Disables IE ESC – User discretion here
  • Renames server
  • Renames administrator account – User choice

Tasks not covered by the script

  • Set required local administrator permissions
  • Create cluster using PowerShell
  • Add AD permissions for Cluster CNO
  • Run additional load-balancing and rebuild best practice PowerShell
  • Create Storage Pool
  • Create Tiered Storage Space
  • Install Scale-Out File Server role
  • Create file share
  • Add SOFS nodes to SCVMM
  • Deploy SCVMM library server and set up library share

Post OS Installation PowerShell Script

##################################################
# Storage Spaces - Post OS Installation Script   #
# Site:                                          #
#                                                #
# Written by: David Fleming                      #
# Date: 20th January 2017                        #
# Version 4.0                                    #
##################################################

#region
Clear-Host
# Set Variables
$User = [adsi]"WinNT://$env:computername/administrator"
$UnusedNICS = Get-NetAdapter NIC3, NIC4
$HostName = Read-Host "Please Enter a New Hostname for This Server"
$IP_Octet = Read-Host "Please enter the last Octet for this servers IP Addressing"

# This function allows the users to chose between multiple sites and will pick the correct subnets and VLANs for the host.

Function Menu-Select
{
PARAM
(
[Parameter(Mandatory=$true)]
$Options,
$DisplayProperty
)
[int]$OptionPrefix = 1
# Create menu list
foreach ($Option in $Options)
{
if ($DisplayProperty -eq $null)
{
Write-Host ("{0,3}: {1}" -f $OptionPrefix,$Option)
}
else
{
Write-Host ("{0,3}: {1}" -f $OptionPrefix,$Option.$DisplayProperty)
}
$OptionPrefix++
}
Write-Host ("{0,3}: {1}" -f 0,"To Cancel")
[int]$Response = Read-Host "Please Select The Correct Infrastructure For The New Host"
$ChosenSite = $null
if ($Response -gt 0 -and $Response -le $Options.Count)
{
$ChosenSite = $Options[$Response-1]
$script:Site = $ChosenSite
}
return $ChosenSite
}

$Infrastructures = "SITE A","SITE B"
$ChosenSite = Menu-Select $Infrastructures

# This IF statement will make sure that the correct IPs and VLANs are being used based on the users site choice above
if ($Site -eq "SITE A")
{
# Chelsio SMB Variables (SITE A)
$SMB1_VLAN = "VLAN ID HERE"
$SMB2_VLAN = "VLAN ID HERE"
$SMB1iPAddress = "10.10.10." + $IP_Octet # Add the first 3 octets of your SMB 1 subnet here
$SMB2iPAddress = "10.10.11." + $IP_Octet # Add the first 3 octets of your SMB 2 subnet here

# Management Variables (SITE A) – Modify these for your environment
$ManagementTeam_Name = "SITE A Management Team"
$ManagementVLAN = "VLAN ID HERE"
$ManagementIP = "10.10.12." + $IP_Octet
$ManagementDefaultGW = "10.10.12.1"
$DNS1 = "10.10.12.11"
$DNS2 = "10.10.12.12"
}
Else
{
# Chelsio SMB Variables (SITE B)
$SMB1_VLAN = "VLAN ID HERE"
$SMB2_VLAN = "VLAN ID HERE"
$SMB1iPAddress = "10.11.10." + $IP_Octet # Add the first 3 octets of your SMB 1 subnet here
$SMB2iPAddress = "10.11.11." + $IP_Octet # Add the first 3 octets of your SMB 2 subnet here

# Management Variables (SITE B)
$ManagementTeam_Name = "SITE B Management Team"
$ManagementVLAN = "VLAN ID HERE"
$ManagementIP = "10.11.12." + $IP_Octet
$ManagementDefaultGW = "10.11.12.1"
$DNS1 = "10.11.12.11"
$DNS2 = "10.11.12.12"
}
#endregion

#region
# Chelsio NICs
# Rename Network Adapters
Write-Host "Renaming Chelio Adapters" -ForegroundColor Yellow
Get-NetAdapter | where InterfaceDescription -Like "Chelsio*" | where Name -Like "SLOT * *" | Rename-NetAdapter -NewName "SMB 2 (VLAN $SMB2_VLAN)"
Get-NetAdapter | where InterfaceDescription -Like "Chelsio*" | where Name -Like "SLOT *" | Rename-NetAdapter -NewName "SMB 1 (VLAN $SMB1_VLAN)"

# Set IPs on SMB NICs
Write-Host "Configuring IPs on SMB NICs" -ForegroundColor Yellow
New-NetIPAddress -InterfaceAlias "SMB 1 (VLAN $SMB1_VLAN)" -IPAddress $SMB1iPAddress -PrefixLength 24
New-NetIPAddress -InterfaceAlias "SMB 2 (VLAN $SMB2_VLAN)" -IPAddress $SMB2iPAddress -PrefixLength 24

# Enable VLAN ID on SMB 2 NIC
Write-Host "Enabling VLAN ID of $SMB2_VLAN on SMB 2 NIC" -ForegroundColor Yellow
$SMB2NIC = Get-NetAdapter "SMB 2 (VLAN $SMB2_VLAN)"
Set-NetAdapter -Name $SMB2NIC.Name -VlanID $SMB2_VLAN -Confirm:$false

# Enable Jumbo Packets on SMB NICs
Write-Host "Enabling Jumbo Packets on SMB NICs" -ForegroundColor Yellow
$SMB2_NICs = Get-NetAdapter | where InterfaceDescription -Like "Chelsio*"
Get-NetAdapterAdvancedProperty -Name $SMB2_NICs.InterfaceAlias -RegistryKeyword "*jumbopacket" | Set-NetAdapterAdvancedProperty -RegistryValue 9000
#endregion

# Disable Unused 1Gb NICs
Write-Host "Disabling Unused 1Gb NICs" -ForegroundColor Yellow
Get-NetAdapter -Name $UnusedNICS.Name | Disable-NetAdapter -Confirm:$false

# Disable IPv6 on all NICs
Write-Host "Disabling IPv6 Binding on all NICs" -ForegroundColor Yellow
$NICIPv6 = Get-NetAdapter | where ConnectorPresent -eq $true
Disable-NetAdapterBinding -Name $NICIPv6.Name -ComponentID ms_tcpip6

# Disable "Register in DNS" Setting on Relevant NICs
Write-Host "Disabling DNS Registration on all relevant NICs" -ForegroundColor Yellow
$RegisterDNS_NICs = Get-NetAdapter -Name "SMB 1 (VLAN $SMB1_VLAN)", "SMB 2 (VLAN $SMB2_VLAN)", "NIC2"
Set-DnsClient -InterfaceAlias $RegisterDNS_NICs.Name -RegisterThisConnectionsAddress $False

#region **MANGEMENT NETWORKING USING LACP TEAM**
Write-Host "Creating LACP NIC Team" -ForegroundColor Yellow
$NICTeam = New-NetLbfoTeam -Name $ManagementTeam_Name -TeamMembers NIC1,NIC2 -TeamingMode LACP -LoadBalancingAlgorithm Dynamic -Confirm:$False

# Set VLAN ID for Team NIC
Set-NetLbfoTeamNic -Name $NICTeam.Name -VlanID $ManagementVLAN

# Configure IP Address and DNS Settings on Temp Team NIC
Write-Host "Configuring IP and DNS on Temp Team NIC" -ForegroundColor Yellow
$TeamNIC = $NICTeam.Name + " - VLAN $ManagementVLAN"
New-NetIPAddress -InterfaceAlias $TeamNIC -IPAddress $ManagementIP -PrefixLength 24 -DefaultGateway $ManagementDefaultGW
Set-DnsClientServerAddress -InterfaceAlias $TeamNIC -ServerAddresses $DNS1, $DNS2
#endregion

# Set Local Administrator Password Never Expires Flag to True
Write-Host "Setting Local Adinistrator Password to Never Expire" -ForegroundColor Yellow
$User.UserFlags.value = $User.UserFlags.value -bor 0x10000
$User.CommitChanges()

# Enable Remote Desktop
Write-Host "Enabling Remote Desktop" -ForegroundColor Yellow
set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server'-name "fDenyTSConnections" -Value 0
set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "UserAuthentication" -Value 1

# Setting Windows Time Service Startup to Automatic
Write-Host "Setting Windows Time Service Startup to Automatic" -ForegroundColor Yellow
Set-Service W32Time -StartupType Automatic
Start-Service W32Time

# Disable Windows Firewall
Write-Host "Disabling Windows Firewall" -ForegroundColor Yellow
Set-NetFirewallProfile -All -Enabled False

# Install Windows Features

Add-WindowsFeature FS-FileServer, FS-VSS-Agent, Multipath-IO
Add-WindowsFeature Failover-Clustering, Hyper-V-PowerShell -IncludeManagementTools

# To Disable Trim/UNMAP in Windows
fsutil behavior set disabledeletenotify 1

#Enable MPIO Global Settings - Loadbalancing Policy Configured in a later script
Enable-MSDSMAutomaticClaim -BusType SAS

# Configure Chelsio Offload Settings
Set-NetOffloadGlobalSetting -NetworkDirectAcrossIPSubnets Allowed

# Disable IE ESC
Write-Host "Disabling IE ESC" -ForegroundColor Yellow
$AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
$UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
Set-ItemProperty -Path $AdminKey -Name "IsInstalled" -Value 0
Set-ItemProperty -Path $UserKey -Name "IsInstalled" -Value 0
Stop-Process -Name Explorer

# Rename Server
Write-Host "Renaming Server to: $HostName"
Rename-Computer -NewName $HostName

# Rename Administrator Account and Reboot
Write-Host "Renaming Local Administrator Account to $User" -ForegroundColor Green
$admin=[adsi]"WinNT://./Administrator,user"
$admin.psbase.rename("NEWADMINUSERNAME")
shutdown /r /t 15

When you run the script, you will be asked to provide answers to the following questions:

  • Please enter a new hostname for this server
  • Please enter the last octet for this servers IP addressing

Set Required Local Administrator Permissions

  • Create an account in Active Directory to be used as the SOFS Run As account. This is the account that VMM will use when interacting with the Scale-Out file server cluster.
  • Add this account to the local administrators group on both SOFS nodes

Create Cluster

Before creating the cluster, do the following:

  • Apply all available Windows Update to both nodes – this may take several passes
  • Validate the cluster configuration by running the following command:
Test-Cluster –Node SERVER1, SERVER2

The cluster validation report is saved to the node you run the PowerShell from and in the following location: C:\Windows\Cluster\Reports\Validation Report DATE & TIME.htm

Assuming the validation has succeeded, move on and create the cluster below or attend to any issues if not.

Create a cluster using the PowerShell below paying attention to the -NoStorage flag. Without it the cluster will add every single physical disk individually as we’ve not done any pooling yet.

New-Cluster –Name MyCluster –Node Server1, Server2 –StaticAddress 192.168.1.12 -NoStorage

Add AD Permissions for Cluster CNO

I covered this earlier as part of the SQL cluster deployment guide, you’ll find it HERE

Create a Cluster Quorum

I covered this earlier as part of the SQL cluster deployment guide, you’ll find it HERE

Additional load-balancing and rebuild best practice

The following commands only need to be run once on each host and before any Storage Pools are created.

Set MPIO Load Balancing Policy to “Least Block”
Testing has shown Least Blocks to be the most performant option.

Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy LB

Optimise Storage Spaces for Parallel Rebuilds

As the title suggests, the following commands modify Storage Spaces repair parameters and optimises for parallel rebuilds.

Set-ItemProperty hklm:\System\CurrentControlSet\Services\Spaceport\Parameters -Name ReallocationsPerInterval 32
Set-ItemProperty hklm:\System\CurrentControlSet\Services\Spaceport\Parameters -Name ReallocationInterval 15
Set-ItemProperty hklm:\System\CurrentControlSet\Services\Spaceport\Parameters -Name RepairQueueDepth 4
Set-ItemProperty hklm:\System\CurrentControlSet\Services\Spaceport\Parameters -Name RepairQueueWidth 8
Get-ClusterResourceType "Storage Pool" | Set-ClusterParameter -Name ReEvaluatePlacementTimeout -Value $([uint32]300) –create

Configure Cluster Networks

Launch “Failover Cluster Manager” and browse to “Networks” on the left navigation pane. Both your SMB networks usage should be listed as “Cluster and Client”

clip_image001[6]

Create Storage Pool

As we want to create all of our Storage Pools in exactly the same way and following best practice, I’ve created a script that does the following:

  • Allows users to choose what SOFS node they’re working from
  • Requests a name for the new Storage Pool
  • Gets all SSDs than can be pooled
  • Gets all HDDs that can be pooled
  • Select the first X amount of SSDs based on their slot number – this variable should be modified to suit the amount of disks you want in your pool
  • Select the first X amount of HDDs based on their slot number – this variable should be modified to suit the amount of disks you want in your pool
  • Creates clustered Storage Pool
  • Modifies resiliency settings on new pool
  • Creates a storage tier for both SSDs and HDDs
###########################################
# Storage Spaces - Provision Storage Pool #
# Site:                                   #
#                                         #
# Written by: David Fleming               #
# Date: 20th January 2017                 #
# Version 2.0                             #
###########################################

# This script was written to be run after the SOFS nodes have been clustered
$ErrorActionPreference = Stop

Clear-Host

# Enable MPIO Global Settings - Continued
Write-Host "Setting MPIO Load Balancing Policy" -ForegroundColor Yellow
Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy LB # This is the preferred Load Balancing policy for a Shared SAS Storage Spaces cluster and will provide the best performance

# Function to select SOFS node from list

Function Choose-SOFSNode
{
PARAM
(
[Parameter(Mandatory=$true)]
$Options,
$DisplayProperty
)
[int]$OptionPrefix = 1
# Create menu list
foreach ($Option in $Options)
{
if ($DisplayProperty -eq $null)
{
Write-Host ("{0,3}: {1}" -f $OptionPrefix,$Option)
}
else
{
Write-Host ("{0,3}: {1}" -f $OptionPrefix,$Option.$DisplayProperty)
}
$OptionPrefix++
}
Write-Host ("{0,3}: {1}" -f 0,"To Cancel")
[int]$Response = Read-Host "Please Select the SOFS Node You're Working From"
$NodeValue = $null
if ($Response -gt 0 -and $Response -le $Options.Count)
{
$NodeValue = $Options[$Response-1]
$script:NodeName = $NodeValue.Name
}
return $NodeValue
}

$NodeNames = (Get-ClusterNode).Name
$NodeValue = Choose-SOFSNode $NodeNames

# Define Variables
$PoolName = Read-Host "Please enter a name for your new Storage Pool"
#$SSS = Get-StorageSubSystem | where FriendlyName -Like "*Clustered*"
$SSDs = Get-PhysicalDisk | ? Canpool -EQ $true | ? MediaType -EQ SSD | Sort-Object -Property SlotNumber
$SSDs = $SSDs[0..15] # These numbers will need to be changed based on the amount of disks you have and the number of pools you’re creating with them
$HDDs = Get-PhysicalDisk | ? Canpool -EQ $true | ? MediaType -EQ HDD | Sort-Object -Property SlotNumber
$HDDs = $HDDs[0..63] # These numbers will need to be changed based on the amount of disks you have and the number of pools you’re creating with them
$PhysicalDisks = $SSDs + $HDDs
$SSDTierName1 = "SSD-Tier-"+ $PoolName
$HDDTierName1 = "HDD-Tier-" + $PoolName

# Create Storage Pool and Set Default Values
Write-Host "Creating Storage Pool Using best Practice Values" -ForegroundColor Yellow
$StoragePool = New-StoragePool -StorageSubSystemFriendlyName (Get-StorageSubSystem | where FriendlyName -Like "*Clustered*").FriendlyName `
-FriendlyName $PoolName `
-PhysicalDisks $PhysicalDisks `
-ResiliencySettingNameDefault Mirror `
-ProvisioningTypeDefault Fixed `
-EnclosureAwareDefault $True
Set-StoragePool -FriendlyName $StoragePool.FriendlyName -RetireMissingPhysicalDisks Always
$StoragePool | Set-ResiliencySetting -Name Mirror `
-NumberOfDataCopiesDefault 3 `
-NumberOfColumnsDefault 5 `
-InterleaveDefault 64kb

#region Create Storage Tiers
$Tier_SSD = New-StorageTier -StoragePoolFriendlyName $StoragePool.FriendlyName -FriendlyName $SSDTierName1 -MediaType SSD
$Tier_HDD = New-StorageTier -StoragePoolFriendlyName $StoragePool.FriendlyName -FriendlyName $HDDTierName1 -MediaType HDD
#endregion

Create a Tiered Storage Space

Now that we have a Storage Pool, we can move on and create a Storage Space. For this example we’ll be creating a Tiered Pool using both SSD and HDD capacity.
As with the pool, anytime we’re creating a new tiered Storage Space we want the properties to be identical. So we’ve scripted it again. The script does the following:

  • Gets all Storage Pools on the system (minus primordial) and presents them as a numbered list to a user
  • Asks the user what size of Storage Space they’d like to create
  • The script works out 5% as SSD and 95% as HDD
  • Creates tiered Storage Space
  • Partitions, formats and adds the Storage Space to Cluster Shared Volumes
  • Names Storage Space, volume and CSV mount point the same and based on the pool name
#################################################################################
# Script Name: Create a Tiered Storage Space With 5% SSD                        #
# Version Number: 2.0                                                           #
# Created By: David Fleming                                                     #
# Creation Date: 15th December 2015                                             #
#################################################################################

# This Function Gets all Storage Pools Available to the System the Script is Run on and
# Adds Them to a List Which is Ouptut to the Screen for the User to Choose From

$ErrorActionPreference = Stop

Function Choose-Pool
{
PARAM
(
[Parameter(Mandatory=$true)]
$Options,
$DisplayProperty
)
[int]$OptionPrefix = 1
# Create menu list
foreach ($Option in $Options)
{
if ($DisplayProperty -eq $null)
{
Write-Host ("{0,3}: {1}" -f $OptionPrefix,$Option)
}
else
{
Write-Host ("{0,3}: {1}" -f $OptionPrefix,$Option.$DisplayProperty)
}
$OptionPrefix++
}
Write-Host ("{0,3}: {1}" -f 0,"To Cancel")
[int]$Response = Read-Host "Please Select a Pool to Create Your New Storage Space on"
$PoolValue = $null
if ($Response -gt 0 -and $Response -le $Options.Count)
{
$PoolValue = $Options[$Response-1]
$script:PoolName = $PoolValue.FriendlyName
}
return $PoolValue
}

# This Function Asks the User the Desired Size of the Storage Space and Hands off to the UserPrompt Function

Function DataEntry
{
$script:SpaceSize = Read-Host "What Size of Storage Space Would You Like? (In the following format '5GB' or '5TB' with a Maximum Size of 10TB - TB is Assumed if Nothing Specified)"
Write-Host "`n";"Storage Space Size: $SpaceSize";"`n"
UserPrompt
}

# This Function Allows the User to Confirm the Choice Made Above is Correct and Hands off to the SSCreate Function
Function UserPrompt
{
$answer = Read-Host "Please Review Your Answers and Press 'Y' if They Are Correct or 'N' if You Would Like to Re-Enter Them"
If ($answer -match "N")
{
DataEntry
}
If ($answer -match "Y")
{
SSCreate
}
Else
{
UserPrompt
}
}

# This Function Creates a Tiered Storage Space Using 5% SSD and Hands off to the PrepSS Function
Function SSCreate
{
Write-Host "Creating a $SpaceSize Tiered Storage Pool on $PoolName" -ForegroundColor Yellow
# Format User Data For Use in Space Creation
If ($SpaceSize -like '*GB*')
{
$SpaceSizeInt = $SpaceSize -replace '[GB]',''
$SpaceSizeBytes = [int64]$SpaceSizeInt * 1024 * 1024 * 1024
}
Else
{
$SpaceSizeInt = $SpaceSize -replace '[TB]',''
$SpaceSizeBytes = [int64]$SpaceSizeInt * 1024 * 1024 * 1024 * 1024
}
$SSDCapacity = [int64]$SpaceSizeBytes * .05
$HDDCapacity = [int64]$SpaceSizeBytes * .95

# Set Correct Name for New Storage Space
$CurrentCSVCount = Get-StoragePool $PoolName | Get-VirtualDisk | where FriendlyName -Like "*TCSV*" | measure
$NewCSVCount = $CurrentCSVCount.Count + 1
$script:SpaceName = "$PoolName" + "-TCSV" + $NewCSVCount

# Create Tiered Storage Space
$SSD_Tier = Get-StorageTier | where FriendlyName -Like "SSD-Tier*$PoolName"
$HDD_Tier = Get-StorageTier | where FriendlyName -Like "HDD-Tier*$PoolName"
Get-StoragePool $PoolName | New-VirtualDisk -FriendlyName $SpaceName `
-StorageTiers @($SSD_Tier,$HDD_Tier) `
-StorageTierSizes @($SSDCapacity, $HDDCapacity) `
-ResiliencySettingName Mirror `
-NumberOfDataCopies 3 `
-NumberOfColumns 5 `
-PhysicalDiskRedundancy 2 `
-ProvisioningType Fixed `
-Interleave 65536 `
-AutoWriteCacheSize

# Move "Available Storage" ClusterGroup to the node you're working from
Write-Host "Moving Available Storage to Locahost Cluster Node" -ForegroundColor Yellow
Move-ClusterGroup "Available Storage" -Node $env:COMPUTERNAME
Start-Sleep -Seconds 5
PrepSS
}

# This Function Carries out all Post Creation Configuration Tasks on the new Storage Space
Function PrepSS
{
Write-Host "Preparing New Storage Space For Use" -ForegroundColor Yellow
# Renaming and Suspending Cluster Resource (Disk)
$ClusterDisk = Get-ClusterResource -Name "*$SpaceName*"
$ClusterDisk.Name = $SpaceName
Suspend-ClusterResource $ClusterDisk
Get-VirtualDisk -FriendlyName $SpaceName | Get-Disk | New-Partition -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel $SpaceName -AllocationUnitSize 65536 -Force -Confirm:$false
Resume-ClusterResource $ClusterDisk | Add-ClusterSharedVolume
$CSVPath = Get-WmiObject Win32_Volume | where Label -eq $SpaceName
Rename-Item $CSVPath.Name -NewName $SpaceName
# Move new CSV ownership to the node you're working from
Move-ClusterSharedVolume -Name $SpaceName -Node $env:COMPUTERNAME
Write-Host "New Storage Space Created and Ready for Use" -ForegroundColor Green
Exit
}

# The Following Commands Kick off the Script
Clear-Host
$PoolNames = Get-StoragePool | where FriendlyName -NE "Primordial" | Sort-Object -Property FriendlyName
if ($PoolNames.count -gt 1)
{$PoolValue = Choose-Pool $PoolNames "FriendlyName"}
else {$PoolName = $PoolNames.FriendlyName}
DataEntry

We now have a fully configured Storage Spaces cluster, all that’s left to do is to is configure the Scale-Out File Server Role and create some shares…let’s get to it.

Configure Scale-Out File Server Role

So now that we’ve configured our storage, it’s time to present it out to our Hyper-V cluster. To do this we’ll be making use of the Scale-Out File Server feature, this allows us to create continuously available file shares that can survive the failure of one of our storage nodes without affecting Hyper-V’s connectivity to them…which is rather important for network based storage 🙂

Launch “Failover Cluster manager”, right-click on the cluster in the left pane and select “Configure Role”

clip_image002

Click “Next” past the welcome screen. Now select “File Server” and click “Next”

clip_image003

Select “Scale-Out File Server for application data” and click “Next”

clip_image004

Type a name for your SOFS role, this will be the roles DNS name. Click “Next”, “Next” and “Finish”

clip_image005

You’re SOFS role is now configured and ready to accept file shares.

Add Scale-Out File Share

Launch “Server Manager” and run a refresh job, this is required to make sure you’re new CSV is available to you for the next step.

clip_image001

From Server Manager, browse to “File and Storage Services”, “Shares”, “Tasks” and select “New Share…”

clip_image002[1]

Select “SMB Share – Applications” and click “Next”

clip_image003[1]

Select your SOFS server from the “Server” window.
Click “Select by volume” and select your CSV from the list and click “Next”

clip_image004[1]

Enter a name for your share, review the Local and Remote paths to your share and click “Next”

clip_image005[1]

Make sure only “Enable continuous availability” is selected and click “Next”

If you are using this Scale-Out File Server file share for Hyper-V: All Hyper-V computer accounts, the SYSTEM account, cluster computer account for any Hyper-V clusters, and all Hyper-V administrators must be granted full control on the share and the file system.
From <https://technet.microsoft.com/en-us/library/hh831718(v=ws.11).aspx>

Although the above is true, we’ll be having SCVMM manage our shares and it will all required permissions, other than any administrator permissions, you can add these manually before completing the above wizard.

Add SOFS Cluster to SCVMM for Management

Now that we have our SOFS cluster and storage configured, we’re in a position to add it into SCVMM for management. We’ll leave adding the shares to Hyper-V until Part 4 of this series as we don’t actually have a Hyper-V cluster deployed yet 🙂

Within the SCVMM console, browse to “Fabric”, “Storage”, right click “Providers” and select “Add Storage Devices”

clip_image006

On the “Select Provider Type” windows, select “Windows-based file server” and click “Next”

clip_image007

On the “Specify Discovery Scope” page, enter the cluster FQDN under “Provider IP address or FQDN”
Under “Run As account”, click “Browse” and click “Create Run As Account”

clip_image008

Enter a name for the account, “SOFS Run As Account” – this account is the one you created earlier in the guide HERE Set Required Local Administrator Permissions

Enter the Username and password for the account and make sure “Validate domain credentials” is ticked. Now click “Finish”

clip_image009

On the “Gather Information” page, click “Scan Provider” (This may take a while to complete), now click “Next”

clip_image010

On the “Select Storage Devices” page make sure both your SOFS cluster and SOFS role are ticked.
Create a Classification and assign it to both, I’ve used “SOFS Tiered Storage” as it makes sense for my use case. Now click “Next” and “Finish”

clip_image011

Now our storage is all configured and managed by SCVMM, now if only we had a Hyper-V cluster to make use of it. We’ll take care of that in Part 4 🙂

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.