Hello,
Could really use some assistance here. We are moving all of our hardware from 1 data center to another data center using SAN replication. At the destination, the SAN admins are going to be presenting us with the raw storage. Our responsibility is to configure the Mount Points, add the disk to Cluster, rename them to match the mount points, configure the disk to be available to the correct SQL Service, and add the correct dependencies for each of the disk.
This is all being done in a Windows Server 2008 R2 environment.
The only information we have from the old system is the Win32_Volume.Label property, telling us what the old mount point was. Our general structure for mount points is
I:\MP_ROOT - This will have already been pre-created on the destination
I:\MP_ROOT\SQLInstance_Data_MP01
I:\MP_ROOT\SQLInstance_Data_MP02
I:\MP_ROOT\SQLInstance_Data_MPxx
The SQLInstance_Data_MPXX is what the labels will have.
Now, I can automatically add each of the drives to the correct Mount Point without much issue (see script below). I can also use Get-ClusterAvailableDisk | Add-ClusterDisk to add all of the disks to the Cluster.
However, once they have been added to the cluster is where I get lost. I cannot seem to find a way to map/key the output from win32_volume to the Get-ClusterResource output. Get-AvailableDisk has a partitions property, but so far I question the validity of that array, as it shows me duplicate values for drive letters on different disks. Additionally, to add the Mount Points, the disk has to be in the cluster, which means that the disk won't show in the get-availabledisk cmdlet.
Does anyone have any thoughts on what I can do to get this accomplished? With 26 nodes to do this on, and approximately 20 minutes per node, this would save a huge amount of time on the day of the cut over.
Thank you very much for the assistance.
cls
$InstanceName = "SQLInstance"
## remove any available storage from the cluster manager as it hasn't been assigned.
## Really, there shouldn't be anything, but hey, shit happens.
Write-Host "Removing Unassigned Available Storage from Cluster Manager" -ForegroundColor Yellow
Get-ClusterResource | where {$_.OwnerGroup -like "*Available*Storage*"} | Remove-ClusterResource -Force -Verbose
## Removing any cluster resource disk automattically takes it offline. As such, we need to online all disks.
$DiskPartFile = "C:\DiskPart.txt"
$AvailableDisk = Get-ClusterAvailableDisk
Write-Host "No of Cluster disk found = " $AvailableDisk.Count.ToString() ". We are going to try bringing these online now" -ForegroundColor Yellow
foreach ($d in $AvailableDisk)
{
IF (!(Test-Path $DiskPartFile))
{
New-Item $DiskPartFile -ItemType file -Force | Out-Null
}
ELSE
{
Remove-Item $DiskPartFile
New-Item $DiskPartFile -ItemType file -Force | Out-Null
}
$disk = 'SELECT DISK ' + $d.Number.ToString()
Add-Content -Path $DiskPartFile -Value $DISK
Add-Content -Path $DiskPartFile -Value "ONLINE DISK NOERR"
diskpart.exe /S $DiskPartFile
}
## Get a list of all volumes that are online.
$VolumeList = Get-WmiObject -Class win32_volume | where Label -Like '*$InstanceName*' | select name, label, deviceid
###### Remove any Mount Points/or assgined drive letters before we do anything else.
foreach ($v in $VolumeList)
{
$VolumeLabel = $v.Label.TrimStart()
$VolumeLabel = $VolumeLabel.TrimEnd()
$wmi = Get-WmiObject -Class win32_volume -Filter "Label='$VolumeLabel'"
IF ($wmi.Label -like "*Data*" -or $wmi.Label -like "*Log*")
{
WRITE-HOST "Removing Mount Point/Drive Letter information for '$VolumeLabel'" -ForegroundColor Yellow
$wmi.Dismount($true, $false) ## removes mount point
mountvol.exe $wmi.Name /d ## removes drive letters
}
}
## get some clean data to work with
$ClusterDisk = Get-ClusterAvailableDisk
$VolumeList = Get-WmiObject -Class win32_volume | where Label -Like '*$InstanceName*' | select name, label, deviceid
## Now that we have all available disk in the variable above, let's add all cluster resources.
Write-Host "Adding storage back to Cluster Manager" -ForegroundColor Yellow
Get-ClusterAvailableDisk | Add-ClusterDisk
## Now that we have removed all of the mount points, we are going to
## add individual drives to a specific drive letter and then use that
## drive lette to figure everything out.
foreach ($vl in $VolumeList)
{
$VolumeLabel = $vl.label.TrimStart()
$VolumeLabel = $VolumeLabel.TrimEnd()
Write-Host "volume label = $VolumeLabel"
IF ($VolumeLabel -like "*Data*" -or $VolumeLabel -like "*Log*")
{
Write-Host $wmi.Label -ForegroundColor Yellow
$wmi = Get-WmiObject -Class win32_volume -Filter "Label='$VolumeLabel'"
$PATH = "I:\MP_ROOT\$VolumeLabel\"
Write-Host $PATH -ForegroundColor Yellow
IF(!(Test-Path $PATH))
{
Write-Host "Directory $Path created" -ForegroundColor Cyan
New-Item -ItemType DIRECTORY -Path $PATH
}
ELSE
{
Write-Host "Directory $PATH already exists" -ForegroundColor Yellow
}
## Add the mountpoint
Write-Host "Adding Mount Point $Path for Label: " $wmi.Label
$wmi.AddMountPoint($PATH)
#$wmi.Put()
#Set-WmiInstance -InputObject $wmi -Arguments @{DriveLetter="Z:"; Label=$VolumeLabel}
#Write-Host "Assigning Drive letter Z: to '$VolumeLabel'" -ForegroundColor Green
#$VolumeName = $wmi.Name.Substring(0)<#
Write-Host "voluemName = $VolumeName" -ForegroundColor red
foreach ($cd in $ClusterDisk)
{
if ($cd.Partitions.DriveLetter -eq $VolumeName)
{
Write-Host "we have a match for $VolumeName" -ForegroundColor Red
}
}
#WRITE-HOST "Removing Mount Point/Drive Letter information for '$VolumeLabel'" -ForegroundColor Yellow
mountvol.exe $wmi.Name /D
#>
}
}