I found the below useful script for finding orphaned vmdk files as seen below:
Purpose : List all orphaned vmdk on all datastores in all VC's
Version: 1.1
Author : HJA van Bokhoven
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.
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!!
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
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.
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
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!!
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
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).
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
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?
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
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?
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
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
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
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
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
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
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
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
Hi LucD,
there are files named as ctk.vmdk.
what are they and what is they are used for?
rgds,
Deepak