Created
April 24, 2017 08:16
-
-
Save mo6020/e2cf196c0954092d8450dab564c9e538 to your computer and use it in GitHub Desktop.
Gets VM RoC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# This scripts measures the amount of disk change on VMs each time it is run. | |
# It measures all VM virtual disks for which CBT has been enabled. | |
# | |
# The first time it is run, it creatse a file containing baseline data (CBT change IDs and times). | |
# Each subsequent run measures changes since the baseline was set. | |
# It supports multiple virtual disks per VM, but not addition of new virtual disks after the baseline is established. | |
# Note that every run creates a short-lived snapshot on every VM that has CBT enabed. | |
# | |
# Time to run will vary in each environment. In my case, it took about 20 seconds per VM for the 1st run, | |
# and about half that long for subsequent runs. | |
# | |
# To reset the baseline, just delete (or move, or rename) the baseline file and re-run. | |
# | |
# | |
# # Inspired by the VMGuru.com blog posting of August 2011 -- "CBT Tracker Powershell Script - now with more zombie" | |
# # Re-imagined completely by Carlo.G, February 2016 | |
# # Corrected to call QueryChangedDiskArea repeatedly, May 2016 | |
# | |
# | |
# Important literals used in this script | |
# | |
$Folder = 'C:\Temp' | |
$Basefile = 'Baselines.csv' | |
$Datafile = 'Data.csv' | |
$vCenter = 'vcenter.domain.tld' | |
$DTformat = 'yyyy-MM-dd HH:mm:ss' # Chosen to import correctly into Excel | |
$Creds = Get-Credential 'domain\userid' -Message 'Provide userid\password with permissions on VCenter' | |
# | |
# Initialize PowerCLI and connect to vCenter | |
# | |
Set-Location "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts" | |
. .\Initialize-PowerCLIEnvironment.ps1 $true | |
Connect-VIServer $vcenter -Credential $creds | |
# | |
# Get list of VMs with Change Block Tracking (CBT) enabled | |
# | |
$Vms = Get-VM | ?{$_.PowerState -eq 'PoweredOn'} | ?{(Get-View $_).Config.ChangeTrackingEnabled} | |
# Override with a list of specific VM names for testing | |
# $Vms = @('TEST_VM_1','TEST_VM_2','TEST_VM_3') | % {Get-VM $_} | |
# | |
# Exclude VMs that are sensitive to snapshots | |
# | |
$Vms = $VMs | ?{$_.name -notmatch 'HATES_SNAPSHOTS' } | |
# | |
# Retrieve or generate baseline change ids (one for each disks) for each VM in list to be measured | |
# Generating a new baseline requires creating a snapshot (which is removed immediately) | |
# | |
# Note that there may be more than one disk per VM. | |
# and in some cases only some disks have CBT enabled. | |
# | |
$n = $VMs.count | |
$i = 0 | |
Write-Host "Getting baselines for $n VMs" | |
$baselines = @() | |
Try {$baselines = Import-CSV (Join-Path $folder $basefile)} | |
Catch {Write-Host -f cyan "No $(Join-Path $folder $basefile) file found, so new one will be created" } | |
$more = $false | |
ForEach ($vm in $Vms) { | |
++$i | |
$b = $baselines | ?{$vm.name -eq $_.VMname} | select -first 1 | |
If ($b -eq $null) { | |
Write-Host "Creating baseline for $($vm.name) ($i of $n)" | |
$more = $true | |
$TimeStamp = Get-Date -format $DTformat | |
$snapshot = New-Snapshot -VM $vm -Name 'Temp for CBT baseline - Delete immediately ' -Description "for Carlo's change block tracking script, $TimeStamp" | |
$snapview = Get-View $snapshot | |
$snapdisks = $snapview.Config.Hardware.Device | where {($_.GetType()).Name -eq "VirtualDisk"} | |
ForEach ($d in $snapdisks) { | |
[array]$baselines += New-Object 'PSObject' | select ` | |
@{N='VmName';E={$vm.name}}, | |
@{N='VmGBProv';E={$vm.ProvisionedSpaceGB}}, | |
@{N='VmGBUsed';E={$vm.UsedSpaceGB}}, | |
@{N='DiskSummary';E={$d.deviceinfo.summary}}, | |
@{N='DiskName';E={$d.deviceinfo.label}}, | |
@{N='DiskKey';E={$d.key}}, | |
@{N='TimeStamp';E={$TimeStamp}}, | |
@{N='ChangeId';E={$d.Backing.ChangeId}} | |
} | |
Remove-Snapshot $snapshot -Confirm:$false | |
} | |
} | |
If ($more) {$Baselines | Export-CSV (Join-Path $folder $basefile) -NoTypeInformation -Force} | |
# | |
# For each item in Baselines list, measure changes since baseline was set | |
# A snapshot (which is removed immediately) is needed for each VM measured | |
# Append results to existing file (if it exists) | |
# | |
# Note that there may be more than one disk per VM. | |
# and in some cases only some disks have CBT enabled. | |
# | |
$lastVMname = $null | |
$snapshot = $null | |
$data = @() | |
$Baselines = $BaseLines | Sort VMname, DiskKey | ? {$_.ChangeID -ne '' -and $_.ChangeId -ne $null} | |
$n = $Baselines.count | |
$i = 0 | |
ForEach ($b in $Baselines) { | |
++$i | |
If ($b.VmName -ne $lastVMname) { | |
If ($snapshot -ne $null) {Remove-Snapshot $snapshot -Confirm:$false} | |
$LastVmName = $b.VmName | |
$vm = Get-VM $b.VmName | |
$vmview = Get-View $vm | |
$TimeStamp = Get-Date -format $DTformat | |
$Interval = (New-Timespan $b.TimeStamp $TimeStamp) | |
$snapshot = New-Snapshot -VM $vm -Name 'Temp for CBT polling - Delete immediately ' -Description "for Carlo's change block tracking script, $TimeStamp" | |
$snapview = Get-View $snapshot | |
$snapdisks = $snapview.Config.Hardware.Device | where {($_.GetType()).Name -eq "VirtualDisk"} | sort key | |
} | |
$disk = $snapdisks | ?{$_.key -eq $b.DiskKey} | |
Try { | |
$Offset = 0 | |
$GBChanged = 0 | |
Do { | |
$changes = $VmView.QueryChangedDiskAreas($SnapView.MoRef,$Disk.key,$Offset,$b.ChangeId) | |
$GBchanged += ($changes.ChangedArea | % {$_.length} | measure-object -sum).sum/1024/1024/1024 | |
$LastChange = $changes.changedarea | Sort Start | select -last 1 | |
$Offset = $LastChange.start + $LastChange.Length | |
} | |
While ($Disk.CapacityInBytes -gt $Offset -and $Changes.ChangeArea.Count -gt 0) | |
} | |
Catch {$GBchanged = 'error'} | |
Write-Host "$($b.Vmname) $($b.DiskName) $GBchanged GB changed since $($b.TimeStamp) ($i of $n)" | |
$data += New-Object 'PSObject' | select ` | |
@{N='VmName';E={$vm.name}}, | |
@{N='DiskName';E={$disk.deviceinfo.label}}, | |
@{N='DiskSummary';E={$disk.deviceinfo.summary}}, | |
@{N='BaseTime';E={$B.TimeStamp}}, | |
@{N='ThisTime';E={$TimeStamp}}, | |
@{N='Interval';E={$Interval}}, | |
@{N='GBChanged';E={$GBChanged}}, | |
@{N='VmGBProv';E={$vm.ProvisionedSpaceGB}}, | |
@{N='VmGBUsed';E={$vm.UsedSpaceGB}} | |
} | |
Remove-Snapshot $snapshot -Confirm:$false -EA 0 | |
$Data | Export-CSV (Join-Path $folder $datafile) -NoTypeInformation -Append | |
# | |
# Check for left-over CBT-related snapshots | |
# | |
Write-Host "Checking for leftover snapshots..." | |
$Snapshots = Get-VM | Get-Snapshot | ?{$_.name -match '\sCBT\s'} | |
If ($snapshots) { | |
Write-Host -f red "$(Snapshots.count) left-over CBT snapshots????" | |
$Snapshots | ft vm,created,name | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment