VMware Cloud Community
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Get Guest OS disks letter

I find this script in the community Get List of VMs, Datastores and VMDK / path per Cluster 

I would like to exclude vCLS from output and get also the below information

 Drive Letter, Storage Format, Size, free space
 
I believe that I'm tackling this in wrong way.
Any idea?

 

Reply
0 Kudos
2 Solutions

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You mean like this?

        @{N="VMDK Size";E={[math]::Round(($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB)}},

Like I said earlier, this Get-VMGuestDisk doesn't always work.
There are many prerequisites for this cmdlet and VMware Tools to return values.


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

View solution in original post

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

What exactly does the error say?

That line with Get-View is not needed.
You can get those values also from the original $vm variable.

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
    ForEach ($VM in ($Cluster | Get-VM | Where-Object{$_.Name -notmatch '^vcls'} | Sort-Object -Property Name)) {
        ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
            $guestHD = Get-VMGuestDisk -HardDisk $HardDisk
            "" | Select-Object -Property @{N="VM";E={$VM.Name}},
            @{N="Configured OS";E={$vm.ExtensionData.Config.GuestFullName}},
            @{N="Running OS";E={$vm.ExtensionData.Guest.GuestFullName}},
            @{N="Datacenter";E={$Datacenter.name}},
            @{N="Cluster";E={$Cluster.Name}},
            @{N="Hard Disk";E={$HardDisk.Name}},
            @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
            @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
            @{N="VMDKpath";E={$HardDisk.FileName}},
            @{N="VMDK Size";E={[math]::Round(($vm.extensiondata.layoutex.file|Where-Object{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB)}},
            @{N="Drive Size";E={$HardDisk.CapacityGB.foreach{[math]::Round($_)}}},
            @{N='GuestDiskPath';E={$guestHD.DiskPath -join "`n"}},
            @{N='GuestCapacityGB';E={($guestHD.CapacityGB.foreach{[math]::Round($_)}) -join "`n"}},
            @{N='GuestFreeGB';E={($guestHD.FreeSpaceGB.foreach{[math]::Round($_)}) -join "`n"}},
            @{N='GuestDiskType';E={$guestHD.FileSystemType -join "`n"}}
          }
      }
    }
  }
$VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path ".\VmInfo.csv"


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

View solution in original post

Reply
0 Kudos
20 Replies
LucD
Leadership
Leadership
Jump to solution

That is a rather old thread.
To exclude the vCLS VMs you could add a Where-clause

ForEach ($VM in ($Cluster | Get-VM | where{$_.Name -notmatch '^vcls'} | Sort-Object -Property Name)) {

To link this to Guest OS disk info you can use the Get-VMGuestDisk cmdlet, provided all the prerequisites for that cmdlet are fulfilled.


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thanks LuD, it's OK for excluding the vCLS.

Not sure how to use the cmdlet Get-VMGuestDisk in the script

can you assist ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do something like this, but be aware that there can be more than 1 guest partition on a VMDK.
Hence the -join operator

Also, if the Get-VMGuestDisk does not return anything, those Guest* properties will be empty.

 

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
    ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
      ForEach ($VM in ($Cluster | Get-VM | where{$_.Name -notmatch '^vcls'} | Sort-Object -Property Name)) {
        ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
          $guestHD = Get-VMGuestDisk -HardDisk $HardDisk
          "" | Select-Object -Property @{N="VM";E={$VM.Name}},
          @{N="Datacenter";E={$Datacenter.name}},
          @{N="Cluster";E={$Cluster.Name}},
          @{N="Hard Disk";E={$HardDisk.Name}},
          @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
          @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
          @{N="VMDKpath";E={$HardDisk.FileName}},
          @{N="VMDK Size";E={($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}},
          @{N="Drive Size";E={$HardDisk.CapacityGB}},
          @{N='GuestDiskPath';E={$guestHD.DiskPath}},
          @{N='GuestCapacityGB';E={$guestHD.CapacityGB}},
          @{N='GuestFreeGB';E={$guestHD.FreeSpaceGB}},
          @{N='GuestDiskType';E={$guestHD.FileSystemType}}
        }
      }
    }
  }
  $VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "C:\VmInfo4.csv"

 

 


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thanks again it's working but we are missing the drive letter is that possible?

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, I'm getting the drive letter under the GuestDiskPath property.
Is Get-VMGuestDisk returning the letter for those VMs?
It might be an issue with the cmdlet for a specific Guest OS and/or VMware Tools version.

