VMware Cloud Community
kbay
Contributor
Contributor

Datastore script listing cluster, datastore name, provisioned space, capacity space used and free space

I am trying to write a PowerShell script for datastores - listing by cluster, the datastore name, provisioned space, capacity space used and free space. Exportable to csv file. Adding in used/total IOPS would be a bonus. All our datastores are thin provisioned.

I was hoping to have this automate daily to list a trending report/graph to know when a future date we may max out at.

I am trying to create storage metrics at the SAN level which is the same as pulling the datastore information.

Thank you very much for any and all help!

Tags (2)
15 Replies
GuilhermeAlves
Enthusiast
Enthusiast



Hi! That's what i think you want. Maybe exploring the Get-datastore cmdlet you can have all information you're looking for. 😃


#loading powercli environment


if(!(get-pssnapin|where{$_.name -eq"vmware.vimautomation.core"})) {


try{


add-pssnapinVMware.VimAutomation.Core


} catch{


$ErrorMessage=$_.Exception.Message


outputThis"$ErrorMessage"


}


}


#change the parameter Server to your vCenter


$myvc=connect-viserver-Server"yourServer"-wa0


#you can get the datastores by the Hosts in your clusters


$myclusters=Get-Cluster-Server$myvc


$info2export=@()


foreach($clusterin$myclusters){


$datastoresPerCluster=$cluster|Get-VMhost|Get-Datastore


foreach($datastorein$datastoresPerCluster){


$partialInfo=""|selectClusterName,DatastoreName,CapacitySpaceUsed,FreeSpace


$partialInfo.ClusterName =$cluster.Name


$partialInfo.DatastoreName =$datastore.Name


#$partialInfo.ProvisionedSpace = ?


$partialInfo.CapacitySpaceUsed =$datastore.CapacityGB


$partialInfo.FreeSpace =$datastore.FreeSpaceGB


$info2export+=$partialInfo


}


}


#Export to csv in the path you want


$path="c:\temp\datastoreList.csv"


$info2export|Export-Csv-Path$path-NoTypeInformation-UseCulture

0 Kudos
kbay
Contributor
Contributor

Thank you for your help.

I'm fairly new to Powershell and trying to learn.

After changing the parameter to my vcenter server I get the following errors:

At line:43 char:9

