Highlighted
Contributor
Contributor

How to find Orphaned VMDK files

How can we find out Orphaned VMDK files in all the Data-stores.

85 Replies
Highlighted
Commander
Commander

Hi,

You can easily find these orphaned vmdk’s via the Service Console / SSH from Putty:

find -iname “*-flat.vmdk” -mtime +7

Thanks n Regards Umesh Ahuja If your query resolved then please consider awarding points by correct or helpful marking.
0 Kudos
Highlighted
User Moderator
User Moderator

You could try the script from my Orphaned files and folders - Spring cleaning post.


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

Highlighted
Contributor
Contributor

Hi Umesh,

This will exclude the Snapshots file right. i want to check for more than 50 servers. If u have any script... please help.

0 Kudos
Highlighted
Contributor
Contributor

Take a look at this post:

Virtually Jason: Deleting Orphaned (AKA Zombie) VMDK Files

I have found it works well for me.

0 Kudos
Highlighted
Virtuoso
Virtuoso

LucD ,

Just to confirm if the script that you created will not delete anything yet unless it is used with -Delete switch? Is it possible to list the result in .CSV file ?

function Remove-OrphanedData {

<#

.SYNOPSIS   Remove orphaned folders and VMDK files

.DESCRIPTION   The function searches orphaned folders and VMDK files

   on one or more datastores and reports its findings.

   Optionally the function removes  the orphaned folders   and VMDK files

.NOTES   Author:  Luc Dekens

.PARAMETER Datastore

   One or more datastores.

   The default is to investigate all shared VMFS datastores

.PARAMETER Delete

   A switch that indicates if you want to remove the folders

   and VMDK files

.EXAMPLE

   PS> Remove-OrphanedData -Datastore ds1

.EXAMPLE

  PS> Get-Datastore ds* | Remove-OrphanedData

.EXAMPLE

  PS> Remove-OrphanedData -Datastore $ds -Delete

#>

  [CmdletBinding(SupportsShouldProcess=$true)]

  param(

  [parameter(Mandatory=$true,ValueFromPipeline=$true)]

  [PSObject[]]$Datastore,

  [switch]$Delete

  )

  begin{

    $fldList = @{}

    $hdList = @{}

    $fileMgr = Get-View FileManager

  }

  process{

    foreach($ds in $Datastore){

      if($ds.GetType().Name -eq "String"){

        $ds = Get-Datastore -Name $ds

      }

      if($ds.Type -eq "VMFS" -and $ds.ExtensionData.Summary.MultipleHostAccess){

        Get-VM -Datastore $ds | %{

          $_.Extensiondata.LayoutEx.File | where{"diskDescriptor","diskExtent" -contains $_.Type} | %{

            $fldList[$_.Name.Split('/')[0]] = $_.Name

            $hdList[$_.Name] = $_.Name

          }

        }

        Get-Template | where {$_.DatastoreIdList -contains $ds.Id} | %{

          $_.Extensiondata.LayoutEx.File | where{"diskDescriptor","diskExtent" -contains $_.Type} | %{

            $fldList[$_.Name.Split('/')[0]] = $_.Name

            $hdList[$_.Name] = $_.Name

          }

        }

        $dc = $ds.Datacenter.Extensiondata

        $flags = New-Object VMware.Vim.FileQueryFlags

        $flags.FileSize = $true

        $flags.FileType = $true

        $disk = New-Object VMware.Vim.VmDiskFileQuery

        $disk.details = New-Object VMware.Vim.VmDiskFileQueryFlags

        $disk.details.capacityKb = $true

        $disk.details.diskExtents = $true

        $disk.details.diskType = $true

        $disk.details.thin = $true

        $searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec

        $searchSpec.details = $flags

        $searchSpec.Query += $disk

        $searchSpec.sortFoldersFirst = $true

        $dsBrowser = Get-View $ds.ExtensionData.browser

        $rootPath = "[" + $ds.Name + "]"

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

        foreach($folder in $searchResult){

          if($fldList.ContainsKey($folder.FolderPath.TrimEnd('/'))){

            foreach ($file in $folder.File){

              if(!$hdList.ContainsKey($folder.FolderPath + $file.Path)){

                New-Object PSObject -Property @{

                  Folder = $folder.FolderPath

                  Name = $file.Path

                  Size = $file.FileSize

                  CapacityKB = $file.CapacityKb

                  Thin = $file.Thin

                  Extents = [string]::Join(',',($file.DiskExtents))

                }

                if($Delete){

                  If ($PSCmdlet.ShouldProcess(($folder.FolderPath + " " + $file.Path),"Remove VMDK")){

                    $dsBrowser.DeleteFile($folder.FolderPath + $file.Path)

                  }

                }

              }

            }

          }

          elseif($folder.File | where {"cos.vmdk","esxconsole.vmdk" -notcontains $_.Path}){

            $folder.File | %{

              New-Object PSObject -Property @{

                Folder = $folder.FolderPath

                Name = $_.Path

                Size = $_.FileSize

                CapacityKB = $_.CapacityKB

                Thin = $_.Thin

                Extents = [String]::Join(',',($_.DiskExtents))

              }

            }

            if($Delete){

              if($folder.FolderPath -eq $rootPath){

                $folder.File | %{

                  If ($PSCmdlet.ShouldProcess(($folder.FolderPath + " " + $_.Path),"Remove VMDK")){

                    $dsBrowser.DeleteFile($folder.FolderPath + $_.Path)

                  }

                }

              }

              else{

                If ($PSCmdlet.ShouldProcess($folder.FolderPath,"Remove Folder")){

                  $fileMgr.DeleteDatastoreFile($folder.FolderPath,$dc.MoRef)

                }

              }

            }

          }

        }

      }

    }

  }

}

Thanks in advance.

/* Any kind of comment or input would be greatly appreciated */
0 Kudos
Highlighted
User Moderator
User Moderator

Confirmed, without the Delete switch nothing will be removed.

The script shows the results on the console by default.

You can just pipe the result to a CSV.

Remove-OrphanedData -Datastore DS1 | Export-Csv report.csv -NoTypeInformation -UseCulture


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

Highlighted
Virtuoso
Virtuoso

LucD ,

You are absolutely wonderful Smiley Happy.

Thanks for the script.

/* Any kind of comment or input would be greatly appreciated */
0 Kudos
Highlighted
Virtuoso
Virtuoso

Hi Luc,

What about executing the script to go through all of my VMFS datastore ?

I tried the below line:

Remove-OrphanedData -Datastore * | Export-Csv -Path "C:\TEMP\VMDKreport.csv" -NoTypeInformation -UseCulture

but somehow it doesn't work ?

/* Any kind of comment or input would be greatly appreciated */
0 Kudos
Highlighted
User Moderator
User Moderator

Try like this

Get-Datastore | Remove-OrphanedData | Export-Csv report.csv -NoTypeInformation -UseCulture


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

Highlighted
Virtuoso
Virtuoso

Yes, it works as expected.

Thanks once again Luc.

/* Any kind of comment or input would be greatly appreciated */
0 Kudos
Highlighted
Enthusiast
Enthusiast

Hey LucD, I'm trying to run this script but I'm not getting any data out of it.

I copy the function that is pasted in this thread, then after I put:

connect-viserver nameofmyvcenterhere

Remove-OrphanedData -Datastore SGINSCLSV01_DATASTORE1 | Export-Csv 'E:\report.csv' -NoTypeInformation -UseCulture

It runs without error, but just brings me back to the prompt and doesn't export a CSV at all. Any insight?

Thanks

0 Kudos
Highlighted
User Moderator
User Moderator

It could mean there are no orphaned VMDK on that datastore.

Can you do a test, create a VM and then unregister it?


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

Highlighted
Enthusiast
Enthusiast

I know there are a lot. We have a program (Turbonomic) that shows orphaned VMDKs and has many in the list of that datastore, but I'm trying to get to a point where we don't have to rely on third party tools for the information.

EDIT: I should also mention that it returns to the prompt immediately - like it's not searching at all.

0 Kudos
Highlighted
User Moderator
User Moderator

The function only works for shared VMFS datastores.

Is your datastore a shared VMFS datastore?


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

Highlighted
Enthusiast
Enthusiast

Ha! That's why... They're all NFS datastores. Am I screwed at this point?

0 Kudos
Highlighted
User Moderator
User Moderator

You can test with this

Get-Datastore -Name SGINSCLSV01_DATASTORE1 |

select Name,Type,@{N='Shared';E={$_.ExtensionData.Summary.MultipleHostAccess}}


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

0 Kudos
Highlighted
User Moderator
User Moderator

Try removing lines 42 and 124, in theory it should work for NFS datastores as well


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

0 Kudos
Highlighted
Enthusiast
Enthusiast

Removing 42 and 124 worked perfectly! Thank you so much!

0 Kudos
Highlighted
Contributor
Contributor

Is there a way to exclude a directory? It works great for NFS with the modifications listed. But as we use a NetApp feature I would like to exclude the folder .snapshot/

0 Kudos