VMware Cloud Community
David2021
Contributor
Contributor
Jump to solution

Report of Virual Machines folders

Hello,

 

I would like generate a CSV file report concerning VMs in each virtual machine folder. I have create this script but I need some help to improve it.

 

1 - I need folder path but avoid duplicate folder name
2 - I would to know if Provisioned(GB) is the right caracteritic to define all storage of a VM setting
2 - I would like possibility to choose level inventory options when I launch the script:
- vCenter
- Datacenter
- Cluster
- VM folder

 

Write-Host "Connecting to vCenter $($VIServer)" -ForegroundColor Yellow
Connect-VIServer -Server $VIServer


Get-VM | select Name,

@{N="Folder";E={$_.Folder.Name}},

@{N='VM';E={$_.VM.Name}},

@{N="VM PowerState";E={@($_.PowerState)}},

@{N='OS';E={@($_.guest.OSFullName)}},

@{N='CPU';E = {@($_.NumCPU)}},

@{N='Memory(GB)'; E = {@($_.MemoryGB)}},

@{N ='Provisioned(GB)'; E = {[math]::Round($_.provisionedspacegb)}}

@{N='Cluster';E={$_.VM.VMHost.Parent.Name}},

@{N='Datacenter';E={

$p = Get-View -Id $_.VM.VMHost.Parent.ExtensionData.Parent -Property Name,Parent

while($p -and $p -isnot [VMware.Vim.Datacenter])
{
$p = Get-View -Id $p.Parent -Property Name,Parent
}

if($p)
{
$p.Name
cls
}

}
},

|

Export-csv -Path "xxx:\Inventory_report_$($VIServer)_($(Get-Date -Format 'ddMMMyyyy HH_mm')).csv" -NoTypeInformation -UseCulture

# Deconnexion du vCenter
Disconnect-VIServer $VIServer -Confirm:$false


regards,

David

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

1. Calculated property FolderPath added
2. Not sure what you are asking here.
3. Implemented as a function with parametersets

The code

function Get-VMInfo {
  [CmdletBinding(DefaultParameterSetName = 'vCenter')]
  Param(
    [Parameter(ParameterSetName = 'vCenter')]
    [String]$vCenter = $global:defaultVIServer.Name,
    [Parameter(ParameterSetName = 'Datacenter')]
    [String]$Datacenter,
    [Parameter(ParameterSetName = 'Cluster')]
    [String]$Cluster,
    [Parameter(ParameterSetName = 'Folder')]
    [String]$Folder
  )

  switch ($PSCmdlet.ParameterSetName) {
    'vCenter' {
      $location = Get-Folder -Name 'Datacenters' -Server $vCenter
    }
    'Datacenter' {
      $location = Get-Datacenter -Name $Datacenter
    }
    'Cluster' {
      $location = Get-Cluster -Name $Cluster
    }
    'Folder' {
      $location = Get-Folder -Name $Folder
    }
  }

  Get-VM -Location $location |
  ForEach-Object -Process {
    $_ | Select-Object Name,
    @{N = "Folder"; E = { $_.Folder.Name } },
    @{N = 'FolderPath'; E={
      $path = $_.Folder.Name
      $p = $_.Folder.ExtensionData.Parent
      while ($p){
        $p = Get-View -Id $p -Property Name,Parent
        $path = $p.Name, $path -join '/'
        $p = $p.Parent
      }
      $path
    }},
    @{N = 'VM'; E = { $_.Name } },
    @{N = "VM PowerState"; E = { $_.PowerState } },
    @{N = 'OS'; E = { $_.guest.OSFullName } },
    @{N = 'CPU'; E = { $_.NumCPU } },
    @{N = 'Memory(GB)'; E = { $_.MemoryGB } },
    @{N = 'Provisioned(GB)'; E = { [math]::Round($_.provisionedspacegb) } },
    @{N = 'Cluster'; E = { $_.VMHost.Parent.Name } },
    @{N = 'Datacenter'; E = { & {
          $p = Get-View -Id $_.ExtensionData.Parent -Property Name, Parent
          while ($p -and $p -isnot [VMware.Vim.Datacenter]) {
            $p = Get-View -Id $p.Parent -Property Name, Parent
          }
          if ($p) {
            $p.Name
          } } }
    }
  }
}


