Search code examples
powershellstoragepowercli

Powershell: Cannot index into a null array error


I am writing a script to import a LUN list which contain fields "Volume Name", "LUN UID", "Capacity (GiB)", "Storage Pool Name", "Storage System name", "Storage Tier" and "Host Mappings" in variable $luns.

Then I need to match the "LUN UID" in the $luns variable to another variable $dsnaa created to store the datastore naa.

The idea to get a list of all virtual machines residing on the datastores which match the Storage Volume/ LUN ID in the imported excel file.

Error:

Cannot index into a null array.
At C:\Users\troyh\Documents\WindowsPowerShell\ServerList_from_LUN_List.ps1:18 char:40
+ ... re | where {($_.ExtensionData.Info.Vmfs.Extent[0]).DiskName -like $ds ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

Script:

$luns = Import-Excel ~\Documents\WindowsPowerShell\Imports\LUN_Import.xlsx
$arr1 = @()

foreach($lun in $luns)
 {
   $dsnaa = $lun.'LUN UID'
   $dsnaa = "*$dsnaa*"

   $datastore = Get-Datastore | where {($_.ExtensionData.Info.Vmfs.Extent[0]).DiskName -like $dsnaa}
   $vms = Get-Datastore $datastore.Name | Get-VM

   foreach($vm in $vms)
    {

      $data = New-Object System.Object

      $data | Add-Member -MemberType NoteProperty -Name "Name" -Value $vm.Name
      $data | Add-Member -MemberType NoteProperty -Name "Datastore" -Value $datastore.'Name'
      $data | Add-Member -MemberType NoteProperty -Name "naa" -Value $lun.'LUN UID'
      $data | Add-Member -MemberType NoteProperty -Name "Storage Pool Name" -Value $lun.'Storage Pool Name'
      $data | Add-Member -MemberType NoteProperty -Name "Storage System Name" -Value $luns.'Storage System name'

      $arr1 += $data

   }
}

   $arr1 | Export-Excel ~\Documents\WindowsPowerShell\Exports\ServerList_$(Get-Date -Format 'yyyy-MM-dd_H"H"mm').xlsx –Show

Solution

  • This line is the problem:

    $datastore = Get-Datastore | where {($_.ExtensionData.Info.Vmfs.Extent[0]).DiskName -like $dsnaa}
    

    You need to remove the index:

    $datastore = Get-Datastore | where {($_.ExtensionData.Info.Vmfs.Extent).DiskName -like $dsnaa}
    

    The line above will get all datastores that match the criteria that used your -like operator. If you are only interested in getting the first datastore in the list, then index the datastore variable like so in the next line.

    $datastore = Get-Datastore | where {($_.ExtensionData.Info.Vmfs.Extent).DiskName -like $dsnaa}
    $vms = Get-Datastore $datastore[0].Name | Get-VM
    

    The Get-VM cmdlet does take an array of datastores if you want to grab everything at once.

    I have made a few more edits to try to accomplish what you are trying. The problem here besides the indexing is putting the datastore name into the data object. Here is a rewrite using a lot of your code:

    $luns = Import-Excel ~\Documents\WindowsPowerShell\Imports\LUN_Import.xlsx
    $arr1 = @()
    
    foreach($lun in $luns)
     {
       $dsnaa = $lun.'LUN UID'
       $dsnaa = "*$dsnaa*"
    
       $datastore = Get-Datastore | where {($_.ExtensionData.Info.Vmfs.Extent).DiskName -like $dsnaa}
       $VMs = @()
       $datastore | foreach-object {
         $dstore = $_.name
         $VMs += get-VM -datastore $dstore | select @{n="Name";e={$_.name}},@{n="Datastore_Name";e={$dstore}}
       }
    
    
       foreach($vm in $vms)
        {
    
          $data = New-Object System.Object
    
          $data | Add-Member -MemberType NoteProperty -Name "Name" -Value $vm.Name
          $data | Add-Member -MemberType NoteProperty -Name "Datastore" -Value $vm.'Datastore_Name'
          $data | Add-Member -MemberType NoteProperty -Name "naa" -Value $lun.'LUN UID'
          $data | Add-Member -MemberType NoteProperty -Name "Storage Pool Name" -Value $lun.'Storage Pool Name'
          $data | Add-Member -MemberType NoteProperty -Name "Storage System Name" -Value $luns.'Storage System name'
    
          $arr1 += $data
    
       }
    }
    
       $arr1 | Export-Excel ~\Documents\WindowsPowerShell\Exports\ServerList_$(Get-Date -Format 'yyyy-MM-dd_H"H"mm').xlsx –Show