+ foreach($clusterin$myclusters){

+         ~

Missing variable name after foreach.

At line:43 char:19

+ foreach($clusterin$myclusters){

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

Unexpected token '$myclusters' in expression or statement.

At line:43 char:30

+ foreach($clusterin$myclusters){

+                              ~

Unexpected token ')' in expression or statement.

At line:49 char:9

+ foreach($datastorein$datastoresPerCluster){

+         ~

Missing variable name after foreach.

At line:49 char:21

+ foreach($datastorein$datastoresPerCluster){

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

Unexpected token '$datastoresPerCluster' in expression or statement.

At line:43 char:31

+ foreach($clusterin$myclusters){

+                               ~

Missing closing '}' in statement block.

At line:49 char:42

+ foreach($datastorein$datastoresPerCluster){

+                                          ~

Unexpected token ')' in expression or statement.

At line:52 char:34

+ $partialInfo=""|selectClusterName,DatastoreName,CapacitySpaceUsed,FreeSpace

+                                  ~

Missing argument in parameter list.

At line:76 char:1

+ }

+ ~

Unexpected token '}' in expression or statement.

    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : MissingVariableNameAfterForeach

0 Kudos
GuilhermeAlves
Enthusiast
Enthusiast

Here it is indented

#loading powercli environment

if(!(get-pssnapin|where{$_.name -eq"vmware.vimautomation.core"})) {

try{

    add-pssnapin VMware.VimAutomation.Core

} catch{

    $ErrorMessage=$_.Exception.Message

    Write-host "$ErrorMessage"

}

}

#change the parameter Server to your vCenter

$myvc= connect-viserver -Server "yourServer" -wa 0

#you can get the datastores by the Hosts in your clusters

$myclusters=Get-Cluster -Server $myvc

$info2export=@()

foreach($cluster in $myclusters){

    $datastoresPerCluster =$cluster|Get-VMhost|Get-Datastore

foreach($datastore in $datastoresPerCluster){

    $partialInfo=""|select ClusterName,DatastoreName,CapacitySpaceUsed,FreeSpace

    $partialInfo.ClusterName =$cluster.Name

    $partialInfo.DatastoreName =$datastore.Name

    #$partialInfo.ProvisionedSpace = ?

    $partialInfo.CapacitySpaceUsed =$datastore.CapacityGB

    $partialInfo.FreeSpace =$datastore.FreeSpaceGB

    $info2export+=$partialInfo

}

}

#Export to csv in the path you want

$path="c:\temp\datastoreList.csv"

$info2export|Export-Csv -Path $path -NoTypeInformation -UseCulture

0 Kudos
GuilhermeAlves
Enthusiast
Enthusiast

did it work for you?

0 Kudos
kbay
Contributor
Contributor

It does work great (thank you very much!). I only show Free Space and Capacity Space. Do you know the command to add the Provisioned Space? I thought it may be "$partialInfo.ProvisionedSpace =$datastore.ProvisionedSpaceGB" but that didn't work.

Also, for the path I had to include the csv file name, ex: C:\temp\report.csv in order for it to run properly.

I plan to run this daily so how can I have the csv file append that day's date to the end of the csv file name (so nothing is overwritten or info lost)?

thank you again for your help!


GuilhermeAlves
Enthusiast
Enthusiast

Try to use this fragment on the script:

$info2export=@()

foreach($cluster in $myclusters){ 
    $datastoresPerCluster = $cluster|Get-VMhost|Get-Datastore

foreach($datastore in $datastoresPerCluster){

       $view = ($datastore | get-view | select -expandproperty summary)
       $partialInfo=""|select ClusterName,DatastoreName,ProvisionedSpace,CapacitySpaceUsed,FreeSpace 
       $partialInfo.ClusterName =$cluster.Name 
       $partialInfo.DatastoreName =$datastore.Name 
       $Uncommitted = [math]::round(($datastore|get-view |select -expandproperty summary).Uncommited/1GB,2)
       $partialInfo.CapacitySpaceUsed = [math]::round($view.Capacity/1GB,2)
       $partialInfo.FreeSpace = [math]::round($view.FreeSpace/1GB,2)
       $partialInfo.ProvisionedSpace = ($view.CapacityGB – $view.FreeSpaceGB + $Uncommitted)

       $info2export+=$partialInfo 

}

kbay
Contributor
Contributor

I get the following error:

Get-View : Cannot validate argument on parameter 'VIObject'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At C:\Users\K~1\AppData\Local\Temp\4\be2f5715-a348-42f2-b6d0-1de396532ac9.ps1:18 char:35
+     $view = ($datastore | get-view <<<<  | select -expandproperty summary)
    + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

Get-View : Cannot validate argument on parameter 'VIObject'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At C:\Users\K~1\AppData\Local\Temp\4\be2f5715-a348-42f2-b6d0-1de396532ac9.ps1:24 char:51
+     $Uncommitted = [math]::round(($datastore|get-view <<<<  |select -expandproperty summary).Uncommited/1GB,2)
    + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

thanks again for your insight and help!

0 Kudos
GuilhermeAlves
Enthusiast
Enthusiast

Did you ran all the code?

Run everything:

#loading powercli environment 

if(!(get-pssnapin|where{$_.name -eq"vmware.vimautomation.core"})) { 

try{ 

    add-pssnapin VMware.VimAutomation.Core 

} catch{ 

    $ErrorMessage=$_.Exception.Message 

    Write-host "$ErrorMessage" 

#change the parameter Server to your vCenter 

$myvc= connect-viserver -Server "yourServer" -wa 0 

#you can get the datastores by the Hosts in your clusters 

$myclusters=Get-Cluster -Server $myvc 

$info2export=@() 

foreach($cluster in $myclusters){   

    $datastoresPerCluster = $cluster|Get-VMhost|Get-Datastore 

foreach($datastore in $datastoresPerCluster){ 

       $view = ($datastore | get-view | select -expandproperty summary) 

       $partialInfo=""|select ClusterName,DatastoreName,ProvisionedSpace,CapacitySpaceUsed,FreeSpace   

       $partialInfo.ClusterName =$cluster.Name   

       $partialInfo.DatastoreName =$datastore.Name   

       $Uncommitted = [math]::round(($datastore|get-view |select -expandproperty summary).Uncommited/1GB,2) 

       $partialInfo.CapacitySpaceUsed = [math]::round($view.Capacity/1GB,2) 

       $partialInfo.FreeSpace = [math]::round($view.FreeSpace/1GB,2) 

       $partialInfo.ProvisionedSpace = ($view.CapacityGB – $view.FreeSpaceGB + $Uncommitted) 

       $info2export+=$partialInfo   

}   

#Export to csv in the path you want 

$path="c:\temp\datastoreList.csv" 

$info2export|Export-Csv -Path $path -NoTypeInformation -UseCulture


kbay
Contributor
Contributor

Yes. I still get the above errors.

0 Kudos
GuilhermeAlves
Enthusiast
Enthusiast


You'll have this answer while the pipelined parameter for the Get-view cmdlet were null

You can try this:

$null | get-view

This may show you the same error

In the script, the error will appear while the $datastoresPerCluster variable remains null.

You have to make sure that the following variables are properly filled:

=>$myvc

     This will show your vcenter connection, if successfull:

PS C:\users\user\Documents> $myvc

Name                           Port  User                         
----                           ----  ----                         
myserver                     443   DOMAIN\user

=>$myclusters

     This will show you a table with your clusters info:

PS C:\users\user\Documents> $myclusters

Name                           HAEnabled  HAFailover DrsEnabled DrsAutomationLe
                                          Level                 vel           
----                           ---------  ---------- ---------- ---------------
mycluster                          True       1          True       FullyAutomated
mycluster-1                        True       2          True       FullyAutomated
mycluster-4                       True       1          True       FullyAutomated
mycluster-3                       True       1          True       FullyAutomated
mycluster-2                        True       1          True       FullyAutomated

After that, you can run this part of the script:

foreach($cluster in $myclusters){ 

     $cluster|Get-VMhost|Get-Datastore

}

Then you'll see if the $datastorePerCluster variable is null or not.

0 Kudos
animips
Contributor
Contributor

Your script has this line:

$partialInfo.ProvisionedSpace = ($view.CapacityGB – $view.FreeSpaceGB + $Uncommitted)

But $View only contains Capacity and FreeSpace properties. The script will return 0 on all ProvisionedSpace headers if you do not remove the GB from the properties. I have changed the section to this:

$info2export=@()

foreach($cluster in $myclusters){  

      $datastoresPerCluster = $cluster|Get-VMhost|Get-Datastore

foreach($datastore in $datastoresPerCluster){

       $view = ($datastore | get-view | select -expandproperty summary)

       $partialInfo=""|select ClusterName,DatastoreName,ProvisionedSpace,CapacitySpaceUsed,FreeSpace  

       $partialInfo.ClusterName =$cluster.Name  

       $partialInfo.DatastoreName =$datastore.Name  

       $Uncommitted = [math]::round(($datastore|get-view |select -expandproperty summary).Uncommited/1GB,2)

       $partialInfo.CapacitySpaceUsed = [math]::round($view.Capacity/1GB,2)

       $partialInfo.FreeSpace = [math]::round($view.FreeSpace/1GB,2)

       $partialInfo.ProvisionedSpace = ([math]::round($view.Capacity/1GB,2) – ([math]::round($view.FreeSpace/1GB,2) + $Uncommitted))

       $info2export+=$partialInfo  

}  

}

OUTPUT:

ClusterName            : Name

DatastoreName         : Name

ProvisionedSpace     : 4836.15

CapacitySpaceUsed : 5119.75

FreeSpace                : 283.6

By the way, thank you. You saved me a lot of time!

animips
Contributor
Contributor

Just noticed another typo:

    $Uncommitted = [math]::round(($datastore|get-view |select -expandproperty summary).Uncommited/1GB,2)

       $partialInfo.CapacitySpaceUsed = [math]::round($view.Capacity/1GB,2)

       $partialInfo.FreeSpace = [math]::round($view.FreeSpace/1GB,2)

       $partialInfo.ProvisionedSpace = ([math]::round($view.Capacity/1GB,2) – ([math]::round($view.FreeSpace/1GB,2) + $Uncommitted))

GuilhermeAlves
Enthusiast
Enthusiast

Sorry about that GB...

But great! glad to know you made it work. Smiley Happy

ambil85
Contributor
Contributor

Hi Alves ,

Can i get this report in email body

0 Kudos
ejfiel
Contributor
Contributor

Hi,

I already have the script but it seems it is different from what I can see on the GUI. I want to get the provisioned space exactly as what is in the GUI. Below is the output of the script and screenshot from the GUI.

Script Output

ClusterNameDatastoreNameProvisionedSpaceCapacitySpaceUsedFreeSpace
XXXXwphesx02_v21179.315001262.57
XXXXwphesx01_v6560.5515001278.34
XXXXlocal0070131.75130.14
XXXXvmware_dmx3_003117.15269.5226.02
XXXXwphesx01_v2394.41500643.88
XXXXwphesx01_v3681.1215001081.81
XXXXwphesx01swap_v10270269.57
XXXXwphesx02_v11008.7215001282.15
XXXXwphesx02_v3768.9815001196.12
XXXXwphesx02_v4361.131500792.49
XXXXwphesx01_v5690.1715001122.06
XXXXwphesx01_v1853.415001125.83
XXXXwphesx01_v4790.541500

1138.25

0 Kudos