Write-Host "Connecting to vCenter $($VIServer)" -ForegroundColor Yellow | Out-Default
Connect-VIServer -Server $VIServer

Get-VMInfo |
#Get-VMInfo -Datacenter datacenter |
#Get-VMInfo -Cluster cluster
#Get-VMInfo -Folder folder |
Export-Csv -Path "xxx:\Inventory_report_$($VIServer)_($(Get-Date -Format 'ddMMMyyyy HH_mm')).csv" -NoTypeInformation -UseCulture

Disconnect-VIServer $VIServer -Confirm:$false

 


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

View solution in original post

0 Kudos
16 Replies
LucD
Leadership
Leadership
Jump to solution

1. Calculated property FolderPath added
2. Not sure what you are asking here.
3. Implemented as a function with parametersets

The code

function Get-VMInfo {
  [CmdletBinding(DefaultParameterSetName = 'vCenter')]
  Param(
    [Parameter(ParameterSetName = 'vCenter')]
    [String]$vCenter = $global:defaultVIServer.Name,
    [Parameter(ParameterSetName = 'Datacenter')]
    [String]$Datacenter,
    [Parameter(ParameterSetName = 'Cluster')]
    [String]$Cluster,
    [Parameter(ParameterSetName = 'Folder')]
    [String]$Folder
  )

  switch ($PSCmdlet.ParameterSetName) {
    'vCenter' {
      $location = Get-Folder -Name 'Datacenters' -Server $vCenter
    }
    'Datacenter' {
      $location = Get-Datacenter -Name $Datacenter
    }
    'Cluster' {
      $location = Get-Cluster -Name $Cluster
    }
    'Folder' {
      $location = Get-Folder -Name $Folder
    }
  }

  Get-VM -Location $location |
  ForEach-Object -Process {
    $_ | Select-Object Name,
    @{N = "Folder"; E = { $_.Folder.Name } },
    @{N = 'FolderPath'; E={
      $path = $_.Folder.Name
      $p = $_.Folder.ExtensionData.Parent
      while ($p){
        $p = Get-View -Id $p -Property Name,Parent
        $path = $p.Name, $path -join '/'
        $p = $p.Parent
      }
      $path
    }},
    @{N = 'VM'; E = { $_.Name } },
    @{N = "VM PowerState"; E = { $_.PowerState } },
    @{N = 'OS'; E = { $_.guest.OSFullName } },
    @{N = 'CPU'; E = { $_.NumCPU } },
    @{N = 'Memory(GB)'; E = { $_.MemoryGB } },
    @{N = 'Provisioned(GB)'; E = { [math]::Round($_.provisionedspacegb) } },
    @{N = 'Cluster'; E = { $_.VMHost.Parent.Name } },
    @{N = 'Datacenter'; E = { & {
          $p = Get-View -Id $_.ExtensionData.Parent -Property Name, Parent
          while ($p -and $p -isnot [VMware.Vim.Datacenter]) {
            $p = Get-View -Id $p.Parent -Property Name, Parent
          }
          if ($p) {
            $p.Name
          } } }
    }
  }
}


Write-Host "Connecting to vCenter $($VIServer)" -ForegroundColor Yellow | Out-Default
Connect-VIServer -Server $VIServer

Get-VMInfo |
#Get-VMInfo -Datacenter datacenter |
#Get-VMInfo -Cluster cluster
#Get-VMInfo -Folder folder |
Export-Csv -Path "xxx:\Inventory_report_$($VIServer)_($(Get-Date -Format 'ddMMMyyyy HH_mm')).csv" -NoTypeInformation -UseCulture

