Thursday, 11 August 2011

Checks datastores for orphaned VMDK files

#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'