Hi
I have a virtual machine having a thin provisioned virtual disk. The disk's allocated size is 8 GB but used size is around 2 GB.
I am interested in knowing is there a why of finding out the used size of disk programmatically like we can see in the
vSphere Client GUI's datastore browser. I have already tried to query the datastore using the "HostDatastoreBrowser" but
it also returns the size of disk as 8GB. Any ideas in this direction will be appreciated. Thanks.
Basically with vSphere 4 API, there is a new storageInfo property with a given VM storageInfo and it contains an array of the datastores in which a particular VM's VMDK are stored and provides attributes such as committed, uncommitted and shared.
=========================================================================
William Lam
VMware vExpert 2009
VMware ESX/ESXi scripts and resources at:
VMware Code Central - Scripts/Sample code for Developers and Administrators
If you find this information useful, please award points for "correct" or "helpful".
Hi William Lam
Thanks a lot of reply. Your reply was helpful but I was looking for more granular information i.e. down to each thin provisioned virtual disk
of the virtual machine. Right now we have the information at the virtual machine level only and not for individual disks.
Unfortunately that information is not exposed at the VMDK level, if you had a single VMDK on a single datstore, then you can use the information exposed at the datastore level, but if you have multiple disks, then you won't be able to correlate.
=========================================================================
William Lam
VMware vExpert 2009
VMware ESX/ESXi scripts and resources at:
VMware Code Central - Scripts/Sample code for Developers and Administrators
If you find this information useful, please award points for "correct" or "helpful".
Is this still true? It's impossible to get thin provisioning info on a per virtual disk level?
Thanks!
Yes I believe that is still true today, you don't get the actual "used" value when querying from the datastore and afaik, there is no property on a per VMDK that tells you how much has been consumed, part of this requires some guest data since you could be doing thin provisioned but if you created a file and then deleted it, the block has already been updated unless you have zeroed it out again which needs data feed back to vSphere ....
The best you can do is on a per VM basis or per Datastore basis on the amount of thin provisioning savings, check this script out for some details - http://communities.vmware.com/docs/DOC-10777
there is a way now to find out about thin provisioned disks
Get-VM | select Name,VmHost,UsedSpaceGB,ProvisionedSpaceGb | Sort-Object {$_.name} | format-list
I am working on this and if someone would like to carry on it would be agreat help. I would like to go through my entire enterprise and group my vm's by hosts the only information I need is the information above.
I figure I will have to use var to store the above information then group it by host name and output it to a table.
Thanks hope some of my code helps.
RichG
I've been playing around with this today and it is possible to identify how much space EACH virtual disk is consuming on the datastore when it is thin provisioned (regardless of how many virtual disks are on the same datastore).
I was able to achieve this using the datastore browser. Attached is a script that allows you to query a VM's virtual disk usage (for every disk it has).
Usage:
./guest_disk_usage.pl --server <ESXi Host or vCenter Server> --username <username> --password <password> --guest <vm to query>
Output:
Hard disk 1 (scsi0:0) on 'RAID1 (0)(7)'
Provisioning: Thin
Total Size: 200.5 GB
Size On Datastore: 24.6 GB
Free Space: 175.9 GB
Hard disk 2 (scsi0:1) on 'RAID1 (0)(7)'
Provisioning: Thin
Total Size: 700.5 GB
Size On Datastore: 355.4 GB
Free Space: 345.1 GB
Hard disk 3 (scsi0:2) on 'RAID1 (0)(7)'
Provisioning: Thin
Total Size: 701.5 GB
Size On Datastore: 419.6 GB
Free Space: 281.9 GB
Hard disk 4 (scsi0:3) on 'RAID1 (1)(3)'
Provisioning: Thin
Total Size: 702.5 GB
Size On Datastore: 656.4 GB
Free Space: 46.1 GB
Here is the script:
#!/usr/bin/perl -w
# ------------------------------------------------------------------------------
# guest_disk_usage.pl
# Copyright (C) 2014 Troy Lea AKA Box293
# Original Author: Troy Lea <troy@box293.com> Twitter: @Box293
# See all my Nagios Projects on the Nagios Exchange:
# http://exchange.nagios.org/directory/Owner/Box293/1
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
#
# Version 2014-01-30
use strict;
use VMware::VIRuntime;
# Define Options
my %opts = (
guest => {
type => '=s',
help => 'The name of the virtual machine you want to generate disk usage information.',
required => 1,
}, # End 'guest' => {
); # End my %opts = (
# Read/Validate options and connect to the server
Opts::add_options(%opts);
# Check and validate the options
Opts::parse();
Opts::validate();
# Connect to vCenter or ESX(i) Host
Util::connect();
my $target_guest_view;
my $target_guest_option;
# Need to make sure the --guest argument has been provided
if (!Opts::option_is_set('guest')) {
# The --guest argument was not provided, abort
die "The --guest argument was not provided, aborting!\n";
} # End if (!Opts::option_is_set('guest')) {
else {
$target_guest_option = Opts::get_option('guest');
$target_guest_view = Vim::find_entity_view (
view_type => 'VirtualMachine',
filter => {
name => $target_guest_option
}
); # End $target_guest_view = Vim::find_entity_view (
} # End else {
# Make sure we were able to find the guest
if (!$target_guest_view) {
# Guest was not found, aborting
die "Guest \'" . $target_guest_option . "\' not found\n";
} # End if (!$target_guest_view) {
# Get the host this guest is currently running on
my $target_host_view = Vim::get_view (
mo_ref => $target_guest_view->summary->runtime->host
); # End $target_host_view = Vim::get_view (
# Get all the virtual disks in the guest
my $guest_disks;
my $guest_controllers;
my $guest_disk_counter = 0;
# Loop through all the devices in the guest
foreach my $device (@{$target_guest_view->config->hardware->device}) {
# Check for a VirtualDisk
if (ref($device) eq 'VirtualDisk') {
# Add this VirtualDisk to $guest_disks
$guest_disks->{$guest_disk_counter} = $device;
$guest_disk_counter++;
} # End if (ref($device) eq 'VirtualDisk') {
# Check for a VirtualSCSIController
if (ref($device)->isa('VirtualSCSIController')) {
# Add this VirtualSCSIController to $guest_controllers
$guest_controllers->{$device->key} = $device;
} # End if (ref($device)->isa('VirtualSCSIController')) {
# Check for a VirtualIDEController
if (ref($device)->isa('VirtualIDEController')) {
# Add this VirtualIDEController to $guest_controllers
$guest_controllers->{$device->key} = $device;
} # End if (ref($device)->isa('VirtualIDEController')) {
} # End foreach my $device (@{$target_guest_view->config->hardware->device}) {
# Make sure the guest has virtual disks
if (defined($guest_disks)) {
# Loop through all the virtual disks
for (my $current_disk = 0; $current_disk < scalar(keys %$guest_disks); $current_disk++) {
# Get the datastore this virtual disk resides on
my $target_datastore_view = Vim::get_view (
mo_ref => $guest_disks->{$current_disk}->backing->datastore
); # End $target_host_view = Vim::get_view (
my $datastore_name = $target_datastore_view->summary->name;
my $disk_name = $guest_disks->{$current_disk}->deviceInfo->label ;
my $disk_id;
my $controller_label = $guest_controllers->{$guest_disks->{$current_disk}->controllerKey}->deviceInfo->label;
if ($controller_label =~ /^(SCSI)/) {
$disk_id = "scsi" . $guest_controllers->{$guest_disks->{$current_disk}->controllerKey}->busNumber . ":" . $guest_disks->{$current_disk}->unitNumber;
} # End if ($controller_label =~ /^(SCSI)/) {
elsif ($controller_label =~ /^(IDE)/) {
$disk_id = "ide" . $guest_controllers->{$guest_disks->{$current_disk}->controllerKey}->busNumber . ":" . $guest_disks->{$current_disk}->unitNumber;
} # End elsif ($controller_label =~ /^(IDE)/) {
my $disk_capacity = $guest_disks->{$current_disk}->capacityInKB / 1048576;
my $disk_provision_type;
my $disk_size_on_datastore;
# Determine the thin provisioning type and disk size on datastore
if ($guest_disks->{$current_disk}->backing->thinProvisioned) {
$disk_provision_type = 'Thin';
# Because it's a thin disk, get the size it is consuming on the datastore
# Get the $current_disk_file_name
my $current_disk_file_name = (split(/\//, $guest_disks->{$current_disk}->backing->fileName))[1];
# Get the datastore browser
my $target_datastore_browser = Vim::get_view(mo_ref => $target_datastore_view->browser);
# Create the SearchSpec for browsing the datastore
my $file_search_spec = HostDatastoreBrowserSearchSpec->new(
details => FileQueryFlags->new(
fileOwner => 1,
fileSize => 1,
fileType => 1,
modification => 1
),
matchPattern => [$current_disk_file_name]
); # End my $file_search_spec = HostDatastoreBrowserSearchSpec->new(
# Perform the search of the datastore
my $target_datastore_browser_results = $target_datastore_browser->SearchDatastoreSubFolders(
datastorePath => '[' . $datastore_name . ']',
searchSpec => $file_search_spec,
); # End my $target_datastore_browser_results = $target_datastore_browser->SearchDatastoreSubFolders(
# Now loop through the search results to get the items we are after
foreach my $datastore_item (@$target_datastore_browser_results) {
foreach my $array_item (@{$datastore_item->file}) {
# Define $disk_size_on_datastore
$disk_size_on_datastore = sprintf("%.1f", $array_item->fileSize / 1073741824);
} # End foreach my $array_item (@{$datastore_item->file}) {
} # End foreach my $datastore_item (@$target_datastore_browser_results) {
} # End if ($device->backing->thinProvisioned) {
elsif ($guest_disks->{$current_disk}->backing->eagerlyScrub) {
$disk_provision_type = 'Thick (Eager)';
# Define $disk_size_on_datastore (because it's thick it's the same as the capacity)
$disk_size_on_datastore = $disk_capacity;
} # End elsif ($device->backing->eagerlyScrub) {
else {
$disk_provision_type = 'Thick (Lazy)';
# Define $disk_size_on_datastore (because it's thick it's the same as the capacity)
$disk_size_on_datastore = $disk_capacity;
} # End else {
print "$disk_name ($disk_id) on \'$datastore_name\' \n";
print "Provisioning: $disk_provision_type \n";
print "Total Size: $disk_capacity GB \n";
print "Size On Datastore: $disk_size_on_datastore GB \n";
if ($disk_provision_type eq 'Thin') {
# Get the remaining free space in the thin disk
my $disk_space_remaining = $disk_capacity - $disk_size_on_datastore;
print "Free Space: $disk_space_remaining GB \n";
} # End if ($disk_provision_type eq 'Thin') {
print "\n"
} # End for (my $current_disk = 0; $current_disk < scalar(keys %$guest_disks); $current_disk++) {
} # End if (defined($guest_disks)) {
else {
# There are no virtual disks, abort
die "This guest has NO virtual disks, aborting!";
} # End else {
# Disconnect from the vCenter Server / ESX(i) Host
Util::disconnect();
Cheers
Troy
This doesn't work. The fileSize and capacity of the vmdk file are always the same.