Removing tiered storage spaces - Windows Server 2022

As part of the work I have done in my homelab with tiered storage on Server 2022 storage spaces, here is a script I created that allows you to easily remove a tiered storage space, so you can start again from scratch with your pool of disks

Drop this in a .ps1 file and watch it go:

#Provided by Luke Varley - www.Phishandchips.dev
#orignal creator Joe Freeman
#Credit: https://github.com/freemansoft/win10-storage-spaces
#Variables names here MUST MATCH create-storage-space.ps1
#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
$StoragePoolName = "VMStoreHDDCache"
$SSDTierName = "SSDTier-VMStoreHDD"
$HDDTierName = "HDDTier-VMStoreHDD"
$TieredDiskName = "VMStoreHDDCacheVD"

# Make sure they really want to do this!
$choices  = '&Yes', '&No'
$decision = $Host.UI.PromptForChoice('Remove Storage Space', 'Are you sure you wish to remove the storage space named "' + $TieredDiskName + '"?' + [Environment]::NewLine + 'ALL DATA WILL BE PERMANENTLY LOST', $choices, 1)
if ($decision -ne 0) {
    exit
}

# In reverse order of creation
if ((Get-VirtualDisk -FriendlyName $TieredDiskName) -ne $null){
    Write-Output "Removing drive: $TieredDiskName"
    Get-VirtualDisk -FriendlyName $TieredDiskName
    Remove-virtualdisk -friendlyName $TieredDiskName -Confirm:$false
} else {
    Write-Output "Drive does not exist: $TieredDiskName"
}

# Remove Storage Tier
if ((Get-StorageTier -FriendlyName $HDDTierName) -ne $null){
    Write-Output "Removing storage tiers: $HDDTierName"
    Get-StorageTier -FriendlyName $HDDTierName | FT FriendlyName, MediaType, Size -AutoSize
    Remove-StorageTier -FriendlyName $HDDTierName -Confirm:$false
} else {
    Write-Output "Tier does not exist: $HDDTierName"
}
if ((Get-StorageTier -FriendlyName $SSDTierName) -ne $null){
    Write-Output "Removing storage tiers: $SSDTierName"
    Get-StorageTier -FriendlyName $SSDTierName | FT FriendlyName, MediaType, Size -AutoSize
    Remove-StorageTier -FriendlyName $SSDTierName -Confirm:$false
} else {
    Write-Output "Tier does not exist: $SSDTierName"
}
Get-StorageTier

# Remove the Storage Pool
if ((Get-StoragePool -FriendlyName $StoragePoolName) -ne $null){
    Write-Output "Removing storage pool: $StoragePoolName"
    Get-StoragePool -FriendlyName $StoragePoolName | Get-PhysicalDisk | FT FriendlyName, MediaType
    Remove-StoragePool -FriendlyName $StoragePoolName -Confirm:$false
} else {
    Write-Output "Storage Pool does not exist: $StoragePoolName"
}
# Show just the primoridal pool
Write-Output "Poolable drives after cleanup"
Get-StoragePool | Get-PhysicalDisk -CanPool:$True

Write-Output "Operation complete"

Finding the max size of a tiered storage space - Windows Server 2022

As part of the work I have done in my homelab with tiered storage on Server 2022 storage spaces, here is a script I created that allows you to easily find the max size of a tiered storage space

Drop this in a .ps1 file and watch it go:

#start
write-output "
=================================================================
Welcome to the EASYTIERSIZEMAX script.

By Luke Varley  - www.phishandchips.dev

This script will allow you to easily Calculate the max size of a Tiered Storage Spaces
Virtual Disk when you add new a SSD or HDD.

Read the comments in the script for instructions

#Created with knowledge obtained from
 Philippe Tschumi
#Credit: https://techblog.ptschumi.ch/automation-scripting/storage-spaces-direct-query-maximum-tier-size-storage-tiers/
=================================================================
"

$vdisks = Get-VirtualDisk
$diskdata=@()
 
