Share via


Getting LUN for a Cluster Disk Ressource with powershell

Question

Tuesday, August 30, 2011 6:54 AM

My storage-colleague added 44 disks to my new Cluster. On the cluster i will later have 22 File Server services. Every service will get 2 LUNs, one for storage with a drive letter, one for snapshots without a drive letter. The disks are dedicated to one service depending on the LUN number. Example:

for service svc50 there are the 2 LUNs 50 and 150.

for service svc51 there are the 2 LUNs 51 and 151.

...

for service svc71 there are the 2 LUNs 71 and 171.

So now i have the 44 LUNs on our cluster and i already managed to get them ready with Powershell:

  • GPT
  • 2TB partitions each with right Cluster Size (16kB)
  • set the right name
  • set a drive letter for 22 disks out of the 44.
  • setting NTFS-ACLs for the new disk and create a data-folder for content for drives with drive letter

But then i have problems to geht the disks to the cluster without loosing overview and i already was looking for ways to get it solved for about 2 days:

  • When adding all disks with "Get-ClusterAvailableDisk | Add-ClusterDisk" i don't know anymore which disk (without drive letter) in cluster was which LUN. The IDs of Cluster Disks doen't match the IDs of diskpart disks, where I can find the LUN-number.
  • When trying to add only special LUNs to the Cluster and then select the new disk I have the same problem with the ID the "Get-ClusterAvailableDisk"-command shows me.
  • When trying to online only one disk and then get this disk with "Get-ClusterAvailableDisk | Add-ClusterDisk" I noticed strange behaviour. For the first disk all was OK, it came up in the cluster with drive letter D:\ as before. I was able to rename it and with the new name i was able to create the service later. But when getting the second disk online and adding it to the cluster it was added on the second node with drive letter D:\ (you remember, the first disk is also D:) and when switching back to the first node my first disk switches to Y:\ Also when expecting this way to be the easiest to get to work, I think the problem here is that you can't check the disks afterwards for correct assignment.

Ideas for a solution are welcome.

PS:

I really need to get the disk with the right LUN to get it in my service, because in times of maintenance we need to know which service will affected when getting a certain LUN offline.

PPS:

Here is the way to get the drive letter for a disk ressource (and so get the LUN with diskpart):

http://blogs.msdn.com/b/clustering/archive/2009/10/16/9908325.aspx

All replies (6)

Tuesday, September 20, 2011 8:37 AM ✅Answered

I think I have found the solution. The following query should work and give you the DISK-ID, which is the same like in diskpart:

Get-ClusterResource §resource | Get-ClusterParameter | where-object { $_.Name -eq "DiskIdGuid"} | ft -property value


Tuesday, August 30, 2011 11:48 AM

Hi,

I have tried a few times the similar task with 70+ LUN's so what i do is after presenting all the LUN's to the host, i reboot the server. After reboot my disks have the same ID as the LUN. Ie. Disk 2 is = LUN 2 . But only after reboot...

This way i can rename all the cluster disks as i can see what i called them in the OS.

I have seen an article somewhere discussing this issue, because in the SQL world it is common in large environments to use alot of mountpoints. I saw a guy from Microsoft commenting on why they don't "carry" over the disk labels to the Cluster Disks, and it was simply because they did not realise that it was used this way out in the public. So he encoureged people to comment on the article that they had this need.

Article: http://social.technet.microsoft.com/Forums/en-US/winserverClustering/thread/3a72789d-2a09-4ecd-9afd-1d8f2820df88

But back to the topic, i would also be interested in knowing a good script that can take all the disk labels and transfer them to the Cluster disks :) it would save me a lot of work.

Best Regards

René


Tuesday, August 30, 2011 12:40 PM

Here is my script, not that I am the perfect powershell-scripter and only for volumes with drive letter so far ;)

 

First of all, I work with a csv-file. Here is the head, you can have as many lines as you want to: "cluservice,preferredowner,LUN,diskname,unit,letter,IP,folder"

cluservice ist the (network-)Name of the cluster-service

preferredowner will be the preferred owner of that service

LUN will be the LUN

diskname is the diskname for that LUN (e.g. LUN 50 shall become svc50)

unit is the allocation unit size (eg. 16k, see diskpart)

letter is the drive letter of that volume

IP is the IP-adress for the cluster service

folder is the folder which will be generated on that volume (can be left blank)

Then my first script makes all the pre-cluster-work:

 