Disconnect-VIServer $VIServer -Confirm:$false

 


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

2. Not sure what you are asking here. = the total size of each virtual machine disks

 

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You said, "... is the right caracteritic to define all storage of a VM".

Does that mean you think the values in that property are not correct?


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

I prefer to get total size of disks set for each VMs than provisioned storage because active snapshots are included.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is a discussion I already mentioned in my yadr – A vdisk reporter post.

Feel free to incorporate that code.


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

I try to use this

@{n="HardDiskSizeGB"; e={(Get-HardDisk -VM $_ | Measure-Object -Sum CapacityGB).Sum}}

but the result is empty

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Not sure how you inserted that line, but it works for me


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

I saw a missing "," that I corrected. I retry but the HardDiskSize(GB) is empty again.

 

code

 

function Get-VMInfo {
[CmdletBinding(DefaultParameterSetName = 'vCenter')]
Param(
[Parameter(ParameterSetName = 'vCenter')]
[String]$vCenter = $global:defaultVIServer.Name,
[Parameter(ParameterSetName = 'Datacenter')]
[String]$Datacenter,
[Parameter(ParameterSetName = 'Cluster')]
[String]$Cluster,
[Parameter(ParameterSetName = 'Folder')]
[String]$Folder
)

switch ($PSCmdlet.ParameterSetName) {
'vCenter' {
$location = Get-Folder -Name 'Datacenters' -Server $vCenter
}
'Datacenter' {
$location = Get-Datacenter -Name $Datacenter
}
'Cluster' {
$location = Get-Cluster -Name $Cluster
}
'Folder' {
$location = Get-Folder -Name $Folder
}
}

Get-VM -Location $location |
ForEach-Object -Process {
$_ | Select-Object Name,
@{N = "Folder"; E = { $_.Folder.Name } },
@{N = 'FolderPath'; E={
$path = $_.Folder.Name
$p = $_.Folder.ExtensionData.Parent
while ($p){
$p = Get-View -Id $p -Property Name,Parent
$path = $p.Name, $path -join '/'
$p = $p.Parent
}
$path
}},
@{N = 'VM'; E = { $_.Name } },
@{N = "VM PowerState"; E = { $_.PowerState } },
@{N = 'OS'; E = { $_.guest.OSFullName } },
@{N = 'CPU'; E = { $_.NumCPU } },
@{N = 'Memory(GB)'; E = { $_.MemoryGB } },
@{N = 'HardDiskSizeGB'; E = { (Get-HardDisk -VM $_ | Measure-Object -Sum CapacityGB).Sum } },
@{N = 'Provisioned(GB)'; E = { [math]::Round($_.provisionedspacegb) } },
@{N = 'Cluster'; E = { $_.VMHost.Parent.Name } },
@{N = 'Datacenter'; E = { & {
$p = Get-View -Id $_.ExtensionData.Parent -Property Name, Parent
while ($p -and $p -isnot [VMware.Vim.Datacenter]) {
$p = Get-View -Id $p.Parent -Property Name, Parent
}
if ($p) {
$p.Name
} } }
}
}
}

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Works for me


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

I found a point. When I select the parent folder the script can calculate this line

@{N = 'HardDiskSizeGB'; E = { (Get-HardDisk -VM $_ | Measure-Object -Sum CapacityGB).Sum } },

But if I selected a subfolder the script cannot calculate the line

@{N = 'HardDiskSizeGB'; E = { (Get-HardDisk -VM $_ | Measure-Object -Sum CapacityGB).Sum } },

and the result column is empty.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Not sure what you are saying.
If the VM is not located in the folder or one of the subfolders, the VM will not be listed.


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

When I search at this level : Datacenter/DatacenterName/vm

The folder "vm" corresponding in fact all VMs present at Datacenter root level in "VMs and Templates" view. These VMs are not inside a specific folder. The HardDiskSizeGB information is present for all VMs present in this directory in output CSV file.

 

But If I require to search at this level : Datacenter/DatacenterName/vm/folder1

The "HardDiskSizeGB" is not present for all VMs present in this directory. I have the same behaviour for all folders present in the Datacenter root level in "VMs and Templates" view.

I don't know why the script cannot calculate only this option "HardDiskSizeGB" when a VM is in folder.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

How do you call the Get-VMInfo function?

PS: your threads always seem to go on forever


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

This is my script:

 

[CmdletBinding(SupportsShouldProcess=$true)]

# Input pour le nom du vCenter
Param(
[string] $VIServer = $(throw "Missing parameter: The -VIServer parameter is required.")
)


# Connexion au vCenter
Write-Host "Connecting to vCenter $($VIServer)" -ForegroundColor Yellow
Connect-VIServer -Server $VIServer


function Get-VMInfo {
[CmdletBinding(DefaultParameterSetName = 'vCenter')]
Param(
[Parameter(ParameterSetName = 'vCenter')]
[String]$vCenter = $global:defaultVIServer.Name,
[Parameter(ParameterSetName = 'Datacenter')]
[String]$Datacenter,
[Parameter(ParameterSetName = 'Cluster')]
[String]$Cluster,
[Parameter(ParameterSetName = 'Folder')]
[String]$Folder
)

switch ($PSCmdlet.ParameterSetName) {
'vCenter' {
$location = Get-Folder -Name 'Datacenters' -Server $vCenter
}
'Datacenter' {
$location = Get-Datacenter -Name $Datacenter
}
'Cluster' {
$location = Get-Cluster -Name $Cluster
}
'Folder' {
$location = Get-Folder -Name $Folder
}
}

Get-VM -Location $location |
ForEach-Object -Process {
$_ | Select-Object Name,
@{N = "Folder"; E = { $_.Folder.Name } },
@{N = 'FolderPath'; E={
$path = $_.Folder.Name
$p = $_.Folder.ExtensionData.Parent
while ($p){
$p = Get-View -Id $p -Property Name,Parent
$path = $p.Name, $path -join '/'
$p = $p.Parent
}
$path
}},
@{N = 'VM'; E = { $_.Name } },
@{N = "VM PowerState"; E = { $_.PowerState } },
@{N = 'OS'; E = { $_.guest.OSFullName } },
@{N = 'CPU'; E = { $_.NumCPU } },
@{N = 'Memory(GB)'; E = { $_.MemoryGB } },
@{N = 'HardDiskSizeGB'; E = { (Get-HardDisk -VM $_ | Measure-Object -Sum CapacityGB).Sum } },
@{N = 'Provisioned(GB)'; E = { [math]::Round($_.provisionedspacegb) } },
@{N = 'Cluster'; E = { $_.VMHost.Parent.Name } },
@{N = 'Datacenter'; E = { & {
$p = Get-View -Id $_.ExtensionData.Parent -Property Name, Parent
while ($p -and $p -isnot [VMware.Vim.Datacenter]) {
$p = Get-View -Id $p.Parent -Property Name, Parent
}
if ($p) {
$p.Name
} } }
}
}
}


#Get-VMInfo |
#Get-VMInfo -Datacenter datacenter |
#Get-VMInfo -Cluster cluster
Get-VMInfo -Folder Folder1 |
Export-Csv -Path "xx:\Inventory_VMs_report_$($VIServer)_($(Get-Date -Format 'ddMMMyyyy HH_mm')).csv" -NoTypeInformation -UseCulture

Disconnect-VIServer $VIServer -Confirm:$false

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Works perfectly for me
folder.png


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

0 Kudos
David2021
Contributor
Contributor
Jump to solution

I discovered why.

In fact, it concern VM replicate. I don't pay attention of the VMs icons with 3 little dark blue squares on the top of the VM icon.

So it's normal that HardDiskSizeGB is not calculate

Sorry, to disturb you on that point. Thank you a lot LucD for your help.

0 Kudos