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!
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
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
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
did it work for you?
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!
Try to use this fragment on the script:
$info2export=@()
foreach($cluster in $myclusters){
$datastoresPerCluster = $cluster|Get-VMhost|Get-Datastoreforeach($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
}
}
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!
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
Yes. I still get the above errors.
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.
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!
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))
Sorry about that GB...
But great! glad to know you made it work.
Hi Alves ,
Can i get this report in email body
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
ClusterName | DatastoreName | ProvisionedSpace | CapacitySpaceUsed | FreeSpace |
XXXX | wphesx02_v2 | 1179.3 | 1500 | 1262.57 |
XXXX | wphesx01_v6 | 560.55 | 1500 | 1278.34 |
XXXX | local007 | 0 | 131.75 | 130.14 |
XXXX | vmware_dmx3_003 | 117.15 | 269.5 | 226.02 |
XXXX | wphesx01_v2 | 394.4 | 1500 | 643.88 |
XXXX | wphesx01_v3 | 681.12 | 1500 | 1081.81 |
XXXX | wphesx01swap_v1 | 0 | 270 | 269.57 |
XXXX | wphesx02_v1 | 1008.72 | 1500 | 1282.15 |
XXXX | wphesx02_v3 | 768.98 | 1500 | 1196.12 |
XXXX | wphesx02_v4 | 361.13 | 1500 | 792.49 |
XXXX | wphesx01_v5 | 690.17 | 1500 | 1122.06 |
XXXX | wphesx01_v1 | 853.4 | 1500 | 1125.83 |
XXXX | wphesx01_v4 | 790.54 | 1500 | 1138.25 |