foreach ($vdisk in $vdisks){
    $storagetiers = Get-StorageTier -VirtualDisk $vdisk
    $i=0
 
    foreach ($storagetier in $storagetiers){
        # ResiliencySettingName can be Mirror, Simple or Parity depending on your deployment
        $tier = $storagetier | Get-StorageTierSupportedSize -ResiliencySettingName Simple # edit ResiliencySettingName
        $tiermin = ($tier.TierSizeMin/1GB)
        $tiermax = ($tier.TierSizeMax)/1GB
        $tierdivisor = ($tier.TierSizeDivisor)/1GB
        $object = New-Object -TypeName PSObject -Property (@{
            'vDisk'= $vdisk.FriendlyName;
            'StorageTier'= $storagetier.FriendlyName
            'TierSizeMin'= $tiermin;
            'TierSizeMax'= $tiermax;
            'TierSizeDivisor'= $tierdivisor
        })
        $diskdata += $object
        $i++
    }
}
$diskdata | Select-Object vDisk, StorageTier, TierSizeMin, TierSizeDivisor, TierSizeMax | ft -AutoSize

Extending tiered storage spaces - Windows Server 2022

 As part of the work I have done in my homelab with tiered storage on Server 2022 storage spaces, here is a script I created that allows you to easily extend a tiered storage space, so you can expand your storage pool size when you add more disks or even replace your current disks with higher capacity ones

Drop this in a .ps1 file and watch it go:

#start
write-output "
=================================================================
Welcome to the EASYExtendTieredVD script.

By Luke Varley  - www.Phishandchips.dev

This script will allow you to easily extend a Tiered Storage Spaces
Virtual Disk when you add new a SSD or HDD

Read the comments in the script for instructions

#Created with knowlegde 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
=================================================================
"
# https://nils.schimmelmann.us/post/153541254987/intel-smart-response-technology-vs-windows-10
#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
#
#Number of columns in your VD is the number of disks you need to add before you can utilise the extra capacity of those disks
    #so if you have 3 columns, you wont be able to exend capacity of your VD until you add an extra 3 disks
        #OR you replace all disks in your storage tier with disks of a higher capacity e.g. 8TB - 4 x 2TB disks, replace each disk 1 by 1 to 4 x 4tb disks for 16TB capacity
#Tiers in the storage pool
#Find these by running get-StorageTier
$SSDTierName = "VMStoreHDDCacheVD-SSDTier-VMStoreHDD"
$HDDTierName = "VMStoreHDDCacheVD-HDDTier-VMStoreHDD"

#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 to calculate the max size, not always working... better to manually specify a size
#set to $null the tier you dont want to extend, to extend both populate both with the apropriate value
$SSDTierSize = 508GB
$HDDTierSize = 7.22TB
#Drives cannot always be fully allocated - probably broken for drives < 10GB
#Dont change this
$UsableSpace = 0.99
#Set tier Resilency setting
$SSDTierResiliency = "Simple"
$HDDTierResiliency = "Simple"

#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 )"

$HDDTierSizeBytes = $HDDTierSize / 1GB
$HDDTierSizeGB = "$HDDTierSizeBytes" + "GB"
$SSDTierSizeBytes = $SSDTierSize / 1GB
$SSDTierSizeGB = "$SSDTierSizeBytes" + "GB"

#Extend two tiers in the Storage Pool created. One for SSD disks and one for HDD disks
Write-Output "Extend $SSDTierName by:"
$SSDTierSizeGB
Resize-StorageTier -FriendlyName $SSDTierName -size $SSDTierSize
Write-Output "Extend $HDDTierName by:"
$HDDTierSizeGB
Resize-StorageTier -FriendlyName $HDDTierName -size $HDDTierSize
Write-Output "Operation complete"

Creating tiered storage spaces - Windows Server 2022 - Getting the best performance on your home server

