Last Sunday there appeared an interesting thread in the VMTN PowerCLI Community where one the questions was how to find all ‘Thin‘ virtual disks without passing via a virtual machine. The reason for this question was that most of the user’s virtual machines in Lab Manager are not registered on the vCenter Server.
My first idea was to use ‘Get-Datastore | Get-Harddisk‘ and then use the Extensiondata property to query the thinProvisioned property. Something like Arne did in his PowerCLI: Virtual Machine Disk (VMDK) info post. But that, unfortunately, doesn’t work since the Extensiondata property is $null in this case.
The alternative I came up with in the end, is to use the SearchDatastoreSubFolders_Task method that is available on the HostDatastoreBrowser object.
With this method you use a HostDatastoreBrowserSearchSpec object to specify which types of files must be searched for.
And since API 4.0, the VmDiskFileQueryFilter allows you to specify if you only want ‘Thin’ virtual disks to be returned.
Note that the following script requires PowerCLI 4.1 !
Update October 4th 2010: added a test to check if the script is running in at least PowerCLI 4.1
The script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
function Find-ThinDisk { <# .SYNOPSIS Returns all virtual disks that are Thin .DESCRIPTION The function returns all the Thin disks it finds on the datastore(s) passed to the function .NOTES Authors: Luc Dekens .PARAMETER Datastore On or more datastore objects returned by Get-Datastore .PARAMETER Thin If this switch is $true, only Thin virtual disks are returned. If the switch is set to $false, all non-Thin virtual disks are returned. .EXAMPLE PS> Get-Datastore | Find-ThinDisk .EXAMPLE PS> Find-ThinDisk -Datastore (Get-Datastore -Name "DS*") #> param( [parameter(valuefrompipeline = $true, mandatory = $true, HelpMessage = "Enter a datastore")] [VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl[]]$Datastore, [switch]$Thin = $true ) begin{ if((Get-PowerCLIVersion).Build -lt 264274){ Write-Error "The script requires at least PowerCLI 4.1 !" exit } $searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec $query = New-Object VMware.Vim.VmDiskFileQuery $query.Details = New-Object VMware.Vim.VmDiskFileQueryFlags $query.Details.capacityKb = $true $query.Details.controllerType = $true $query.Details.diskExtents = $true $query.Details.diskType = $true $query.Details.hardwareVersion = $true $query.Details.thin = $true $query.Filter = New-Object VMware.Vim.VmDiskFileQueryFilter $query.Filter.Thin = $Thin $searchspec.Query += $query } process{ $Datastore | %{ $dsBrowser = Get-View $_.Extensiondata.Browser $datastorepath = "[" + $_.Name + "]" $taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec) $task = Get-View $taskMoRef while ("running","queued" -contains $task.Info.State){ $task.UpdateViewData("Info.State") } $task.UpdateViewData("Info.Result") if($task.Info.Result){ foreach ($folder in $task.Info.Result){ if($folder.File){ foreach($file in $folder.File){ $record = "" | Select DSName,Path,VmdkName $record.DSName = $_.Name $record.Path = $folder.FolderPath $record.VmdkName = $file.Path $record } } } } } } } |
Annotations
Line 29-32: The script requires at least PowerCLI 4.1. To avoid errors when running with an older PowerCLI versions, I added this test.
Line 34-45: The HostDatastoreBrowserSearchSpec object is constructed in the Begin block since it stays constant for all objects that come in through the pipeline.
Line 44: This is where the value of the -Switch parameter is used.
Line 49: If the function is not used in a pipeline, the $Datastore variable can be an array. To solve this and to avoid an If-statement to discover this situation, I used the ForEach-Object cmdlet.
Line 60,62: The ForEach statement will execute the code block at least once, even if the collection is $null. These 2 If-statements avoid this situation. A $null value in a condition is interpreted as $false.
Samples
The Find-ThinDisk function can be called in several ways.
As a standalone cmdlet
1 |
Find-ThinDisk -Datastore (Get-Datastore DS*) |
And it can be used in a pipeline as follows
1 |
Get-Datastore -Name "DS*" | Find-ThinDisk |
In both invocation methods the result will be the same and will look something like this.
A handy feature is the -Thin parameter. This switch is by default $true and hence the function will return only Thin virtual disks. But you can set the switch to $false and then the function will return all non-Thin disks.
1 |
Get-Datastore -Name DS1 | Find-ThinDisk -Thin:$false |
Needless to say that the HostDatastoreBrowserSearchSpec object contains many other interesting properties that can be used to launch other queries against a datastore.
Let me know if there is a specific query you are looking for ?
Rick
Could we just use
get-datacenter | Get-Datastore | Get-VM | Get-HardDisk | Where {$_.storageformat -eq “Thin” } | Select Parent, Name, CapacityGB, storageformat | FT -AutoSize
LucD
Yes, you can do it that way.
THis is an older post from the time that option was not available yet.
DaveM
sorry, that should read …”…I’m trying to write a powercli script that will search for datastores that have 20% and under available storage and are made up of thin disks…”
Thanks,
– DM
DaveM
Hey LucD,
I’m interested in using the find-thin function in powercli. How do I get it? I’m trying to write a powercli script that will search for all datastores that are 20% and under consumed and have thin disks. I was hoping to incorporate the find-thin function in my script to see if I can get the results I’m looking for. Please let me know….thanks in advance!
Thanks,
– DM
David M
How do I use Find-Thin cmdlet? Do I need to import a module? If so, where do I get it?
Thanks,
– DM
Lenny
Do you have a script that will list Eager Zeroed disks?
Tommy
Great script! Anyway to get the thin disk size too? I’m new to PowerCLI . I’m having fun with it! I appreciate all of your work -it’s good stuff!!
LucD
@Tommy, that is possible.
Have a look at my yadr – A vdisk reporter post, it shows Thin disks and how much they already consumed.
Michael
Thanks Luc, found this via google and works great. Is is possible to ignore snapshots and RDM vmdk files from the results?
antize
Ever since VMware 4.0.1 came out with support for thin disks with Lab Manager and ESX/vCenter, we have been working to convert all of our disks to thin disks to save space on our storage arrays. On a side note, we do have to be careful with this though because it could lead to over provisioning. So I’ve been looking to create something with PowerShell to get a list of thick disks so I can target the biggest ones first. Now that LucD has navigated the API and has put together this nice script, I now have a means to do this with Powershell in an easy to use object oriented fashion! Before I was thinking about creating a bash or perl script to read .vmdk files looking for: ddb.thinProvisioned = “1”, yuck! Thanks LucD!
Andy
Great script! Useful in large environments where you want to confirm that your disks are all thin disk. That way without having to navigate through multiple menu’s in the CLI, you can run this script with the false parameter and you are good to go.