VMware Cloud Community
Guv
Enthusiast
Enthusiast

orphaned vmdk files script

I found the below useful script for finding orphaned vmdk files as seen below:

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

  2. Version: 1.1

  3. Author : HJA van Bokhoven

  4. Modifications: LucD

$report = @()

$arrUsedDisks = Get-View -ViewType VirtualMachine | % {$_.Layout} | % {$_.Disk} | % {$_.DiskFile}

$arrDS = Get-Datastore | Sort-Object -property Name

foreach ($strDatastore in $arrDS) {

Write-Host $strDatastore.Name

$ds = Get-Datastore -Name $strDatastore.Name | % {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.details = $fileQueryFlags

$searchSpec.matchPattern = "*.vmdk"

$searchSpec.sortFoldersFirst = $true

$dsBrowser = Get-View $ds.browser

$rootPath = ""

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

foreach ($folder in $searchResult)

{

foreach ($fileResult in $folder.File)

{

if ($fileResult.Path)

{

if (-not ($arrUsedDisks -contains ($folder.FolderPath + $fileResult.Path))){

$row = "" | Select DS, Path, File, Size, ModDate

$row.DS = $strDatastore.Name

$row.Path = $folder.FolderPath

$row.File = $fileResult.Path

$row.Size = $fileResult.FileSize

$row.ModDate = $fileResult.Modification

$report += $row

}

}

}

}

}

When I run this script, it lists my datastores, but then after each datastore it brings up the following error message:

Exception calling "SeachDatastoresubfolders" with "2" argument (s): Invalid datastore path..........

Is there any reason why this script would bring this error message, I am using the lastest version of powercli client, or would it mean I have no orphaned vmdk files. Any advise.

72 Replies
drivera01
Enthusiast
Enthusiast

Hi LucD,

Since this is commented out, I would assume that it defaults to FALSE and therefore registers what it finds out of inventory?

So since I only want to REPORT any VMDKs and VMs out of inventory and take no other action than reporting. I assume I need to uncomment out this line particular:

114# Register-VMX -entityName "MyDatacenter" -whatif:$true



Am I missing anything else to acheive what I want to do. Since I plan to only check specific clusters, I will update the entity parameter appropriately..


thanks!!

Reply
0 Kudos
LucD
Leadership
Leadership

That line 114 is a sample call of the function.

But your assumption is correct, remove the comment symbol and specify a cluster on the entityName parameter.


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

Reply
0 Kudos
drivera01
Enthusiast
Enthusiast

Hi LucD,

OK got it,

one question... I ran it and it found items I expected, except for one VM out of inventory. The VM it did not find, there actually is a VM by the same displayname in inventory right now. Did the VM with the same displayname that is in inventory confusing the script?

I plan to remove/delete the out of inventory VM, but this is a real case that appears to happen in my environment.. people leave stuff lying around.

Reply
0 Kudos
LucD
Leadership
Leadership

Yes, the script is not intelligent enough to find doubles, of which one is registered.

But that is a good idea !

Something to put on my (long) list of functions I need to write if I find the time :smileygrin:


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

Reply
0 Kudos
drivera01
Enthusiast
Enthusiast

So the other scenario that is  seen alot is there may be a sole vmdk in a folder that is out of inventory for a particular VM.  The original VM was svmotioned so it left this vmdk in its original location in a folder on the original datastore.

As time goes on this type of cruft is left around and forgot about because someone just REMOVED it from the VM and did not DELETE it.

Do you have any suggestions on how to find these orphan VMDKs just laying around?

thanks!!

Reply
0 Kudos
LucD
Leadership
Leadership

Those orphaned VMDK should be discovered by the current script.

Did you encounter any of those that were not discovered ?


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

Reply
0 Kudos
drivera01
Enthusiast
Enthusiast

mean to to say...

yes I did

also to confrim, I staged a scenario on a test VM. I added a disk,  but later removed and left it on a datastore (not the same datastore as the in-nventory VM).

Reply
0 Kudos
LucD
Leadership
Leadership

Just to clarify, the script didn't find that VMDK ?

And did you include the datastore, where that VMDK was located, in the call to the function ?


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

Reply
0 Kudos
drivera01
Enthusiast
Enthusiast

Hi LucD,

The script did not find the VMDK.

I did not include a datatore.. this would be the issue, we have so many datastores and as part of a house cleaning process, it would of been great to just find these out of inventory vmdks since I  would not know where they are located.

Do I have to specify the particular datastore the out of inventory vmdk is on?

Reply
0 Kudos
LucD
Leadership
Leadership

Just to make sure, we are talking about the script from Orphaned files and folders – Spring cleaning ?

If you don't pass anything on the Datastore parameter, the function will look on all shared datastores.


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

Reply
0 Kudos
drivera01
Enthusiast
Enthusiast

That would be the reason, we started talking about your raiders script some how...

so this script " spring cleaning script"

you run it like this?

Remove-OrphanedData -Datastore <datastore-name>

Since I do NOT want to delete anything it finds, I do NOT put in the "-delete" switch?

If I want to check all datastores, do I need to populate $ds as you have as an example:

But then I read this in your post:

When you combine the Delete switch with the WhatIf switch, not files or folders will be deleted. But the function will show what actions will be taken without

I do not understand where to add the whatif switch?

Reply
0 Kudos
LucD
Leadership
Leadership

That is correct, that is how you run it.

Just realised that the parameters can be a bit confusing.

In summary:

Remove-OrphanedData -Datastore ds1

will show orphaned VMDK on datastore named ds1.

When you add the Delete switch, the function will delete the files it finds.

Remove-OrphanedData -Datastore ds1 -Delete

It is safer to first run such a delete with the WhatIf switch.

Then the function will show which files it would delete, but not actually delete them.

Remove-OrphanedData -Datastore ds1 -Delete -WhatIf

This is in fact producing approximately the same output as if you run the function without the Delete and WhatIf switch.

The only difference is that you will get a line that starts with "What if: performing..."

To run the function against all your datastores, you can do

Remove-OrphanedData -Datastore *

I'm planning a v2 of the function that will have some more intelligence as this version.

But don't hold your breath :smileygrin:


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

Reply
0 Kudos
PorzioM
Contributor
Contributor

Does this script work with 5.x? I used a modified version of this script you gave me a little more than a year ago on an environment with 5.0 using NFS datasstores and received an error. below is the script I used and below that is the error. Thanks LucD.

#

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

# Version: 1.1

# Author  : HJA van Bokhoven

# Modifications: LucD

$arrayVC = "put IP of VC here"

$report = @()

foreach ($strVC in $arrayVC)

{

    Connect-VIServer $strVC

    $arrUsedDisks = Get-View -ViewType VirtualMachine | % {$_.Layout} | % {$_.Disk} | % {$_.DiskFile}

    $arrDS = Get-Datastore | Sort-Object -property Name

    foreach ($strDatastore in $arrDS)

    {

        Write-Host $strDatastore.Name

        $ds = Get-Datastore -Name $strDatastore.Name | % {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.details = $fileQueryFlags

        $searchSpec.matchPattern = "*.vmdk"

        $searchSpec.sortFoldersFirst = $true

        $dsBrowser = Get-View $ds.browser

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

       

        #Workaround for vSphere 4 fileOwner bug

        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 {

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

        }

       

        foreach ($folder in $searchResult)

        {

            foreach ($fileResult in $folder.File)

            {

                if ($fileResult.Path)

                {

                    if (-not ($arrUsedDisks -contains ($folder.FolderPath + $fileResult.Path))){

                        $row = "" | Select DS, Path, File, Size, ModDate, Host

                        $row.DS = $strDatastore.Name

                        $row.Path = $folder.FolderPath

                        $row.File = $fileResult.Path

                        $row.Size = $fileResult.FileSize

                        $row.ModDate = $fileResult.Modification

                        $row.Host = (Get-View $ds.Host[0].Key).Name

                        $report += $row

                    }

                }

            }

        }

    }

    # Disconnect session from VC

    disconnect-viserver -confirm:$false

}

$report | Export-Csv "C:\VMDK-orphaned.csv" -noTypeInformation

Error Recieved:

I only put one of the errors, this was returned for all datastores.

VBLOCK-NFS-2

Get-View : Cannot validate argument on parameter 'VIObject'. The argument is nu

ll or empty. Supply an argument that is not null or empty and then try the comm

and again.

At C:\Users\adm_roberbl1\Desktop\Get-orphaned-VMDK-vSphere.ps1:27 char:24

+         $dsBrowser = Get-View <<<<  $ds.browser

    + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingVal

   idationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

   ation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

You cannot call a method on a null-valued expression.

At C:\Users\adm_roberbl1\Desktop\Get-orphaned-VMDK-vSphere.ps1:38 char:56

+             $searchResult = $dsBrowser.SearchDatastoreSubFolders <<<< ($rootP

ath, $searchSpec)

    + CategoryInfo          : InvalidOperation: (SearchDatastoreSubFolders:Str

   ing) [], RuntimeException

    + FullyQualifiedErrorId : InvokeMethodOnNull

Reply
0 Kudos
deepakjangra023
Contributor
Contributor

hi LucD,

it is giving me a warning message while running this script that it might be harmful.

is it ok to ignore that?

rgds,

Deepak

Reply
0 Kudos
LucD
Leadership
Leadership

Hi Deepak,

You can ignore those warning messages.

You can also disable displaying these warning messages with

Set-PowerCLIConfiguration -DisplayDeprecationWarnings:$false


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

deepakjangra023
Contributor
Contributor

hi LucD,

i am getting blank output of this script whereas there are lots of orphaned VMDKs on the datastore.

can u pls help.

thanks in advance!!

rgds,

Deepak

Reply
0 Kudos
LucD
Leadership
Leadership

Which script did you run ? There are many variations floating around in this thread.

You could start from the script in my VMX Raiders Revisited post.


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

Reply
0 Kudos
deepakjangra023
Contributor
Contributor

Hi LucD,

how i can check whether this orphaned vmdks is not being used?

any script where i can verify as well as delete them?

rgds,

Deepak

Reply
0 Kudos
LucD
Leadership
Leadership

The 1st version of my "raiders" script, in Raiders of the Lost VMX, has an option to delete or not the orphaned VMDK.

It's the WhatIf switch.

The script itself validates if a VMDK is used or not.

In fact the listed VMDK are all checked against all the VMDK connected to VMs.

But is of course the final decission if the VMDK can be deleted is up to you.


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

Reply
0 Kudos
deepakjangra023
Contributor
Contributor

Hi LucD,

there are files named as ctk.vmdk.

what are they and what is they are used for?

rgds,

Deepak

Reply
0 Kudos