Ever since I rebuilt my homelab during the covid pandemic, I was never happy with the performance I was getting for the hardware that I had. Homelab 2.0 as I dubbed it has changed to something different than I originally designed, moving from VMware vcenter to Hyper-V 2022 being one of the biggest changes! Frustratingly, I have rebuilt this lab about 3 or 4 times now to get things working as well as it should.

The final issue I’m battling is dreadful storage write and read speeds in storage spaces on server 2022.

If you have been using storage spaces in your homelab, you probably had performance issues. Google it and you will see there’s tons of discussion and blogs about this topic online.

Like most things designed for enterprise, things are not always as simple as they seem. When it comes to storage spaces and getting the most out of your hardware, there are some best practices that need to be followed, the problem is they aren't very well documented by MS and as a result most people have had issues and had to figure it out by themselves. Thankfully, there are other people like me who blog their findings and share knowledge online for others, filling that documentation void.

There's a severe lack of documentation on a lot of MS storage spaces stuff. for the most part I resorted to going back to basics, doing what we do in vendor support, creating a lab vm and testing things out !

This was accompanied by a LOT of research, I would recommend that you check out the following resources, these guys do a way better job of explaining this than I could:


The summary of it is you have to carefully match your interleave, column and allocation unit size:

Allocation Unit size = Parity calculation: ($number_of_columns - 1) * $interleave
                                    Double parity Calculation: ($number_of_columns - 2) * $interleave
                                    Simple Calculation: ($number_of_columns) * $interleave

My original plan was to use SSD caching in my server as I thought that would solve my issues. I bought some SSDs on prime day and set out to configure it. Originally, I thought that storagebus cache would be the best solution, I already run server 2022 and do not have clustering, should be simple right.

In the end I decided against this... the severe lack of documentation and no information about this online make it a dangerous prospect. My original plan was again to lab this feature out and see how it works, but I had so many issues getting this to work in a VM that I decided it was too risky to put data in this configuration without knowing how I would handle drive failures and general DR related scenarios. I am not sure if my failures were due to me trying to do this in a VM or not, but I saw other people online who blogged about it and did have it working in a VM. I was confused to say the least.

New and unproven technology with little info online is a risky data storage solution. Furthermore, when comparing it with the old storage tiers type setup for SSD caching there was no real information about any benefits to using storagebus cache over tiers. Plus, there’s a lot more information out there about storage tiers configuration with PowerShell, so I decided that would be the best option and got to work writing a script in the lab to configure this.

