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
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
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
2. Not sure what you are asking here. = the total size of each virtual machine disks
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
I prefer to get total size of disks set for each VMs than provisioned storage because active snapshots are included.
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
I try to use this
@{n="HardDiskSizeGB"; e={(Get-HardDisk -VM $_ | Measure-Object -Sum CapacityGB).Sum}}
but the result is empty
Not sure how you inserted that line, but it works for me
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
} } }
}
}
}
Works for me
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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.
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
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.
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
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
Works perfectly for me
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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.