kthomas45
Contributor
Contributor

Adding a RAW disk to existing VM

I am new to Powershell and PowerCLI and I need to add a RAW device mappings to an existing VM.  I am running Vcenter 4.1.0 and ESXi 4.1. I have tried every suggestion I can find on-line and nothing seems to work.    I can find all the VM and Disk information but I can't get the new-harddisk cmdlet to work. 

Here  is the setup:

I am working on a replicated DR site.

When the disk is split and replication suspended the VMs lose their RAW device mappings and resets those to Virtual Disks.

I need to remove those Virtual Disks and reassign the appropriate RAW disks using the appropriate Virtual Device Node (SCSI(1:0))

It is not hard to do in Vcenter but its a pain when you have quite a few VMs to do. 

Any help would be appreciated.

Tags (2)
0 Kudos
19 Replies
LucD
Leadership
Leadership

How do you determine the appropriate raw disk ?

Are the reset raw disks after the split on device node scsi(1:0) ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
kthomas45
Contributor
Contributor

LucD,

Thanks for responding.

I know the LUN ID already.  and that never changes I can look up the canonical name and if that also does not change I will always know that name/ID.

Yes, the reset has to take place after the disk set is split.  The re-establish/split process is what breaks the connection between the VM and RDM in the first place.  Does that make sense?

-K

0 Kudos
LucD
Leadership
Leadership

So I can assume that you a file (CSV ?) that contains the VM-Canonicalname link ?

Is the virtual disk to be removed always on device node scsi(1:0) ?

Perhaps you could include a screenshot of before and after the split ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
kthomas45
Contributor
Contributor

The virtual disk to be removed ALWAYS assumes the same SCSI assignment that the RDM had before the split so "yes" its always 1:0.  Subsequent RDMs are assigned to 1:1, 1:2, 1:3, 1:4 as necessary but always using those device assignments.

ALso, I haven't put the input file together yet but 'Yes" I could use a CSV file.

I have attached a doc with screen shots of one of my VMs before and after adding the RAW disk.

0 Kudos
LucD
Leadership
Leadership

Try this script.

It requires a CSV file with the following layout

VM        UnitNr    CanonicalName

MyVM          0     naa.600507680180809ed0000000000000f8

You can in fact create this CSV before the split.

Since it seems you can have multiple RDMs, the script requires the UnitNr to know which LUN goes where (scsi(1:0) is UnitNr 0, scsi(1:1) is UnitNr 2,...)

The script uses a hash table to lookup the CanonicalName for a specific VM and a specific UnitNr.

# Assume a CSV with columns
# VM UnitNr CanonicalName
#
$vms = @() $vmLun = @{} Import-Csv "C:\RDM-mapping.csv" -UseCulture | %{     $vms += $_.VM     $vmLun[$_.VM + "|" + $_.UnitNr] = $_.CanonicalName } $vms = $vms | Sort-Object -Unique
foreach
($vmName in $vms){     $vm = Get-VM -Name $vmName
    $sc = Get-ScsiController -VM $vm | where {$_.Extensiondata.BusNumber -eq 1}     Get-HardDisk -VM $vm |where {$_.ExtensionData.ControllerKey -eq $sc.ExtensionData.Key -and $_.Extensiondata.Backing.GetType().Name -notlike "*raw*"} | %{         Remove-HardDisk -HardDisk $_ -DeletePermanently -Confirm:$false
        $canonical = $vmLun[$vm.Name + "|" + $_.Extensiondata.UnitNumber]         $consDev = (Get-ScsiLun -VmHost $vm.Host | where {$_.CanonicalName -eq $canonical}).ConsoleDeviceName         New-HardDisk -VM $vm -DeviceName $consDev -DiskType rawVirtual -Controller $sc | Out-Null
    } }


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
kthomas45
Contributor
Contributor

Thanks for the script LucD.  I'm just getting to it now and am getting several errors that I'm trying to work through.  I attached a screen shot if you're interested.

I'll keep plugging away at it and see what I can fix.  If something jumps out at you let me know.

0 Kudos
LucD
Leadership
Leadership

The Get-ScsiController error is most probably because you are not using the latest PowerCLI build. Do a Get-PowerCLiVersion and check if you have version 4.1U1. The Get-VM error seems to indicate there could be something wrong with CSV file. Is the header row in there with correct names?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
kthomas45
Contributor
Contributor

I upgraded from 4.0U1 to 4.1U1 It appears to be reading the csv file OK.  I ran just the import-csv command and the output is in the attached file. The screen output contains a line after the first record (0).  Not sure if that is part of the issue or not.

0 Kudos
kthomas45
Contributor
Contributor

The "Name" error remains but the Get-ScsiController error has changed.  At least now its recognizing the command.

I will create a new CSV file and see if the first one is corrupt or has other issues. 

0 Kudos
LucD
Leadership
Leadership

The first line in the CSV should be a line with the names of the columns.

VM          UnitNr         CanonicalName

MyVM1         0             naa.123456

MyVM2         0             naa.123456

MyVM2         1             naa.123456


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
kthomas45
Contributor
Contributor

Thanks,  getting closer.  I had the column names in the file but it must have corrupted somewhere along the way.  I just recreated it and it imported.  I am now getting an error on the 'remove' that there is no such disk.  I think it may be an "ordering" issue.  (see attached)  When the virtual disk is deleted the subsequent disk are renumbered and this may be causing an issue.  I will play with it and see if I can restructure a bit.  May need to remove the virtual disk outside the loop......

0 Kudos
Butcha
Contributor
Contributor

Hi LucD,

Quick question......The script that you have posted is very interesting, but it raises a question. When one deletes the last disk on a SCSI controller, I notice that, in fact, the virtual SCSI controller is actually removed entirely. How would the subsequent RDM disk adds actually transpire in this case without using "New-SCSIController" for that initial RDM disk add......

And building on top of this, how would you add subsequent disks after the first one is created along with the new SCSI controller?  I have an idea or two, but honestly, I build off of your brain dumps waaaaaaay more than you know!! LOL

0 Kudos
LucD
Leadership
Leadership

That is correct, the SCSI controller is removed when you remove the last harddisk.

Subsequent New-Harddisk cmdlet would add the new harddisk to the remaining SCSI controller (if present).

If there is no SCSI controller fit to take the new harddisks you will get an error.

Unfortunatly the New-Harddisk cmdlet doesn't have an option to specify the unit number.

That means that your new harddisks will be get sequential unit numbers.

If you want to divert from this sequential sequence, you will have to use the SDK ReconfigVM_Task method, where you can explictely specify a unit number.

See for example my Add-HD function in Adding VMDK's to VM's in new vSphere PowerCLI

In that function I look for the next free unitnumber, but you could easily adapt the function to accept the unitnumber as a parameter to the function.

Let me know if that answers your questions.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
smccreadie
Enthusiast
Enthusiast

LucD,

I am trying to modify this function to be abel to add RDMs to VMs, but not remove any vmdks first.  It seems like this function needs to loop through the existing harddisks on a VM and remove old/replace with new RDM.  I would like to just add RDMs, based on CSV file, to a VM.  Is there an easy way to modify this script to do that?  I cant figure out what I need to be able to add a new harddisk RDM.  Thanks in advance for any help.

Sean

0 Kudos
Butcha
Contributor
Contributor

Building from LucD's and others examples, I was able to come up with the following for adding RDMs to clustered VM pairs using shared disks, and it seems to work flawlesly. It could easily be modified to handle single VMs though. Of course, Im sure that LucD could probably refine this for more efficiency. It requires a csv with column headers.....by the way, great book LucD!! :smileycool:

$DefaultVIServers = $null

Connect-VIServer "" -Credential (Get-Credential)

# Assume a CSV with columns

