VMware Cloud Community
AlecMcMillan
Contributor
Contributor
Jump to solution

Script to export virtual disk information in a specific format

Hello all,

First too all of the scripters who I have borrowed code from on here, thank you! Smiley Happy

Now, I've been able to get all of the information I want out of vCenter but I am having issues with two of the scripts I wrote.  This one is in regards to getting information on the virtual disks associated with all of the vms in the environment.

I have been able to export the data, but I get One line per VM which does not work for how we want to use the data.

What I am looking to get is a csv export with one line per VM that looks like:

vm number 1 name, harddisk number 1 name, hd number 1 datastore, hd number 1 vmdk path, hd number 1 capactity, hd number 1 controller, harddisk number 2 name, .... up to 7

vm number 2 name, ....

Thanks!

Alec

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Ok, I see what happened.

The 2nd block is to create the empty properties in the object.

There the Value should be $null, like this

$report = @()
foreach($vm in Get-VM){
 
$row = New-Object PSObject -Property @{Name = $vm.Name}
 
$i = 1
 
Get-HardDisk -VM $vm | %{
   
$row | Add-Member -Name "Disk #$($i) Name" -Value $_.Name -MemberType NoteProperty
   
$row | Add-Member -Name "Disk #$($i)" -Value $_.FileName.Split("/")[1] -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)path" -Value $_.FileName -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Capacity(MB)" -Value ($_.CapacityGB*1024) -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Controller" -Value ($_ | Get-ScsiController).Name -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Datastore" -Value $_.FileName.Split(']')[0].TrimStart('[') -MemberType NoteProperty
   
$i++
  }
 
while($i -le 8){
   
$row | Add-Member -Name "Disk #$($i) Name" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk #$($i)" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)path" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Capacity(MB)" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Controller" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Datastore" -Value $null -MemberType NoteProperty
   
$i++
  }
 
$report += $row
}

$report  | Export-Csv -path virtual_disks2.csv -notype


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

View solution in original post

0 Kudos
10 Replies
RvdNieuwendijk
Leadership
Leadership
Jump to solution

Hi Alec,

I hope that the following PowerCLI script is what you want:

Get-VM |

ForEach-Object {

  $Report = "" | Select-Object -Property VM,

    'Hard Disk 1 Name','Hard Disk 1 Datastore','Hard Disk 1 VMDK Path','Hard Disk 1 Capacity GB','Hard Disk 1 Controller',

    'Hard Disk 2 Name','Hard Disk 2 Datastore','Hard Disk 2 VMDK Path','Hard Disk 2 Capacity GB','Hard Disk 2 Controller',

    'Hard Disk 3 Name','Hard Disk 3 Datastore','Hard Disk 3 VMDK Path','Hard Disk 3 Capacity GB','Hard Disk 3 Controller',

    'Hard Disk 4 Name','Hard Disk 4 Datastore','Hard Disk 4 VMDK Path','Hard Disk 4 Capacity GB','Hard Disk 4 Controller',

    'Hard Disk 5 Name','Hard Disk 5 Datastore','Hard Disk 5 VMDK Path','Hard Disk 5 Capacity GB','Hard Disk 5 Controller',

    'Hard Disk 6 Name','Hard Disk 6 Datastore','Hard Disk 6 VMDK Path','Hard Disk 6 Capacity GB','Hard Disk 6 Controller',

    'Hard Disk 7 Name','Hard Disk 7 Datastore','Hard Disk 7 VMDK Path','Hard Disk 7 Capacity GB','Hard Disk 7 Controller'

  $Report.VM = $_.Name

  $_ | Get-HardDisk |

  ForEach-Object {

    $Name = $_.Name

    $Report."$Name Name" = $_.Name

    $Report."$Name Datastore" = $_.FileName.Split(']')[0].TrimStart('[')

    $Report."$Name VMDK Path" = $_.FileName

    $Report."$Name Capacity GB" = $_.CapacityGB

    $Report."$Name Controller" = ($_ | Get-ScsiController).Name

  }

  $Report

}

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
LucD
Leadership
Leadership
Jump to solution

Try something like this

$report = @()
foreach($vm in Get-VM){
 
$row = New-Object PSObject -Property @{VMName = $vm.Name}
 
$i = 1
 
Get-HardDisk -VM $vm | %{
   
$row | Add-Member -Name "HD$($i)Name" -Value $_.Name -MemberType NoteProperty
   
$i++
  }
 
while($i -le 7){
   
$row | Add-Member -Name "HD$($i)Name" -Value $null -MemberType NoteProperty
   
$i++
  }
 
$report += $row
}

I only did it for the HD name property, but the other properties can be done in a similar way.


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

AlecMcMillan
Contributor
Contributor
Jump to solution

Thanks Rvd

This script seemed to work for generating the report.  When I tried to put an export-csv command in... it would only export the last VM it came across?