LucD_0-1699541171503.png


I seem to have forgotten the -join operator I mentioned earlier.

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
    ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
      ForEach ($VM in ($Cluster | Get-VM | where{$_.Name -notmatch '^vcls'} | Sort-Object -Property Name)) {
        ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
          $guestHD = Get-VMGuestDisk -HardDisk $HardDisk
          "" | Select-Object -Property @{N="VM";E={$VM.Name}},
          @{N="Datacenter";E={$Datacenter.name}},
          @{N="Cluster";E={$Cluster.Name}},
          @{N="Hard Disk";E={$HardDisk.Name}},
          @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
          @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
          @{N="VMDKpath";E={$HardDisk.FileName}},
          @{N="VMDK Size";E={($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}},
          @{N="Drive Size";E={$HardDisk.CapacityGB}},
          @{N='GuestDiskPath';E={$guestHD.DiskPath -join '|'}},
          @{N='GuestCapacityGB';E={$guestHD.CapacityGB -join '|'}},
          @{N='GuestFreeGB';E={$guestHD.FreeSpaceGB -join '|'}},
          @{N='GuestDiskType';E={$guestHD.FileSystemType -join '|'}}
        }
      }
    }
  }
  $VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "C:\VmInfo4.csv"

 


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thanks LucD it's working fine.

for VMDK Size & Drive Size they are in GB, right?

I made a change in order to get data without "." unfortunately GuestCapacityGB and GuestFreeGB are Empty

          @{N='GuestCapacityGB';E={([Math]::Round($guestHD.CapacityGB)/1GB,0) -join "`n"}},
          @{N='GuestFreeGB';E={([Math]::Round($guestHD.FreeSpaceGB)/1GB,0) -join "`n"}},
 
Screenshot 2023-11-09 175017.png

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, that is why I added GB to the property name.

Try like this

        @{N='GuestCapacityGB';E={($guestHD.CapacityGB.foreach{[math]::Round($_)}) -join '|'}},
        @{N='GuestFreeGB';E={($guestHD.FreeSpaceGB.foreach{[math]::Round($_)}) -join '|'}},


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

for this line, I tried multiple ways to get things like other lines unfortunately without success

@{N="VMDK Size";E={($vm.extensiondata.layoutex.file|Where-Object{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}}
 
by the way, do you know why for some VMs the below details are missing?
Is it related to Guest OS? vmwareTools?
 
 
GuestDiskPath GuestCapacityGB GuestFreeGB GuestDiskType
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You mean like this?

        @{N="VMDK Size";E={[math]::Round(($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB)}},

Like I said earlier, this Get-VMGuestDisk doesn't always work.
There are many prerequisites for this cmdlet and VMware Tools to return values.


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thanks LucD as always, you help me a lot.

the script is working fine and I tried to add some details related to VM and I made it like this, unfortunately, I get an error message related to this line **$guestHD = Get-VMGuestDisk -HardDisk $HardDisk**

what's wrong in the modified script?

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
    ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
      ForEach ($VM in ($Cluster | Get-VM | Where-Object{$_.Name -notmatch '^vcls'} | Sort-Object -Property Name)) {
          ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
            foreach ($VM in (Get-View -ViewType VirtualMachine -Property Guest.GuestFullName, Config.GuestFullName)){
              $guestHD = Get-VMGuestDisk -HardDisk $HardDisk
              "" | Select-Object -Property @{N="VM";E={$VM.Name}},
              @{N="Configured OS";E={$Config.GuestFullName}},
              @{N="Running OS";E={$Guest.GuestFullName}},
              @{N="Datacenter";E={$Datacenter.name}},
              @{N="Cluster";E={$Cluster.Name}},
              @{N="Hard Disk";E={$HardDisk.Name}},
              @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
              @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
              @{N="VMDKpath";E={$HardDisk.FileName}},
              @{N="VMDK Size";E={[math]::Round(($vm.extensiondata.layoutex.file|Where-Object{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB)}},
              @{N="Drive Size";E={$HardDisk.CapacityGB.foreach{[math]::Round($_)}}},
              @{N='GuestDiskPath';E={$guestHD.DiskPath -join "`n"}},
              @{N='GuestCapacityGB';E={($guestHD.CapacityGB.foreach{[math]::Round($_)}) -join "`n"}},
              @{N='GuestFreeGB';E={($guestHD.FreeSpaceGB.foreach{[math]::Round($_)}) -join "`n"}},
              @{N='GuestDiskType';E={$guestHD.FileSystemType -join "`n"}}
            }
        }
      }
    }
  }
  $VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path ".\VmInfo.csv"
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

What exactly does the error say?

That line with Get-View is not needed.
You can get those values also from the original $vm variable.

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
    ForEach ($VM in ($Cluster | Get-VM | Where-Object{$_.Name -notmatch '^vcls'} | Sort-Object -Property Name)) {
        ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
            $guestHD = Get-VMGuestDisk -HardDisk $HardDisk
            "" | Select-Object -Property @{N="VM";E={$VM.Name}},
            @{N="Configured OS";E={$vm.ExtensionData.Config.GuestFullName}},
            @{N="Running OS";E={$vm.ExtensionData.Guest.GuestFullName}},
            @{N="Datacenter";E={$Datacenter.name}},
            @{N="Cluster";E={$Cluster.Name}},
            @{N="Hard Disk";E={$HardDisk.Name}},
            @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
            @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
            @{N="VMDKpath";E={$HardDisk.FileName}},
            @{N="VMDK Size";E={[math]::Round(($vm.extensiondata.layoutex.file|Where-Object{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB)}},
            @{N="Drive Size";E={$HardDisk.CapacityGB.foreach{[math]::Round($_)}}},
            @{N='GuestDiskPath';E={$guestHD.DiskPath -join "`n"}},
            @{N='GuestCapacityGB';E={($guestHD.CapacityGB.foreach{[math]::Round($_)}) -join "`n"}},
            @{N='GuestFreeGB';E={($guestHD.FreeSpaceGB.foreach{[math]::Round($_)}) -join "`n"}},
            @{N='GuestDiskType';E={$guestHD.FileSystemType -join "`n"}}
          }
      }
    }
  }
$VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path ".\VmInfo.csv"


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

sorry I didn't add the error message: "11/10/2023 12:00:00 PM Get-VMGuestDisk An error occurred while sending the request."

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I haven't seen that one yet.
Sounds like an issue in the communication to the VMware Tools in the Guest OS.
Are the VMware Tools running?
Can you try a restart of the VMware Tools?


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

the issue is related to my modified script, once I used the one you shared it's fine and OK 🙂 

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Just a question, when I try to collect scsi id information I used the tow different syntax bu the output is always empty, what's is my error? 

 

@{N="Scsi";E={$vm.ExtensionData.UnitNumber}},
@{N="Scsi";E={$_.ExtensionData.UnitNumber}},
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try with

@{N="Scsi";E={$HardDisk.ExtensionData.UnitNumber}},


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thanks, I got it, the error was $vm 🙂

UnitNumber provides only the ID, not bus also, right?

would you please help me with the documentation

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

"documentation" ?
Do you mean the API Reference, for all properties under ExtensionData?


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Yes, the API Reference, for all properties under ExtensionData

I would like also learn more in order to be able to understand things and add details to the script 🙂 

Reply
0 Kudos