VMware Cloud Community
hguthrie
Contributor
Contributor
Jump to solution

Disk consolidation script -- Need help testing

Recently we encountered an issue where a team member mistakenly did not delete a snapshot following some maintenance on a VM.  Long story short, the snapshot ballooned into more than 2TB and took many hours to consolidate.  Aside from the obvious of "don't forget to delete snapshots", we're looking for ideas on ways to prevent this from happening.

One idea that our manager wanted us to pursue was to have a script which would routinely scan for VMs showing the "Disk Consolidation Needed" warning. It would then alert us, and start the consolidation process. This wasn't complicated to write, but I'm having trouble getting a VM into the "Disk Consolidation Needed" state to test it.

Also, any other ideas on better ways to handle this are certainly welcome.

Script code:

# Overview: Check vCenter(s) for any VMs with disks needing consolidation. If it finds any, attempt to consolidate them.

# Notes: Since we don't specify a credential pair to connect with, it will attempt to connect as the current script environment's user.


# Load PowerCLI Module

Import-Module -Name VMware.VimAutomation.Core


##### Variables #####

$vCenters = @('XXXX', 'YYYY')

$logpath = "$env:SystemDrive\Windows\Temp\VM_Consolidation.log"

############


<#

.SYNOPSIS

Logs messages to a file


.DESCRIPTION

Receives messages and logs them to an output file.


.PARAMETER msg

The message to be written


.EXAMPLE

Write-Log 'Write this to the logfile'


.NOTES

Requires $logfile to be configured as the path to the output log file

#>

function Write-Log {

  param($msg)

  "$(Get-Date -Format G) : $msg" | Out-File -FilePath $logpath -Append -Force

}


foreach ($vCenter in $vCenters) {

  try {

   Connect-VIServer $vCenter -ErrorAction Stop

  } catch {

   Write-Log 'Cannot connect to $vCenter'

  }

}


if ($Global:DefaultVIServers.Count -gt 0) {

  $VMsNeedingConsolidation = Get-VM | Where-Object {$_.ExtensionData.Runtime.consolidationNeeded}


  if ($VMsNeedingConsolidation -gt 0){

   Write-Log "VMs needing consolidation: $VMsNeedingConsolidation"


   $VMsNeedingConsolidation | ForEach-Object {

   Write-Log "Needs consolidation $_ "

  $_.ExtensionData.ConsolidateVMDisks_Task()

  }

  }

}

Tags (2)
33 Replies
vmk2014
Expert
Expert
Jump to solution

HI Lucd,

I did run the script after removing the quotes around the string but still same error. Script attached for you ref.

PS D:\vmk> .\consolidate-Disk.ps1

D:\vmk\report.txt : The term 'D:\vmk\report.txt is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was

included, verify that the path is correct and try again.

At D:\vmk\consolidate-Disk.ps1:1 char:13

+ $logPaths = D:\vmk\report.txt

+             ~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (D:\vmk\report.txt:String) [], CommandNotFoundException

    + FullyQualifiedErrorId : CommandNotFoundException

Out-File : Cannot bind argument to parameter 'FilePath' because it is null.

At D:\vmk\consolidate-Disk.ps1:10 char:57

+ ...  "$(Get-Date -Format G) : $msg" | Out-File -FilePath $logpath -Append ...

+                                                          ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Out-File], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.OutFileCommand

Type Value

is it possible to modify attached script.

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

There should be quotes around the full filename, as I mentioned in Re: Disk consolidation script -- Need help testing


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

I tried the script suggested but it keeps showing in log.

11/8/2019 12:55:32 PM : Cannot connect to $vCenter

11/8/2019 12:55:36 PM : Cannot connect to $vCenter

11/8/2019 12:58:09 PM : Cannot connect to $vCenter

11/8/2019 12:58:13 PM : Cannot connect to $vCenter

11/8/2019 1:05:20 PM : Cannot connect to $vCenter

11/8/2019 1:05:24 PM : Cannot connect to $vCenter

11/8/2019 1:06:58 PM : Cannot connect to $vCente

i got prompted for vcenter credential and i entred the credential

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you initialise the $vcenters variable somewhere in your script?
It should contain the names of the vCenters for which you want to consolidate the VM disks.


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Yes, like this

$vCenters = @('XXXX', 'YYYY')

replaced - $vCenters = @('my vc', )

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Do you really have that comma after the 1st VC name?


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LuCd,

No comma after VC. Right now only one VC, i'm trying to connect.

Thanks

vmk

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

In log still shows cannot connect vcenter but in console output

Cannot compare "VM00M967" because it is not IComparable.

At D:\vmk\consolidate-Disk2.ps1:78 char:7

+   if ($VMsNeedingConsolidation -gt 0){

+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

    + FullyQualifiedErrorId : NotIcomparable

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I don't see that line in the last script you attached.


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

I have vcenter ip address, might that is causing issue but np difference. Attaching entire script

$vCenters = $vCenters = @('10.x.x.78')

$logpath = "$env:D\vmk\VM_Consolidation.log"

############

<#

.SYNOPSIS

Logs messages to a file

.DESCRIPTION

Receives messages and logs them to an output file.

.PARAMETER msg

The message to be written

.EXAMPLE

Write-Log 'Write this to the logfile'

.NOTES

Requires $logfile to be configured as the path to the output log file

#>

function Write-Log {

  param($msg)

  "$(Get-Date -Format G) : $msg" | Out-File -FilePath $logpath -Append -Force

}

foreach ($vCenter in $vCenters) {

  try {

   Connect-VIServer $vCenter -ErrorAction Stop

  } catch {

   Write-Log 'Cannot connect to $vCenter'

  }

}

if ($Global:DefaultVIServers.Count -gt 0) {

  $VMsNeedingConsolidation = Get-VM | Where-Object {$_.ExtensionData.Runtime.consolidationNeeded}

  if ($VMsNeedingConsolidation -gt 0){

   Write-Log "VMs needing consolidation: $VMsNeedingConsolidation"

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You need to use the Count property of you want to test like that

$vCenters = $vCenters = @('10.x.x.78')

$logpath = "$env:D\vmk\VM_Consolidation.log"


############

<#

.SYNOPSIS

Logs messages to a file

.DESCRIPTION

Receives messages and logs them to an output file.

.PARAMETER msg

The message to be written

.EXAMPLE

Write-Log 'Write this to the logfile'

.NOTES

Requires $logfile to be configured as the path to the output log file

#>


function Write-Log {

  param($msg)


  "$(Get-Date -Format G) : $msg" | Out-File -FilePath $logpath -Append -Force

}


foreach ($vCenter in $vCenters) {

  try {

   Connect-VIServer $vCenter -ErrorAction Stop

  } catch {

   Write-Log 'Cannot connect to $vCenter'

  }

}


if ($Global:DefaultVIServers.Count -gt 0) {

  $VMsNeedingConsolidation = Get-VM | Where-Object {$_.ExtensionData.Runtime.consolidationNeeded}

  if ($VMsNeedingConsolidation.Count -gt 0){

   Write-Log "VMs needing consolidation: $VMsNeedingConsolidation"

}


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Thank you, LucD. It worked this time, but it only  generated output saying that the VM's consolidation needed in VM_consolidation.log file. I'm looking to automate the VM consolidation and i also observed while using the first script that the disk consolidation fails due to lock on file. Can it be mitigated ?

Thanks

vmk

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Hi LucD,

Can the VM disk consolidation be initiated from this script ? Right now, it only recommend the VM disk consolidation.

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, call the ConsolidateVMDisks method on the VirtualMachine.

$vm.ExtensionData.ConsolidateVMDisks()


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

0 Kudos