#Description: This function checks datastores for orphaned VMDK files
#Purpose: Discovering wasted storage on datastores
#Designed to be added as function into $profile for quick-admin tasks, run from commandline
#Requires VCLI snapin - www.vmware.com/support/developer/vcli/
#Author: Kirk Munro, extracted from VMware powerpack: http://www.powergui.org/entry.jspa?externalID=1802&categoryID=290
#Tested with: ESX4.1
#Last edit by: MsMiller on 11/08/2011
function func_Orphaned_VMDK_Files()
{
$noConnection = $true
if ($defaultVIServers) {
foreach ($managedHost in $defaultVIServers) {
$noConnection = $false
Get-View -ViewType VirtualMachine -Server $managedHost | ForEach-Object {
$_.Layout.Disk | ForEach-Object {
$usedDisk += $_.DiskFile
}
}
}
$uniqueUsedDisk = @()
foreach ($managedHost in $defaultVIServers) {
VMware.VimAutomation.Core\Get-Datastore -Server $managedHost | ForEach-Object {
$dsName = $_.Name
$dsv = $_ | Get-View
$fqFlags = New-Object VMware.Vim.FileQueryFlags
$fqFlags.FileSize = $true
$fqFlags.FileType = $true
$fqFlags.Modification = $true
$searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$searchSpec.details = $fqFlags
$searchSpec.matchPattern = "*.vmdk"
$dsBrowser = Get-View -Server $managedHost $dsv.browser
$rootPath = "["+$dsv.summary.Name+"]"
## Special thanks to Yasen Kalchev @ VMware for a vSphere fix
if ($dsBrowser.Client.Version -eq "Vim4") {
$searchSpec = [VMware.Vim.VIConvert]::ToVim4($searchSpec)
$searchSpec.details.fileOwnerSpecified = $true
$dsBrowserMoRef = [VMware.Vim.VIConvert]::ToVim4($dsBrowser.MoRef);
$searchTaskMoRef = $dsBrowser.Client.VimService.SearchDatastoreSubFolders_Task($dsBrowserMoRef, $rootPath, $searchSpec)
$searchResult = [VMware.Vim.VIConvert]::ToVim($dsBrowser.WaitForTask([VMware.Vim.VIConvert]::ToVim($searchTaskMoRef)))
} else {
trap {
if ($_.Exception.MethodFault -is [VMware.Vim.FileNotFound]) {
continue
} elseif ($_.Exception.MethodFault -is [VMware.Vim.NoPermission]) {
Write-Warning $_
continue
}
else {
Write-Warning $_
continue
}
}
$searchResult = $dsBrowser.SearchDatastoreSubFolders($rootPath, $searchSpec)
}
foreach ($fPath in $searchResult){
$folderPath = $fPath.folderPath
if ($fPath.File){
$fPath.File | ForEach-Object {
$fileSize = $_.FileSize/1024/1024
$lastModified = $_.Modification
$_.Path | ForEach-Object {
$finalFolderPath = ($folderPath + $_)
if (($usedDisk -notcontains $finalFolderPath) -and ($uniqueUsedDisk -notcontains $finalFolderPath) -and ($finalFolderPath -notlike "*-rdm*")){
$uniqueUsedDisk += $finalFolderPath
$orphanedVMDK = New-Object PSObject
$orphanedVMDK.TypeNames.Clear
$orphanedVMDK.PSObject.TypeNames.Insert(0,"VMwareOrphanedVMDK#VmwarePowerPackExtension")
$orphanedVMDK `
| Add-Member -MemberType NoteProperty -Name Datastore -Value $dsname -PassThru `
| Add-Member -MemberType NoteProperty -Name Folder -Value $folderPath -PassThru `
| Add-Member -MemberType NoteProperty -Name File -Value $_ -PassThru `
| Add-Member -MemberType NoteProperty -Name SizeMB -Value $fileSize -PassThru `
| Add-Member -MemberType NoteProperty -Name Modified -Value $lastModified -PassThru
}
}
}
}
}
}
}
}
if ($noConnection) {
Show-MessageBox -Text 'You must connect to one or more vSphere servers before you can run the Orphaned VMDK Files best practice query on those servers. Please click on the ''Managed Hosts'' node, connect to one or more of the vSphere servers you have configured there, and then try again.' -Caption 'Connection not established' -Buttons 'OK' -Icon 'Information' | Out-Null
}
}
func_Orphaned_VMDK_Files | Select-Object -property 'Datastore', 'Folder', 'File', 'Modified', 'SizeMB'