Use PowerCLI to find the datastore from a disk name

PowerCLI logoRecently we get vSphere alarms in our environment that say for instance:

“[VMware vCenter – Alarm Host error] Issue detected on host in datastore: ScsiDeviceIO: 2368: Failed write command to write-quiesced partition naa.600a0b8000111155000021c53f97784e:1 (42:01:04:07.994 cpu7:5191)”

There seems to be a problem on a partition. But which datastore is on this partition? We can use PowerCLI to find the datastore involved.

List all datastores and disk names

We can use the PowerCLI script from listing 1 to list all datastores and the disk names of the partitions.

Get-Datastore |
Where-Object {$_.ExtensionData.Info.GetType().Name -eq "VmfsDatastoreInfo"} |
ForEach-Object {
  if ($_)
  {
    $Datastore = $_
    $Datastore.ExtensionData.Info.Vmfs.Extent |
    Select-Object -Property @{Name="Name";Expression={$Datastore.Name}},
      DiskName
  }
}

Listing 1. PowerCLI script to list all datastores and the disk names of the partitions.

A sample output of this script is:

Name                        DiskName
----                        --------
esxi01_boot                 naa.600a0b80001111550000fb9cf54f414d
esxi02_boot                 naa.600a0b80001111550000850e884f414d
cluster01_gold_001          naa.600a0b80001111550000778bc952494d
cluster01_silver_001        naa.600a0b8000111155000074088c52494d
cluster01_bronze_003        naa.600a0b80001111550000e451a8ed794e
esxi03_boot                 naa.600508b4001078340000e00004c00000
esxi04_boot                 naa.600508b4001078340000e00002c60000
cluster02_gold_001          naa.600508b400055c680000800000dc0000
cluster02_silver_001        naa.600508b4001078340000e00004bb0000
cluster02_bronze_001        naa.600508b4001078340000e00002cb0000

Output 1. Sample output from the PowerCLI script from listing 1.

Of course you can try to find the diskname and the corresponding datastore in the list. But if the list is long this is not easy.

A better way is to let PowerCLI do the search.

Find a specific datastore

The PowerCLI from listing 2 shows returns only the datastore that contains the partition with the requested disk name.

Get-Datastore |
Where-Object {$_.ExtensionData.Info.GetType().Name -eq "VmfsDatastoreInfo"} |
ForEach-Object {
  if ($_)
  {
    $Datastore = $_
    $Datastore.ExtensionData.Info.Vmfs.Extent |
      Where-Object {$_.DiskName -eq "naa.600a0b80001111550000fb9cf54f414d"} |
      ForEach-Object {
        if ($_)
        {
          $Datastore
        }
      }
  }
}

Listing 2. PowerCLI script to get the datastore that contains the partion with the requested disk name.

Unfortunately the script from listing 2 is slow. In our environment with 138 datastores the script takes 43 seconds to run.

A faster script

I decided to make a PowerCLI advanced function that searches for the datastore as fast as possible. It uses the PowerCLI Get-View cmdlet to retrieve all the datastores. It then tries to match the datastores in this list with the given disk name.

function Get-DatastoreByDiskName {
  <#
  .SYNOPSIS
    Retrieves the datastore for a given disk name.
	
  .DESCRIPTION
    Retrieves the datastore for a given disk name.
	
  .PARAMETER DiskName
    Specify the disk name of the partition in the datastore to search for.
	
  .EXAMPLE
    Get-DatastoreByDiskName -DiskName naa.600a0b80001111550000a3fdfb4e6c4f
    Retrieves the datastore with disk name naa.600a0b80001111550000a3fdfb4e6c4f.
	
  .EXAMPLE
    "naa.600a0b800011115500006852e34d6c4f" | Get-DatastoreByDiskName
    Retrieves the datastore with disk name naa.600a0b800011115500006852e34d6c4f.
	
  .COMPONENT
    VMware vSphere PowerCLI

  .INPUTS
    String
	
  .OUTPUTS
    VmfsDatastoreImpl

  .NOTES
    Author:  Robert van den Nieuwendijk
    Date:    1-6-2012
    Version: 1.0

  .LINK
    https://rvdnieuwendijk.com/
    http://twitter.com/rvdnieuwendijk
	
  #>
  
  [CmdletBinding()]
  param(
    [parameter(Mandatory = $true,
               ValueFromPipeline = $true,
               ValueFromPipelineByPropertyName = $true)]
    [string[]] $DiskName
  )
  
  begin {	
    # Get all the datastores
    $DatastoresView = Get-View -ViewType Datastore -Property Name,Info
  }
  
  process {
    ForEach ($Datastore in $DatastoresView)
    {
      # Only objects of type VMware.Vim.DatastoreInfo.VmfsDatastoreInfo
      # have the Info.Vmfs property
      if ($Datastore.Info.GetType().Name -eq "VmfsDatastoreInfo")
      {
        ForEach ($Disk in $DiskName)
        {
          $Datastore.Info.Vmfs.Extent |
            ForEach-Object {
              if ($_ -and $_.Diskname -eq $Disk)
              {
                # Return the found datastore
                $Datastore | Get-VIObjectByVIView 
              }
            }
        }
      }
    }
  }
}

Listing 3. A PowerCLI advanced function that searches for the datastore as fast as possible.

This script finds one datastore in 1.5 seconds. That is 29 times faster than the script from listing 2.