0 Kudos
AlecMcMillan
Contributor
Contributor
Jump to solution

LucD,

thanks as well... this one does export as I expected to csv file.  Between this and the other response, I'm going through and adding each required element in to the script.

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

To export to a .csv file with my script you can change the last line into:

} | Export-Csv -Path VMdatastoreInfo.csv -NoTypeInformation -UseCulture

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
AlecMcMillan
Contributor
Contributor
Jump to solution

I will start by saying you guys rock Smiley Happy

That being said is there away to suppress the errors I get during script running for FileName.Split and the | to get-scsicontroller?  When the script loops through a vm that does not have disks in any of the 2-7 slots, it shows an error to screen?

You cannot call a method on a null-valued expression.

+     $row | Add-Member -Name "HD$($i)Datastore" -Value $_.FileName.Split(']')[0]. ...

+                                  ~~

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

    + FullyQualifiedErrorId : InvokeMethodOnNull

Get-ScsiController : Cannot validate argument on parameter 'HardDisk'. The argument is null or empty. Supply an

argument that is not null or empty and then try the command again.

+     $row | Add-Member -Name "HD$($i)controller" -Value ($_ | Get-ScsiController) ...

+                                                              ~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-ScsiController], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.VirtualDev

   ice.GetScsiController

Thanks!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It looks as if you are not using PowerShell v3.

In that version the problem with a foreach loop over an empty array has been fixed.

When there are no entries in the array, the code block will not be executed.

In PowerShell v2 you will have to check yourself in the script if Get-HardDisk returns anything.

I don't see how my solution will execute the first codeblock for a non-existing 2nd harddisk.

Perhaps you can attach the code you are using ?


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

0 Kudos
AlecMcMillan
Contributor
Contributor
Jump to solution

been updating it to match the columns we need...

PSversion:

PS G:\> $psversiontable.psversion

Major  Minor  Build  Revision

-----  -----  -----  --------

3      0      -1     -1

Thanks!

$report = @()

foreach($vm in Get-VM){

  $row = New-Object PSObject -Property @{Name = $vm.Name}

  $i = 1

  Get-HardDisk -VM $vm | %{

    $row | Add-Member -Name "Disk #$($i) Name" -Value $_.Name -MemberType NoteProperty

    $row | Add-Member -Name "Disk #$($i)" -Value $_.FileName.Split("/")[1] -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)path" -Value $_.FileName -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)Capacity(MB)" -Value ($_.CapacityGB*1024) -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)Controller" -Value ($_ | Get-ScsiController).Name -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)Datastore" -Value $_.FileName.Split(']')[0].TrimStart('[') -MemberType NoteProperty

    $i++

  }

  while($i -le 8){

    $row | Add-Member -Name "Disk #$($i) Name" -Value $_.Name -MemberType NoteProperty

    $row | Add-Member -Name "Disk #$($i)" -Value $_.FileName.Split("/")[1] -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)path" -Value $_.FileName -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)Capacity(MB)" -Value ($_.CapacityGB*1024) -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)Controller" -Value ($_ | Get-ScsiController).Name -MemberType NoteProperty

    $row | Add-Member -Name "Disk$($i)Datastore" -Value $_.FileName.Split(']')[0].TrimStart('[') -MemberType NoteProperty

    $i++

  }

  $report += $row

}

$report  | Export-Csv -path virtual_disks2.csv -notype

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, I see what happened.

The 2nd block is to create the empty properties in the object.

There the Value should be $null, like this

$report = @()
foreach($vm in Get-VM){
 
$row = New-Object PSObject -Property @{Name = $vm.Name}
 
$i = 1
 
Get-HardDisk -VM $vm | %{
   
$row | Add-Member -Name "Disk #$($i) Name" -Value $_.Name -MemberType NoteProperty
   
$row | Add-Member -Name "Disk #$($i)" -Value $_.FileName.Split("/")[1] -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)path" -Value $_.FileName -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Capacity(MB)" -Value ($_.CapacityGB*1024) -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Controller" -Value ($_ | Get-ScsiController).Name -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Datastore" -Value $_.FileName.Split(']')[0].TrimStart('[') -MemberType NoteProperty
   
$i++
  }
 
while($i -le 8){
   
$row | Add-Member -Name "Disk #$($i) Name" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk #$($i)" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)path" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Capacity(MB)" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Controller" -Value $null -MemberType NoteProperty
   
$row | Add-Member -Name "Disk$($i)Datastore" -Value $null -MemberType NoteProperty
   
$i++
  }
 
$report += $row
}

$report  | Export-Csv -path virtual_disks2.csv -notype


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

0 Kudos
AlecMcMillan
Contributor
Contributor
Jump to solution

Yes, I screwed that up, thanks!  Didnt notice the difference in lines and copied over top of it.

0 Kudos