Import-Csv "C:\TEMP\RDM.csv" -UseCulture | %{
    $vm = Get-VM -Name $_.VM
    $vm2 = Get-VM -Name $_.VM2
    $sc = Get-ScsiController -VM $vm | where {$_.Extensiondata.BusNumber -eq 1}
    $sc2 = Get-ScsiController -VM $vm2 | where {$_.Extensiondata.BusNumber -eq 1}
    $vmLun = $_.CanonicalName
    $rdmPaths = @()

# Operate on the first VM cluster node
      if ($sc) {
        $canonical = $vmLun
        $consDev = (Get-ScsiLun -VmHost $vm.Host | where {$_.CanonicalName -like $canonical}).ConsoleDeviceName
        New-HardDisk -VM $vm -DeviceName $consDev -DiskType RawPhysical -Controller $sc | Out-Null
        }

     else {
        $canonical = $vmLun
        $consDev = (Get-ScsiLun -VmHost $vm.Host | where {$_.CanonicalName -like $canonical}).ConsoleDeviceName
        $hd = New-HardDisk -VM $vm -DiskType RawPhysical -DeviceName $consDev
        New-ScsiController -HardDisk $hd -Type VirtualLsiLogicSAS -BusSharingMode Physical -Confirm:$false
        $hd = @();
        } 
   
       
# Operate on the second VM cluster node   
    Foreach ($disk in $vm.HardDisks){
        if ($disk.DiskType -eq "RawPhysical") {
            $rdmPaths += $disk.Filename
        }
    }   
      
        if ($sc2) {
            New-HardDisk -VM $vm2 -Diskpath $rdmPaths[-1] -Controller $sc2
            }
        else {
            $2ndVMhd = New-HardDisk -VM $vm2 -Diskpath $rdmPaths[-1]
            New-ScsiController -HardDisk $2ndVMhd -Type VirtualLsiLogicSAS -BusSharingMode Physical -Confirm:$false
            $2ndVMhd = @();
        }
    }

0 Kudos
smccreadie
Enthusiast
Enthusiast

Thank you for quick reply.  I will dive into your script tonight to see what I can get out of it.  What I cant seem to get going is the ability to loop through all the devices in the csv file and create new RDMs.  With the New-Hardisk cmdlet, I need to pass it the VM name, controller, and device name.  I jusut cant figure out how to do this when I have multiple RDMs per VM.  I have created a csv file just like LucD specified earlier in the thread, it has all my VM names, along with canonical names and UnitNr.  Thanks again for the post.

Sean

0 Kudos
Butcha
Contributor
Contributor

Totally understand the confusion.

This is actually the loop defined:

Import-Csv "C:\TEMP\RDM.csv" -UseCulture | %{

Entire body of code

}

The '%' is an alias for the 'foreach' command, but foreach what? Since we are piping the import of the csv to it, it automatically becomes 'foreach line in the csv'.....this is how the script is looping through the csv. In my script, I needed clustered VMs manipulated, therefore my csv was setup so that each line of my csv contained a column for each member VM, but for single VMs all you need is one column in your csv for VM name......

0 Kudos
smccreadie
Enthusiast
Enthusiast

Thank you very much for the help on this.  So using the knowledge gained from Butcha, and of course all of LucDs postings, I got some very basic code working for what I need.  I do have some questions though.  Attached is the code I arrived at for now.

This code is very simple of course but it will do what I want, it loops through each line in my csv and adds the RDM to the VM based on naa values I put in the csv file.  The problem I have is this piece of code takes so long to run it drags the entire function in the mud:

$consDev = (Get-ScsiLun -VmHost $vm.Host | where {$_.CanonicalName -eq $canonical}).ConsoleDeviceName

So looking at the output of that line, it seems to scour the hba on the ESX box and find the device with the specified naa value.  But all it seems to output is to append /vmfs/devices/disks/  in front of the naa.  This makes sense of course, but I can prevent waiting forever by just putting /vmfs/devices/disks/naa.12345.. directly in my csv file and omitting this line of code altogether.  I feel like Im missing something here and dont want to have a problem arise down the road.  Thanks again for all the help.

Sean

0 Kudos
LucD
Leadership
Leadership

You're right, that would be a serious time win.

But I'm not sure, if it will be true for all types of storage arrays, hence the original code.

But in your case, yes, go for the shorter way by updating your CSV file


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos