VMware Cloud Community
AhmadAfsar
Contributor
Contributor
Jump to solution

VM & hosting datastore size report

Hello,

I am a newbie to PowerCLI and  strong will to learn. Struggling since a month but no luck.

Would be great if someone can help with a script which fulfills below need.

1. VM Name

2. VM Size

3. Hosting datastore

4. Hosting datastore total space in gb

5. Hosting datastore used space in gb

6. Hosting datastore free space in gb

Thanks everyone.

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

First, did you already do a search in this community?

There are quite a few example scripts in here doing exactly what you are asking for.

Try like this.
Note that

  • The VMHost information is available on the object returned by Get-VM under the VMHost property
  • The same VirtualMachine object also contains information about the datastore(s) on which the VM lives, under DatastoreIdList property.
  • With the Get-View cmdlet you can access the vSphere objects. In this case the Datastore object. Note that PowerCLI cmdlets return what are called .NET Objects. These are not the same as vSphere objects.
  • On a Select-Object you can use what is called a calculated property. These are hash tables with a Name and Expression entry. In the Expression part a script can manipulate data. They are in fact script blocks.
  • In a PowerShell script one can use the .NET methods. That is what [Math]::Round is doing.
  • The -join operator combines elements of an array with the character specified on the right side of the -join operator.

Get-VM |

Select Name,

    @{N='UsedSpaceGB';E={[math]::Round($_.UsedSpaceGB,1)}},

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

    @{N='Datastore';E={

        $script:ds= Get-View -Id $_.DatastoreIdList

        $script:ds.Name -join '|'}},

    @{N='DatastoreCapacityGB';E={($script:ds.Summary | %{[math]::Round($_.Capacity/1GB,0)}) -join '|'}},

    @{N='DatastoreUsedGB';E={($script:ds.Summary | %{[math]::Round(($_.Capacity - $_.FreeSpace)/1GB,0)}) -join '|'}},

    @{N='DatastoreFreeGB';E={($script:ds.Summary | %{[math]::Round($_.FreeSpace/1GB,0)}) -join '|'}}


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

View solution in original post

5 Replies
LucD
Leadership
Leadership
Jump to solution

First, did you already do a search in this community?

There are quite a few example scripts in here doing exactly what you are asking for.

Try like this.
Note that

  • The VMHost information is available on the object returned by Get-VM under the VMHost property
  • The same VirtualMachine object also contains information about the datastore(s) on which the VM lives, under DatastoreIdList property.
  • With the Get-View cmdlet you can access the vSphere objects. In this case the Datastore object. Note that PowerCLI cmdlets return what are called .NET Objects. These are not the same as vSphere objects.
  • On a Select-Object you can use what is called a calculated property. These are hash tables with a Name and Expression entry. In the Expression part a script can manipulate data. They are in fact script blocks.
  • In a PowerShell script one can use the .NET methods. That is what [Math]::Round is doing.
  • The -join operator combines elements of an array with the character specified on the right side of the -join operator.

Get-VM |

Select Name,

    @{N='UsedSpaceGB';E={[math]::Round($_.UsedSpaceGB,1)}},

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

    @{N='Datastore';E={

        $script:ds= Get-View -Id $_.DatastoreIdList

        $script:ds.Name -join '|'}},

    @{N='DatastoreCapacityGB';E={($script:ds.Summary | %{[math]::Round($_.Capacity/1GB,0)}) -join '|'}},

    @{N='DatastoreUsedGB';E={($script:ds.Summary | %{[math]::Round(($_.Capacity - $_.FreeSpace)/1GB,0)}) -join '|'}},

    @{N='DatastoreFreeGB';E={($script:ds.Summary | %{[math]::Round($_.FreeSpace/1GB,0)}) -join '|'}}


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

AhmadAfsar
Contributor
Contributor
Jump to solution

Hello LucD,

A big thank you. This is what my needs was. Yes, I already searched before posting this and came across some scripts but those were not really what I was looking for.

I am very thankful for the explanation that helped me to understand the things and I was able to pull the free datastore space in Percent as well.

Just one thing that I did not get is $script:ds part.

Thank you once again.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

In PowerShell, a variable is always in what is called a scope.

There are 3 of those scopes:

  • local: within one code block (the default)
  • script: for the entire script
  • global: for your PS session

Since the Expressions in a calculated property are code blocks, all variables defined in there are only known within that code block.

Since I wanted to avoid having to fetch the datastores multiple times, I defined that variables in the script scope.

That way the variable is known in the Expression blocks of the other calculated expressions.


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

Reply
0 Kudos
AhmadAfsar
Contributor
Contributor
Jump to solution

Hello LucD,

I would like to thank you again. The script is serving the purpose very well but just need to change the color of the output based on some condition.

Below is the script and output.

My requirement is to change the color of value "DatastoreFreePercent" to red if its less than the double of OR 200% of the value of "UsedSpaceGB".

So if the value of "UsedSpaceGB" is 1024 and the value of "DatastoreFreePercent" is less than double of the "UsedSpaceGB" that the percentage value 2048, change its color to red.

in other words, if my VM size is 1024 GB, free space in datastore must be 2048 gb, else change the color.

Scenario :  if we need to take snapshot of 500 VMs hosted across many datastores, we need to make sure that datastore is having enough free space available to hold the snapshot. Having a look on 500 entries in excel file is a bit time consuming and error prone. but if the color is changed where we have less free space, we can address them quickly.

Get-VM -Name $VMs |

Select Name,

    @{N='UsedSpaceGB';E={[math]::Round($_.UsedSpaceGB,1)}},

    @{N='Datastore';E={

        $script:ds= Get-View -Id $_.DatastoreIdList

        $script:ds.Name -join '|'}},

    @{N='DatastoreCapacityGB';E={($script:ds.Summary | %{[math]::Round($_.Capacity/1GB,0)}) -join '|'}},

    @{N='DatastoreUsedGB';E={($script:ds.Summary | %{[math]::Round(($_.Capacity - $_.FreeSpace)/1GB,0)}) -join '|'}},

    @{N='DatastoreFreeGB';E={($script:ds.Summary | %{[math]::Round($_.FreeSpace/1GB,0)}) -join '|'}},

    @{N="DatastoreFreePercent";E={($script:ds.Summary | %{[math]::Round(($_.Freespace / $_.Capacity * 100),2)}) -join '|'}} | export-csv "$path\DatastoreUsage.csv" -Append -NoTypeInformation

Name UsedSpaceGB Datastore DatastoreCapacityGB DatastoreUsedGB DatastoreFreeGB DatastoreFreePercent

vm1           64.1                 DS1                4096                     2612                          1580                     43.7

vm2           40                    DS2                4096                     3581                          1611                     31.87

vm3          64.1                  DS3                4096                     1612                           1580                     43.7

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

In a CSV file you will not be able to do any conditional formatting.
You could do something like this in an XLSX file or in HTML output.
Would any of those two solutions be ok for you?


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

Reply
0 Kudos