"rescan" | diskpart
$csvfile = Import-Csv Daten.csv
$drives = gwmi Win32_diskdrive | Where-Object {$_.Partitions -eq "0"}
foreach ($disk in $drives) {
    $isincsv = 0
    foreach ($csvitem in $csvfile) {
        if ($disk.SCSILogicalUnit -eq $csvitem.LUN) {
            $isincsv = $isincsv + 1
            $LUN = $csvitem.LUN
            $diskname = $csvitem.diskname
            $unit = $csvitem.unit
            $letter = $csvitem.letter
            $folder = $csvitem.folder
        }
    }
    if ($isincsv -eq 1) {
        $drivenumber = $disk.DeviceID -replace '[\\\\\.\\physicaldrive]',''
        "select disk $drivenumber", "online disk", "attributes disk clear readonly", "convert gpt", "create partition primary" | diskpart
        $diskpartvol = "select disk $drivenumber", "detail disk" | diskpart | where-object { $_.StartsWith(" ") } 
        $vol = $diskpartvol[2].SubString(9,3)
        "select vol $vol", "format fs=ntfs label=$diskname quick unit=$unit" | diskpart
        if ($letter -ne "") {
            "select vol $vol", "assign letter=$letter" | diskpart
            echo Y | cacls.exe $letter':' /g Administrators:f SYSTEM:f
            if ($folder -ne "") {
                New-Item $letter':'$folder -type directory
            }
        }
    }
}
write-host -foreground green "Script finished!"
Wait-Event

 

Then I have a second script for showing the disk details to have a look for:

 

gwmi win32_volume | format-table -property DeviceID, DriveLetter, label, Capacity, BlockSize
gwmi win32_diskpartition | format-table -property DeviceID, StartingOffset
write-host -foreground green "Script finished!"
Wait-Event

 

Next step is adding disks to the cluster and renaming disks with a drive letter:

 

import-module FailoverClusters

$csvfile = Import-Csv Daten.csv
Get-ClusterAvailableDisk | Add-ClusterDisk
$cludisks = Get-ClusterResource | where-object { $_.OwnerGroup -like "Available Storage" }
foreach ($cludisk in $cludisks) {
    $DiskResource = gwmi MSCluster_Resource -Namespace root/mscluster | ?{ $_.Name -eq $cludisk.name }
    $Disk = gwmi -Namespace root/mscluster -Query "Associators of {$DiskResource} Where ResultClass=MSCluster_Disk"
    $Partition = gwmi -Namespace root/mscluster -Query "Associators of {$Disk} Where ResultClass=MSCluster_DiskPartition"
    if ( $Partition.Path -ne "" ) {
        foreach ( $csvitem in $csvfile ) {
            if ( $Partition.Path[0] -contains $csvitem.letter ) {
                Get-ClusterResource $cludisk.name | %{ $_.name = $csvitem.diskname }
            }
        }
    }
}
write-host -foreground green "Script finished!"
Wait-Event

 

The last script than adds the services with the ressources:

 

import-module FailoverClusters

$csvfile = Import-Csv Daten.csv
foreach ($csvitem in $csvfile) {
    $LUN = $csvitem.LUN
    $cluservice = $csvitem.cluservice
    $owner = $csvitem.preferredowner
    $IP = $csvitem.IP
    $diskname = $csvitem.diskname
    $letter = $csvitem.letter
    $clustergroups = Get-ClusterGroup
    if ( -not ( $clustergroups -like $cluservice ) ) {
        Add-ClusterFileServerRole -Storage $diskname -Name $cluservice -StaticAddress $IP -wait 0
        set-clusterownernode -group $cluservice -owners $owner
    }
}
write-host -foreground green "Script finished!"
Wait-Event

 

But to get back to your answer:

The disk 2 is not necessarily the LUN 2! We have LUN0 (local disk) and LUN1 for quorum, followed by LUN 50, 51 and so on. So LUN50 is disk 2 on the server. But here is not my problem, as I can get the LUN-number for any disk in the server and assign the right windows-name to them.

My problem is assigning the windows disk to the disk in the cluster so i can get the right name to the cluster disk (instead of Cluster Disk x).


Wednesday, August 31, 2011 2:54 PM

Maybe the easiest way would be to have one drive letter free (maybe B:\ and get the drive letter to any of the new disks, than identify this disk with the help of the drive letter, rename it and then release the drive letter for the next disk.

But anyway, I don't want to believe that this shall be the way to do it...


Thursday, September 1, 2011 10:52 AM

Would this help at all - http://blogs.technet.com/b/askcore/archive/2011/03/22/mapping-a-cluster-shared-volume-to-the-physical-disk.aspx

Chuck

Chuck Timon Senior, Support Escalation Engineer (SEE) Windows Beta Engineer Microsoft Corporation


Thursday, September 1, 2011 11:53 AM

Thank you for your help.

I am already aware of this article. The problem with this article is that he works with cluster shared volumes (for Hyper-V). He takes the signature of the csv and compares it to the signature of the physical disk (WMI). This doesn't seem to work for Cluster-disk-ressources in the cluster. When I try to compare them (get-clusterressource / diskpart or gwmi), i always get separate signatures.