#start
write-output "
=================================================================
Welcome to the EASYSTOREAGESPACEWITHTIERS script.
By Luke Varley - www.phishandchips.dev
This script will allow you to easily create a Tiered Storage Spaces
Virtual Disk
Read the comments in the script for instructions
#Created with knowledge obtained from
nils.schimmelmann
#Credit: https://nils.schimmelmann.us/post/153541254987/intel-smart-response-technology-vs-windows-10
Joe Freeman
#Credit: https://github.com/freemansoft/win10-storage-spaces
=================================================================
"
#check if elevation is required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
write-output "
=================================================================
SCRIPT REQUIRES ELEVATION, PLEASE RUN FROM AN ADMINISTRATIVE
POWERSHELL WINDOW. RUN AS ADMINISTRATOR.
=================================================================
"
Pause
Exit
}
}
Pause
#start
#Pool that will suck in all drives
$StoragePoolName = "VMStoreTiered"
#Tiers in the storage pool
$SSDTierName = "SSDTier-VMStoreTiered"
$HDDTierName = "HDDTier-VMStoreTiered"
#Virtual Disk Name made up of disks in both tiers
$TieredDiskName = "VMStoreTieredVD"
#Set Mirror, Simple, or Parity Resiliency type. Simple = striped. Mirror only works if both can mirror AFIK
#https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn387076(v=ws.11)
$SSDTierResiliency = "Simple"
$HDDTierResiliency = "Simple"
#$ntfs_aus = Parity calculation: ($number_of_columns - 1) * $interleave
# Double parity Calculation: ($number_of_columns - 2) * $interleave
# Simple Calculation: ($number_of_columns) * $interleave
$SSDInterleave = "65536" #in Bytes
$HDDInterleave = "32768" #in Bytes
$AllocationUnitSize = "65536" #in Bytes
#
$NumberOfHDDColumns = "2"
$NumberOfSSDColumns = "1"
#Change to suit - drive later and the label name
$TieredDriveLetter = "H"
$TieredDriveLabel = "VMStoreTiered"
#Override the default sizing here - useful if have two different size SSDs or HDDs - set to smallest of pair
#These must be Equal or smaller than the disk size available in that tier SSD and HDD
#SSD:cache - HDD:data
#set to null so copy/paste to command prompt doesn't have previous run values
$SSDTierSize = $null
$HDDTierSize = $null
#Drives cannot always be fully allocated - probably broken for drives < 10GB
$UsableSpace = 0.99
#Uncomment and put your HDD type here if it shows up as unspecified with "Get-PhysicalDisk -CanPool $True
# If your HDDs show up as Unspecified instead of HDD
#$UseUnspecifiedDriveIsHDD = "Yes"
#List all disks that can be pooled and output in table format (format-table)
Get-PhysicalDisk -CanPool $True | ft FriendlyName, OperationalStatus, Size, MediaType
#Store all physical disks that can be pooled into a variable, $PhysicalDisks
# This assumes you want all raw / unpartitioned disks to end up in your pool -
# Add a clause like the example with your drive name to stop that drive from being included
# Example " | Where FriendlyName -NE "ATA LITEONIT LCS-256"
if ($UseUnspecifiedDriveIsHDD -ne $null){
$DisksToChange = (Get-PhysicalDisk -CanPool $True | where MediaType -eq Unspecified)
Get-PhysicalDisk -CanPool $True | where MediaType -eq Unspecified | Set-PhysicalDisk -MediaType HDD
# show the type changed
Get-PhysicalDisk -CanPool $True | ft FriendlyName, OperationalStatus, Size, MediaType
}
$PhysicalDisks = (Get-PhysicalDisk -CanPool $True | Where MediaType -NE UnSpecified)
if ($PhysicalDisks -eq $null){
throw "Abort! No physical Disks available"
}
#Create a new Storage Pool using the disks in variable $PhysicalDisks with a name of My Storage Pool
$SubSysName = (Get-StorageSubSystem).FriendlyName
New-StoragePool -PhysicalDisks $PhysicalDisks -StorageSubSystemFriendlyName $SubSysName -FriendlyName $StoragePoolName
#View the disks in the Storage Pool just created
Get-StoragePool -FriendlyName $StoragePoolName | Get-PhysicalDisk | Select FriendlyName, MediaType
#Create two tiers in the Storage Pool created. One for SSD disks and one for HDD disks
$SSDTier = New-StorageTier -StoragePoolFriendlyName $StoragePoolName -FriendlyName $SSDTierName -MediaType SSD -NumberOfColumns $NumberOfSSDColumns -Interleave $SSDInterleave -ResiliencySettingName $SSDTierResiliency
$HDDTier = New-StorageTier -StoragePoolFriendlyName $StoragePoolName -FriendlyName $HDDTierName -MediaType HDD -NumberOfColumns $NumberOfHDDColumns -Interleave $HDDInterleave -ResiliencySettingName $HDDTierResiliency
#Calculate tier sizes within this storage pool
#Can override by setting sizes at top
if ($SSDTierSize -eq $null){
$SSDTierSize = (Get-StorageTierSupportedSize -FriendlyName $SSDTierName -ResiliencySettingName $SSDTierResiliency).TierSizeMax
$SSDTierSize = [int64]($SSDTierSize * $UsableSpace)
}
if ($HDDTierSize -eq $null){
$HDDTierSize = (Get-StorageTierSupportedSize -FriendlyName $HDDTierName -ResiliencySettingName $HDDTierResiliency).TierSizeMax
$HDDTierSize = [int64]($HDDTierSize * $UsableSpace)
}
Write-Output "TierSizes: ( $SSDTierSize , $HDDTierSize )"
# you can end up with different number of columns in SSD - Ex: With Simple 1SSD and 2HDD could end up with SSD-1Col, HDD-2Col
New-VirtualDisk -StoragePoolFriendlyName $StoragePoolName -FriendlyName $TieredDiskName -StorageTiers @($SSDTier, $HDDTier) -StorageTierSizes @($SSDTierSize, $HDDTierSize) -WriteCacheSize 0GB
# initialize the disk, format and mount as a single volume
Write-Output "preparing volume"
Get-VirtualDisk $TieredDiskName | Get-Disk | Initialize-Disk -PartitionStyle GPT
# This will be Partition 2. Storage pool metadata is in Partition 1
Get-VirtualDisk $TieredDiskName | Get-Disk | New-Partition -DriveLetter $TieredDriveLetter -UseMaximumSize
Initialize-Volume -DriveLetter $TieredDriveLetter -FileSystem REFS -AllocationUnitSize $AllocationUnitSize -Confirm:$false -NewFileSystemLabel $TieredDriveLabel
Get-Volume -DriveLetter $TieredDriveLetter
$TieredDriveLetterPath = "$TieredDriveLetter" + ":\"
Write-Output "Setting REFS File integrity on:"
$TieredDriveLetterPath
Set-FileIntegrity $TieredDriveLetterPath -Enable $True
Write-Output "Operation complete"