Monday, February 15, 2016

Find and get all orphaned VMDK's within your datacenter datastores.

#


# Purpose : List all orphaned vmdk on all datastores in all VC's

# Version: 1.1

# Author : HJA van Bokhoven

# Modified: Search multiple vDatacenters + Added code to make vmdk comparison better

#


#Timer
$scriptStartDate = get-date



#Main

$SearchDatacenter = "XXXX"    #change to your datacenter name

$arrayVC = "XXXX.com"         #change to your vCenter Server

$dtTime = get-date -UFormat "%Y%m%d_%H%M%S"

$strOutfile = "C:\tmp\vmware\find_orphaned_vmdks_${dtTime}.csv"

$Col = @()

Foreach ($strVC in $arrayVC)



{
Connect-VIServer $strVC




# $arrUsedDisks = Get-VM | Get-HardDisk | %{$_.filename}
$arrUsedDisks = Get-datacenter $SearchDatacenter | Get-VM | Get-HardDisk | %{ ($_.filename).ToLower() }




"<<<<<<<<<<<<<<<<<<"
#$arrUsedDisks

$arrUsedDisks|measure-object




"<<<<<<<<<<<<<<<<<<"

#exit
#DEBUG

#$arrUsedDisks | measure-object

#$arrUsedDisks

#echo " "

#

#...

#[LUN-name] VM-name/VM-name.vmdk

#[LUN-name] VM-name/VM-name.vmdk

#...

$arrDS = Get-datacenter $SearchDatacenter | get-vmhost | Get-Datastore

Foreach ($strDatastore in $arrDS)



{
$strDatastoreName = $strDatastore.name




"------------------------------"
$strDatastoreName
"------------------------------"

$ds = Get-Datastore -Name $strDatastoreName | %{Get-View $_.Id}

$fileQueryFlags = New-Object VMware.Vim.FileQueryFlags

$fileQueryFlags.FileSize = $true

$fileQueryFlags.FileType = $true

$fileQueryFlags.Modification = $true

$searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec

$searchSpec.searchCaseInsensitive = $True # DREF:we want case INsensitive search

$searchSpec.matchPattern = @("*.vmdk", "*.vrb") # DREF:find only these filetypes

$searchSpec.details = $fileQueryFlags




# $searchSpec.sortFoldersFirst = $true

#"##############################"

#$ds|measure-object

#"##############################"

$ds | % {

$thisDS = $_

$dsBrowser = Get-View $thisDS.browser

# $dsBrowser = Get-View $thisDS.MoRef

# $dsBrowser = Get-View -ViewType Datastore -VIObject $thisDS.MoRef

$rootPath = "["+$thisDS.summary.Name+"]"

$searchResult = $dsBrowser.SearchDatastoreSubFolders($rootPath, $searchSpec)

$myCol = @()

foreach ($folder in $searchResult)



{
$thisfolder = $folder.FolderPath # [LUN-name] VM-name/

foreach ($fileResult in $folder.File)



{
$file = "" | select Name, FullPath

$file.Name = $fileResult.Path

$strFilename = $file.Name

if ($strFilename) {




if (!$strFilename.Contains("-flat.vmdk") -AND !$strFilename.Contains("delta.vmdk") -AND !$strFilename.Contains("ctk.vmdk") -AND !$strFilename.Contains("-000"))

#flat files arent linked to directly in .vmx, and dont find delta files, and dont find CTK files, and dont find snapshot files



{
$strCheckfile = "*"+$file.Name+"*"

$realpath = ($thisfolder + "" + $strFilename).ToLower()

if ($arrUsedDisks -NotContains $realpath) {




Write-Host -BackgroundColor Red -ForegroundColor White "ORPHAN!`t${realpath}"




$this = "" | select VC,SearchCluster,OrphanVMDK,ModifiedDaysAgo,SizeGB

$now = (Get-Date)

$then = ([datetime] $fileResult.Modification)

$fileage = ($now-$then).Days

$filesizeGB = [int](($fileResult.FileSize)/1024/1024/1024)

$this.VC = $strVC

$this.SearchCluster = $SearchCluster

$this.OrphanVMDK = $realpath

$this.ModifiedDaysAgo = ${fileage}

$this.SizeGB = ${filesizeGB}




$Col+=$this




# $strOutput = "Orphaned VMDK Found: "+ $realpath + " `tFileModifiedDaysAgo: ${fileage} `tFileSizeGB: ${filesizeGB}"

# $strOutput



}
else {

Write-Host -BackgroundColor Green -ForegroundColor Black "IsFine!`t${realpath}"



}

}

}

}

}

}

}

}
#Timer
$scriptStopDate = get-date

echo ($scriptStartDate).date

echo ($scriptStopDate).date

$Col | sort VC,OrphanVMDK,ModifiedDaysAgo,SizeGB | ConvertTo-Csv -NoTypeInformation | Out-File $strOutfile