It took a while to get working but I started out by taking the knowledge obtained from nils schimmelmann (https://nils.schimmelmann.us/post/153541254987/intel-smart-response-technology-vs-windows-10) and Joe Freeman (https://github.com/freemansoft/win10-storage-spaces) then building on that to create my own scripts.

I have provided a script below that you can use to create a tiered storage space and adjust the allocation unit size, columns and interleave sizes to suit your setup.

The beauty of it is that you can create SSD (performance) tier and a HDD (Capacity) tier and set different Resiliency settings, Interleave and Column sizes to suit how many disks you have of each type.

For example in my script below i configure a volume that has 2 HDD's and 1 SSD, therefore i needed to set different Interleave and Column sizes to match my Allocation unit size of 64K on REFS.

(I also created some scripts to extend or remove a tired storage space, as well as check the max size space you can create based on the type of array you have.)

Drop this in a .ps1 file and watch it go:

#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"

EASYGETSID - An easy to use script to look up users or group SID's from AD

 

Hey Everyone,

A while back i needed a way to easily look up Group or User SID's for ad users. I needed to do this in a repetitive way where i could over and over look up individual SID's and just keep a Powershell window open on the side for when i wanted to do it, i could literally just paste in the username and hit enter and then boom, here's your SID !

I knocked up this script within about 20 mins that allows me to do it without having to remember any commands or import any Powershell modules.

It was handy for me a while back when i was working on a project so maybe it will be useful for someone else too.

How to move SQL database files (MDF and LDF) to another location

Pre-requisites

In case a database is being used by any Windows services or other resources, these must be stopped in order to allow altering SQL database files. Also, any existing connections to a database must be closed. Before the first step, make sure to locate the appropriate MDF and LDF files for a database you want to work with. By default, these names are in the following format:

    • Database_name_Data.mdf – for MDF file
    • Database_name_log.ldf – for LDF file

The above mentioned format does not need to be necessarily used, so make sure you are targeting correct files.

Moving database files to another location

    • Run the following SQL script to set a new location for SQL database files:
    •  

ALTER DATABASE AdventureWorks2014  

    MODIFY FILE ( NAME = AdventureWorks2014_Data,  

                  FILENAME = 'E:\New_location\AdventureWorks2014_Data.mdf');  

GO

 

ALTER DATABASE AdventureWorks2014  

    MODIFY FILE ( NAME = AdventureWorks2014_Log,  

                  FILENAME = 'E:\New_location\AdventureWorks2014_Log.ldf');  

GO

The New_location is a folder created on a separate drive (in this specific case, we will change from a default C to E drive on a local machine) with sufficient disk space for SQL database files. Specified folder must be created first, in order to be used as a new location for SQL database files in the above SQL statement

    • Run the following SQL script to take a SQL database offline:
    •  

ALTER DATABASE AdventureWorks2014 SET OFFLINE;  

GO

This is important in order to perform the next step. If a database is being used by any application, this step cannot be accomplished, unless all connections to a database are closed.

    • Move MDF and LDF files of the specific SQL database to a new location specified in the statement above. This means to simply cut mentioned files from the existing location and to move them to a newly specified one.

Important note: Make sure that SQL Server can access the specified location. Otherwise, the following error will appears:

Msg 5120, Level 16, State 101, Line 13

Unable to open the physical file “E:\New_location\AdventureWorks2014_Data.mdf”. Operating system error 5: “5(Access is denied.)”.

To fix this:

    • Start SQL Server Configuration Manager
    • Right click a SQL Server instance that hosts a database which files are moved to a new location and choose the Properties option from the drop-down list:

Instead of the current account, switch to the one that has access to a drive where files are moved:

    • Once this is done, a database can be set online by running the following query to get back a database online:
    •  

ALTER DATABASE AdventureWorks2014 SET ONLINE;  

GO

    • To verify that the process is finished successfully run the following query:
      •  

SELECT name, physical_name AS NewLocation, state_desc AS OnlineStatus

FROM sys.master_files  

WHERE database_id = DB_ID(N'AdventureWorks2014')  

GO

This should give the following result:

Once this is done, a SQL database will be hosted on a drive with sufficient free space and the user can continue using it.

 

From <https://www.sqlshack.com/move-sql-database-files-mdf-ldf-another-location/>

 

 

Created with OneNote.

Could not locate file 'mydatabase' for database 'mydatabase' in sys.database_files. The file either does not exist, or was dropped

 

 

Could not locate file 'mydatabase' for database 'mydatabase' in sys.database_files. The file either does not exist, or was dropped

18 October 2022

02:54

dbcc shrinkfile('mydatabase',113311) fails with following error

Could not locate file 'mydatabase' for database 'mydatabase' in sys.database_files. The file either does not exist, or was dropped

 

I managed to resolve it by renaming the logical name of the log file:

USE [clientdatabase];
ALTERDATABASE clientdatabase MODIFY FILE
(NAME =clientdatabase_log, NEWNAME =clientdatabase_log_1);

Running the script

USE [clientTdatawarehouse]
GO
DBCC SHRINKFILE (clientTDataWarehouse_log_1, 1024)
GO

 

From <https://stackoverflow.com/questions/12644312/could-not-locate-file-mydatabase-for-database-mydatabase-in-sys-database-fil>

 

Created with OneNote.

Removing tiered storage spaces - Windows Server 2022

As part of the work I have done in my homelab with tiered storage on Server 2022 storage spaces , here is a script I created that allows you...