We have about 800 VM's, and with thick provisioning. Some of them allocated a large amount of space but not too much being really used. Thus, they wasted a lot of datastore or storage space. I am thinking to list all hard disks usage along with VM's names, then possibly cut them down.
I am thinking to use POWERSHELL to achieve that, but my skills are limited. Could someone here please help me out? Thanks!
Looking at hard disks from outside the Guest OS will not tell you what is actually in use.
You would need to look inside the Guest OS.
But then the next problem is that you will need to map a VMs harddisk with partitions/filesystems inside the Guest OS.
And afaik, there is no foolproof way to do that.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Then the only way I think I could do is to create a script in which using ssh like tool to log into every single server and retrieve the file systems usage from each server, one by one for all 800 servers. Correct?
Would you happen to have such script?
You can also use the Invoke-VMScript cmdlet, provided you have the VMware Tools installed on the VMs.
Even if you have the disk usage inside the Guest OS, how are you going to link that to the VM's hard disks?
Like I said, there is no foolproof method to do that.
Provided all the requirements are met, you could have a look at the Get-VMGuestDisk cmdlet.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
>>how are you going to link that to the VM's hard disks?
I should understand what you are saying here first. Following is the script that I can come up with that will list all file systems and usages t on a server. Based on usages, I can determine which FS I can shrink and therefore reduce the VM's storage usage.
$VM = Get-VM -name vmname
$VM.HardDisks | Select Name,Filename
$vmg = $VM | Get-VMGuest
$vmg.Disks | select Path,CapacityGB,FreeGB
But, I need make the script to be working across all VM's in the vCenter, and also include the percentage of space being used for the FS, and along with each one of VM's name.
Is this something you can help me to complete. Thank you!
First, there is no $vm.HardDisks property.
I suspect you mean
Get-VM -name vmname |
Get-HardDisk | Select Name,Filename
The basic problem is establishing a link between the info from Get-HardDisk and that in $vmg.Disks.
The first one points to VMDK files, the second one is listing Guest OS partition info.
With Get-VMGuestDisk and Get-HardDisk, provided the requirements are met, you can find the link between a VMDK and Guest OS partition.
For example
Get-VM -PipelineVariable vm |
Get-VMGuestDisk -PipelineVariable guesthd |
Get-HardDisk -ErrorAction SilentlyContinue |
Select @{N='VM';E={$vm.Name}},
@{N='Partition';E={$guesthd.DiskPath}},
@{N='HardDisk';E={$_.FileName}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
My script worked well. So, I am not sure I understand "there is no $vm.HardDisks property.". I am sorry, I am not good in powersell, and I am not a actual vmware guy.
Anyway, by running your script I am getting the following message. It seems to me that I am missing some modules? If yes, how to load them:
Get-VMGuestDisk : The term 'Get-VMGuestDisk' is not recognized as the name of a cmdlet, function, script file, or
operable program.
I suspect you might be using an older PowerCLI version.
What does the following return?
Get-Module -Name VMware.* -ListAvailable
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for your patience!
PowerCLI C:\> Get-Module -Name VMware.* -ListAvailable
Directory: C:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Binary 6.0.0.0 VMware.DeployAutomation
Binary 6.0.0.0 VMware.ImageBuilder
Binary 6.5.0.4... VMware.VimAutomation.Cis.Core
Binary 6.5.0.4... VMware.VimAutomation.Cloud
Manifest 6.5.0.4... VMware.VimAutomation.Common
Binary 6.5.0.2... VMware.VimAutomation.Core HookGetViewAutoCompleter
Binary 6.0.0.0 VMware.VimAutomation.HA
Binary 7.0.2.4... VMware.VimAutomation.HorizonView
Binary 6.5.0.4... VMware.VimAutomation.License
Binary 6.5.0.4... VMware.VimAutomation.PCloud
Manifest 6.5.0.4... VMware.VimAutomation.Sdk Get-PSVersion
Binary 6.5.0.4... VMware.VimAutomation.Storage
Binary 6.5.0.4... VMware.VimAutomation.Vds
Binary 6.5.0.4... VMware.VimAutomation.vROps
Binary 6.0.0.0 VMware.VumAutomation
That is a very old version, I suggest you upgrade.
See Welcome PowerCLI to the PowerShell Gallery – Install Process Updates
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
By following steps as shown in the upgrade link, I uninstalled the old vmware power cli first, then below is the screenshot. Can you please let me know what is the right way to verify if the installation is successful or not? and what went wrong in the end, I couldn't run "Connect-VIServer? I did "install-module..." command several times, hopefully it is alright.
PS C:\WINDOWS\system32> install-module -name vmware.powercli -scope currentuser
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from
'PSGallery'?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): Y
PS C:\WINDOWS\system32> install-module -name vmware.powercli -scope currentuser
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> install-module -name vmware.powercli -scope currentuser
PS C:\WINDOWS\system32> get-module vmware* -listavailable
Directory: C:\Users\myuserID\Documents\WindowsPowerShell\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 12.6.0.... VMware.CloudServices {Connect-Vcs, Disconnect-Vcs, Get-VcsOrganizationRole, Get...
Script 7.0.3.1... VMware.DeployAutomation {Add-CustomCertificate, Add-DeployRule, Add-ProxyServer, A...
Script 7.0.3.1... VMware.ImageBuilder {Add-EsxSoftwareDepot, Add-EsxSoftwarePackage, Compare-Esx...
Manifest 12.6.0.... VMware.PowerCLI
Script 12.6.0.... VMware.PowerCLI.Sdk
Script 12.6.0.... VMware.PowerCLI.Sdk.Types
Script 12.6.0.... VMware.PowerCLI.VCenter {Get-VIMachineCertificate, Get-VITrustedCertificate, Remov...
Script 12.6.0.... VMware.PowerCLI.VCenter.Types.Ap...
Script 12.6.0.... VMware.PowerCLI.VCenter.Types.Ce...
Script 3.2.0.1... VMware.Sdk.Nsx.Policy {Connect-NsxServer, Connect-NsxVmcServer, Disconnect-NsxSe...
Script 1.0.106... VMware.Sdk.Runtime {Get-ServerConfiguration, New-ServerConfiguration, Add-Ser...
Manifest 1.0.104... VMware.Sdk.vSphere
Script 3.0.104... VMware.Sdk.vSphere.Appliance {Invoke-GetItemHealthMessages, Invoke-GetHealthSettings, I...
Script 2.0.104... VMware.Sdk.vSphere.Appliance.Access {Invoke-GetAccessConsolecli, Invoke-SetAccessConsolecli, I...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Health {Invoke-GetHealthApplmgmt, Invoke-GetHealthDatabase, Invok...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Inf... {Invoke-ExportInfraprofileConfigs, Invoke-ImportInfraprofi...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Loc... {Invoke-GetLocalAccountsGlobalPolicy, Invoke-SetLocalAccou...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Log... {Invoke-GetLoggingForwarding, Invoke-SetLoggingForwarding,...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Net... {Invoke-CreateNetworkingDnsDomains, Invoke-ListNetworkingD...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Rec... {Invoke-GetSystemNameArchive, Invoke-ListSystemNameArchive...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Sup... Invoke-GetSupportBundleComponents
Script 1.0.104... VMware.Sdk.vSphere.Appliance.System {Invoke-GetSystemGlobalFips, Invoke-SetSystemGlobalFips, I...
Script 1.0.104... VMware.Sdk.vSphere.Appliance.Update {Invoke-InstallVersionPending, Invoke-ListUpdatePending, I...
Script 1.0.104... VMware.Sdk.vSphere.Cis {Invoke-CreateSession, Invoke-DeleteSession, Invoke-GetSes...
Script 1.0.104... VMware.Sdk.vSphere.Cis.Tagging {Invoke-AddToUsedByCategoryId, Invoke-CreateCategory, Invo...
Script 1.0.104... VMware.Sdk.vSphere.Content {Invoke-GetContentConfiguration, Invoke-UpdateContentConfi...
Script 1.0.104... VMware.Sdk.vSphere.ContentLibrary {Invoke-GetLibraryItemVersionLibraryChanges, Invoke-ListLi...
Script 1.0.104... VMware.Sdk.vSphere.Esx.Hcl {Invoke-DownloadHclCompatibilityDataAsync, Invoke-GetHclCo...
Script 1.0.104... VMware.Sdk.vSphere.Esx.Hosts {Invoke-ListHostSoftwareInstalledComponents, Invoke-GetSof...
Script 1.0.104... VMware.Sdk.vSphere.Esx.Settings {Invoke-DeleteClusterDraftSoftwareAddOn, Invoke-GetCluster...
Script 1.0.104... VMware.Sdk.vSphere.VAPI.Metadata {Invoke-GetCliCommand, Invoke-GetCliCommandFingerprint, In...
Script 1.0.104... VMware.Sdk.vSphere.vCenter {Invoke-GetCluster, Invoke-ListCluster, Invoke-CreateDatac...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Authe... Invoke-CreateAuthenticationToken
Script 1.0.104... VMware.Sdk.vSphere.vCenter.CertM... {Invoke-GetCertificateManagementSigningCertificate, Invoke...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Content {Invoke-CreateContentRegistriesHarbor, Invoke-DeleteRegist...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Datas... Invoke-GetDatastoreDefaultPolicy
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Deplo... {Invoke-CheckMigrateActiveDirectory, Invoke-CancelDeployme...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Guest {Invoke-CreateGuestCustomizationSpecs, Invoke-DeleteNameGu...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Identity {Invoke-CreateIdentityProviders, Invoke-DeleteProviderIden...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Inven... {Invoke-GetInventoryDatastore, Invoke-GetInventoryNetwork}
Script 1.0.104... VMware.Sdk.vSphere.vCenter.ISO {Invoke-MountIsoImage, Invoke-UnmountIsoImage, Initialize-...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.LCM {Invoke-CreateLcmDiscoveryAssociatedProducts, Invoke-Delet...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Names... {Invoke-ListNamespaceManagementSoftwareClusterAvailableVer...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Names... {Invoke-CreateNamespaceDomainSubjectAccess, Invoke-DeleteN...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.OVF {Invoke-ListOvfExportFlag, Invoke-ListOvfImportFlag, Invok...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Services {Invoke-GetService, Invoke-GetServices, Invoke-RestartServ...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Storage {Invoke-ListPoliciesEntitiesCompliance, Invoke-CheckCompat...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Syste... {Invoke-GetSystemConfigDeploymentType, Invoke-SetSystemCon...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Tagging Invoke-ListAssociations
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Topology {Invoke-GetNodeTopology, Invoke-ListTopologyNodes, Invoke-...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Trust... {Invoke-CreateTrustedInfrastructureTrustAuthorityHostsAtte...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.VCHA {Invoke-GetClusterActive, Invoke-DeployVchaClusterAsync, I...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.Vm {Invoke-GetVmHardwareBoot, Invoke-UpdateVmHardwareBoot, In...
Script 1.0.104... VMware.Sdk.vSphere.vCenter.VmTem... {Invoke-CheckInTemplateLibraryItemVmCheckOuts, Invoke-Chec...
Script 1.0.104... VMware.Sdk.vSphere.vStats {Invoke-CreateStatsAcqSpecs, Invoke-DeleteIdStatsAcqSpecs,...
Script 1.0.104... VMware.Sdk.vSphereRuntime {New-vSphereServerConfiguration, Get-vSphereServerConfigur...
Script 7.0.3.1... VMware.Vim
Script 12.6.0.... VMware.VimAutomation.Cis.Core {Connect-CisServer, Disconnect-CisServer, Get-CisService}
Script 12.0.0.... VMware.VimAutomation.Cloud {Add-CIDatastore, Connect-CIServer, Disconnect-CIServer, G...
Script 12.6.0.... VMware.VimAutomation.Common {Get-PowerCLIContext, Get-Task, New-OAuthSecurityContext, ...
Script 12.6.0.... VMware.VimAutomation.Core {Add-PassthroughDevice, Add-VirtualSwitchPhysicalNetworkAd...
Script 12.6.0.... VMware.VimAutomation.Hcx {Connect-HCXServer, Disconnect-HCXServer, Get-HCXAppliance...
Script 12.5.0.... VMware.VimAutomation.HorizonView {Connect-HVServer, Disconnect-HVServer}
Script 12.0.0.... VMware.VimAutomation.License Get-LicenseDataManager
Script 12.5.0.... VMware.VimAutomation.Nsxt {Connect-NsxtServer, Disconnect-NsxtServer, Get-NsxtGlobal...
Script 12.5.0.... VMware.VimAutomation.Sdk {Get-ErrorReport, Get-PSVersion, EnableParameterCompleters...
Script 12.3.0.... VMware.VimAutomation.Security {Add-AttestationServiceInfo, Add-KeyProviderServiceInfo, A...
Script 12.6.0.... VMware.VimAutomation.Srm {Connect-SrmServer, Disconnect-SrmServer}
Script 12.6.0.... VMware.VimAutomation.Storage {Add-EntityDefaultKeyProvider, Add-KeyManagementServer, Ad...
Script 1.6.0.0 VMware.VimAutomation.StorageUtility Update-VmfsDatastore
Script 12.5.0.... VMware.VimAutomation.Vds {Add-VDSwitchPhysicalNetworkAdapter, Add-VDSwitchVMHost, E...
Script 12.6.0.... VMware.VimAutomation.Vmc {Add-VmcSddcHost, Connect-Vmc, Disconnect-Vmc, Get-AwsAcco...
Script 12.5.0.... VMware.VimAutomation.vROps {Connect-OMServer, Disconnect-OMServer, Get-OMAlert, Get-O...
Script 12.4.0.... VMware.VimAutomation.WorkloadMan... {Disable-WMCluster, Enable-WMCluster, Get-WMCluster, Get-W...
Script 12.1.0.... VMware.VumAutomation {Add-EntityBaseline, Copy-Patch, Get-Baseline, Get-Complia...
PS C:\WINDOWS\system32> Connect-VIServer xyz.com
Connect-VIServer : 5/14/2022 11:07:31 PM Connect-VIServer Error: Invalid server certificate. Use
Set-PowerCLIConfiguration to set the value for the InvalidCertificateAction option to Prompt if you'd like to connect
once or to add a permanent exception for this server.
Additional Information: Could not establish trust relationship for the SSL/TLS secure channel with authority
'xyz.com'.
At line:1 char:1
+ Connect-VIServer xyz.com
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [Connect-VIServer], ViSecurityNegotiationException
+ FullyQualifiedErrorId : Client20_ConnectivityServiceImpl_Reconnect_CertificateError,VMware.VimAutomation.ViCore.
Cmdlets.Commands.ConnectVIServer
Did you use the Set-PowerCLIConfiguration cmdlet as the error suggests?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It worked now. Thanks!
Now back to your script, I am getting ERRORS because my vSphere version is 6.7 not 7.0 as required for using Get-VMGuestDisk, according ERRORS below:
Get-VMGuestDisk : 5/15/2022 8:43:41 PM Get-VMGuestDisk The current operation requires a server capability which is
unavailable: 'Get-VMGuestDisk requires vSphere version 7.0 and later'.
At line:2 char:1
+ Get-VMGuestDisk -PipelineVariable guesthd |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (/VIServer=alpha...lumbia.edu:443/:String) [Get-VMGuestDisk], ViError
+ FullyQualifiedErrorId : ViCore_Util10_ExceptionHelper_ServerCapabilityUnavailable,VMware.VimAutomation.ViCore.Cm
dlets.Commands.GetVMGuestDisk
I guess I would then have to pick up my script, can you please help me to make my script below to be able to work across all VM's in the vCenter, and also include percentage of space being used for each file system along with VM name?
$VM = Get-VM -name vmname
$VM.HardDisks | Select Name,Filename
$vmg = $VM | Get-VMGuest
$vmg.Disks | select Path,CapacityGB,FreeGB
I'm not sure what I explained incorrectly before, but
- the objects returned by Get-VM do not have a HardDisks property (unless you have defined a New-VIProperty)
- I did say that the requirements should be met for Get-VMGuestDisk to work
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Okay. understand now.
I have a script below, it does most part of what I wanted to have, which includes all VM's and their assigned, used, free, and percentage of used space. Could you please modify it, and add two more fields:
1. List all file system (drive) paths on each VM.
2. Lists Datastores each VM is associated with
Get-VM |
Select Name,
@{N=“GuestCapacityGB";E={[math]::Round(($_.Guest.Disks | %{ $_.Capacity / 1GB} | Measure-Object -Sum | Select -ExpandProperty Sum),2)}},
@{N="GuestUsageGB";E={[math]::Round(($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum),1)}},
@{N=“FreeSpaceGB";E={[math]::Round(($_.Guest.Disks | %{ $_.FreeSpace / 1GB} | Measure-Object -Sum | Select -ExpandProperty Sum),2)}},
@{N="GuestUsage(%)";E={
$capacityGB = ($_.Guest.Disks | Measure-Object -Property CapacityGB -Sum).Sum
$freeGB = ($_.Guest.Disks | Measure-Object -Property FreeSpaceGB -Sum).Sum
[math]::Round((($capacityGB - $freeGB)/$capacityGB*100),2)}} |
Sort-Object -Property "GuestUsage(%)" |
Export-Csv -Path c:\temp\report.csv -NoTypeInformation -UseCulture
Appreciate your help!
For 1. you need Get-VMGuestDisk to work, which it doesn't since you are not on vSphere 7.*
For 2, you can use the Get-Datastore cmdlet
Get-VM |
Select-Object Name,
@{N = 'Datastores'; E={(Get-Datastore -VM $_).Name -join '|'}},
@{N = "GuestCapacityGB"; E = { [math]::Round(($_.Guest.Disks | ForEach-Object { $_.Capacity / 1GB } | Measure-Object -Sum | Select-Object -ExpandProperty Sum), 2) } },
@{N = "GuestUsageGB"; E = { [math]::Round(($_.Guest.Disks | ForEach-Object { $_.CapacityGB - $_.FreeSpaceGB } | Measure-Object -Sum | Select-Object -ExpandProperty Sum), 1) } },
@{N = "FreeSpaceGB"; E = { [math]::Round(($_.Guest.Disks | ForEach-Object { $_.FreeSpace / 1GB } | Measure-Object -Sum | Select-Object -ExpandProperty Sum), 2) } },
@{N = "GuestUsage(%)"; E = {
$capacityGB = ($_.Guest.Disks | Measure-Object -Property CapacityGB -Sum).Sum
$freeGB = ($_.Guest.Disks | Measure-Object -Property FreeSpaceGB -Sum).Sum
[math]::Round((($capacityGB - $freeGB) / $capacityGB * 100), 2) }
} |
Sort-Object -Property "GuestUsage(%)" |
Export-Csv -Path c:\temp\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Great info thanks for replying & sharing.
Here is my plan: Before vSphere gets upgraded to vSphere 7 here, I am going to use the last version of your script to get those attributes I wanted to have, then if I need to know details about all file systems in VM, I am going to use:
$VM = Get-VM -name vmname.abc.com
$VM.HardDisks | Select Name,Filename
$vmg = $VM | Get-VMGuest
$vmg.Disks | select Path,CapacityGB,FreeSpaceGB
Now, last favor I would like to ask you. Based on the last version of your script, would you please add field of OS(Window or Linux), Power(on or off), CPU's, Memory size?
Thank you!