You can use the advanced function to search for multiple datastores at once. Every extra datastore took me 1.1 seconds extra.

Annotations

Line 50: Get all the datastores.

Line 54-72: Loop through all the datastores.

Line 60-70: Loop through all the disk names.

Line 67: Return the found datastore.

Conclusion

We have not solved the issue from our vCenter alarm yet. But it least we now know which datastores are involved.

Writing PowerCLI code for maximum speed can make your code significantly faster.

Update Januari 2nd, 2013: Thanks to reader Brad S. who commented on a problem that was in the original script of listing 1, I could solve the bug in this script. I updated the scripts in listing 1 and listing 2 to work correctly with datastores that have multiple extents.

Advertisement

About Robert van den Nieuwendijk
Robert van den Nieuwendijk is a freelance senior systems engineer with over 30 years of experience in the IT industry. He focusses on VMware vCloud Suite and Microsoft Windows Server. He tries to automate as much of his work as possible using Microsoft PowerShell. Robert is the author of the books “Learning PowerCLI” and “Learning PowerCLI – Second Edition.” Robert is a frequent contributor and moderator at the VMware VMTN Communities. He has a bachelor degree in software engineering and holds the following IT certifications and accreditations: VSP 2016, VTSP 2016, VCP4-DCV, VCP5-DCV, VCP6-DCV, VCP6-CMA, VCA-Cloud, VCA-WM, VCA-NV, VMSP, VMTSP, ZCS, ZCP, ZCP-Cloud, MCSE, MCSA, MCP, MCP+I, PRINCE2 Foundation and ITIL Foundation. In 2012, 2013, 2014, 2015, 2016, 2017, 2018 and 2019 Robert received the VMware vExpert award for his contribution to the community of VMware users over the past year. In 2017 Robert also received the VMware vExpert Cloud award. PernixData made him in 2015 a member of the PernixPro.

13 Responses to Use PowerCLI to find the datastore from a disk name

  1. Yolte says:

    Hello Robert,

    Did you find any solution for “Failed write command to write-quiesced partition” ?

    We have same problem too and cant resolved yet.

    Best Regards

    • Hi Yolte,

      we did not find a solution to this problem yet. Although we found some more information.

      Looking at the ESXi server’s /var/log/messages file, at the time of the problem, it shows a SCSI error D:0x28. That translates to the target device (the storage) says “task set full” or “queue full”. The storage in this case is a HP Enterprise Virtual Array (EVA) behind a HP SAN Virtualization Services Platform (SVSP). Unfortunately we can’t find any problem at SVSP or the EVA.

      So we are still searching for a solution. If we find one, I will let you know. Please let me know if you find a solution before we do.

      Regards, Robert

  2. Greg says:

    When i run your listing 1 script all i get back are the datastore names. Diskname is blank.

    • Hi Greg,

      in our vSphere environment we have fibre channel and NFS datastores. The script in listing 1 returns name and diskname for all our fibre channel datastores only. The NFS datastores are not returned by the script at all. Maybe are you using iSCSI?

      I tested my script using PowerCLI 5.1 Release 1, against a vCenter Server v5.1.0a.

      Regards, Robert

  3. Jonathan says:

    Same as Greg.. and I am using PowerCLI 5.0.1 on vCenter 4.1

    • First I thought that problem was in the PowerCLI version. So I tested the script from listing 1 with PowerCLI 5.0.1. That works fine for me. When I wrote this blogpost we were still runnning vCenter 4.1. So that seems also not the problem. Are you sure you have Fibre Channel datastores and not iSCSI? Because we don’t have iSCSI so I can’t test against that.

  4. Brad S. says:

    This should work

    “get-Datastore |

    Where-Object {
    $_.ExtensionData.Info.GetType().Name -eq “VmfsDatastoreInfo”} |
    Select-Object -Property Name,
    @{Name=”DiskName”;Expression={ $_.ExtensionData.Info.Vmfs.Extent[0].DiskName} }”

    Not sure why we need to use the [0] but I saw other scripts use it and decided to give it a try
    $_.ExtensionData.Info.Vmfs.Extent[0].DiskName

  5. Hi Brad,

    thank you very much for your reaction.

    That you need to use Extent[0] means that you have datastores with multiple extents. With Extent[0] you specify the first extent. I never tested my script against datastores with multiple extents because all our datastores have only one extent.

    I will modify the scripts in this blog post to let them work correctly with datastores with multiple extents.

    Kind regards, Robert

  6. Martin says:

    Hello Robert,

    Thank you for this!

    Will this also search RDM’s? I know the NAA id, and am trying to see if it is presented anywhere in our environment whether as a datastore or an RDM.

    Cheers

    • Hi Martin,

      the scripts in this post will only search for datastores. You can search for RDM’s with a PowerCLI oneliner. For example:

      Get-VM | Get-HardDisk |
      Where-Object {$_.DiskType -like “raw*” -and $_.ScsiCanonicalName -eq “naa.600a0b80001111550000b43a08f4ae4d”} |
      Select-Object -Property Parent,Name,DiskType,ScsiCanonicalName

  7. JMP says:

    this is very handy. is there anyway to get capacity as part of the output?

    • The Get-DatastoreByDiskName function returns standard PowerCLI datastore objects. By default these objects display the Name, FreeSpaceGB and CapacityGB properties. You can pipe the output to the Select-Object cmdlet to select other properties.

  8. Pingback: List all datastores and disk names - Gkhan Tips

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: