vwmagic
Enthusiast
Enthusiast

Powershell to list all hard disks usage(total, free size and percentage) across all VM's?

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!

0 Kudos
17 Replies
LucD
Leadership
Leadership

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

0 Kudos
vwmagic
Enthusiast
Enthusiast

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?

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vwmagic
Enthusiast
Enthusiast

>>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!

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vwmagic
Enthusiast
Enthusiast

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.

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vwmagic
Enthusiast
Enthusiast

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

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vwmagic
Enthusiast
Enthusiast

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

0 Kudos
LucD
Leadership
Leadership

Did you use the Set-PowerCLIConfiguration cmdlet as the error suggests?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vwmagic
Enthusiast
Enthusiast

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

 

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vwmagic
Enthusiast
Enthusiast

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!

 

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
anilspp
Enthusiast
Enthusiast

Great info thanks for replying & sharing.

0 Kudos
vwmagic
Enthusiast
Enthusiast

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!

 

0 Kudos