I have looked in multiple locations, however aren't finding what I need. Many scripts will only report on clusters, or will also register the found VMDK files, which is what I don't want.
I would love (as I'm sure others would) to have a report in a .csv format that will scan my ESX 3.5 update 4 servers in my VC 2.5 update 4, and report any .VMDK files that aren't registered in VC.
We have iSCSI, storage as well as local storage being used on each server.
I have searched high and low for something, yet I can't seem to find anything that works.
thanks in advance.
I started from the script in and made some, in my opinion, improvements.
*) used the disk layout from the VirtualMachine objects since this contains all the .VMDK files
*) included the .VMDK files from templates
*) optimised the search method by only looking for .VMDK files
*) changed the logic to determine if the .VMDK file is orphaned or not
*) exported the results to a CSV file
# # Purpose : List all orphaned vmdk on all datastores in all VC's # Version: 1.1 # Author : HJA van Bokhoven # Modifications: LucD $arrayVC = <VC1-name>, <VC2-name> $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 = "" $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 } } } } } # Disconnect session from VC disconnect-viserver -confirm:$false } $report | Export-Csv "C:\VMDK-orphaned.csv" -noTypeInformation
Please check if the files that are found by this script are indeed orphaned before deleting them !
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks so much, the report seems correct, however my only issue is that the ESX server name isn't listed. So for the orphaned .vmdk files that sit on local storage, it's hard to locate what server they are actually on.
Is there anyway that the ESX server could be one of the columns?
thanks so much
Sure, this should do the trick.
Note that if a datastore is shared between multiple ESX hosts you will see the name of the first ESX host in the CSV file.
# # Purpose : List all orphaned vmdk on all datastores in all VC's # Version: 1.1 # Author : HJA van Bokhoven # Modifications: LucD $arrayVC = <VC1>,<VC2> $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 = "" $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
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome, thanks so much
Any ideas why I get this error?
Exception calling "SearchDatastoreSubFolders" with "2" argument(s): "Invalid datastore path ''."
At 30 char:55
+ $searchResult = $dsBrowser.SearchDatastoreSubFolders <<<< ($rootPath, $searchSpec)
+ CategoryInfo : NotSpecified: ( [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Did you copy the script from your browser or did you use the attached file ?
The $rootPath variable contains some square brackets and the forum SW has problems with displaying those correctly.
Try the attached script.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
Unfortunately that didn't work. Same error.
ta.
HAHA yes it did fix it... stupid me, updated the script in a different folder to where my PS window was running it from.
thanks LucD.
Hi, Thanks for the Script. Unfortunately I cannot get it to work. I downloaded the attached script and all I did was modify the arrayvc line to look like this: $arrayVC = "vcentersrvr"
I keep getting this error:
Exception calling "SearchDatastoreSubFolders" with "2" argument(s): "Not initia
lized: boolean fileOwner"
At C:\Get-orphaned-VMDK.ps1:29 char:55
+ $searchResult = $dsBrowser.SearchDatastoreSubFolders <<<< ($rootPath,
$searchSpec)
+ CategoryInfo : NotSpecified: ( [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any thoughts? I am using vSphere 4. Thanks very much.
Mike
The $arrayVC variable should be an array.
And if you want to create an array with only 1 element you should do
$arrayVC = @("vcentersrvr")
Try the script with that adaptation.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
hmmm ...... I made the modification you suggested and I still get the exact same errors. I see that the script conncects to my VC and then begins pulling all the datastores, but the error is being displayed everytime DS is displayed on the screen. Any further thoughts? Thanks for the help. I'm very rusty in powershell.
Mike
You're right, should have read your error message more accurately.
It seems that the FileQueryFlags object in vSphere has a new property called fileOwner.
This is a Boolean that needs to be set to $false or $true.
So these lines
... $fileQueryFlags = New-Object VMware.Vim.FileQueryFlags $fileQueryFlags.FileSize = $true $fileQueryFlags.FileType = $true $fileQueryFlags.Modification = $true ...
should be
... $fileQueryFlags = New-Object VMware.Vim.FileQueryFlags $fileQueryFlags.fileOwner = $true # Only for vSphere environments ! $fileQueryFlags.FileSize = $true $fileQueryFlags.FileType = $true $fileQueryFlags.Modification = $true ...
when you run the script in a vSphere environment.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Sadly no luck. I copied your new lines and pasted them over the existing lines .... same error:
CX400_500GB_DS4
Exception calling "SearchDatastoreSubFolders" with "2" argument(s): "Not initia
lized: boolean fileOwner"
At C:\Get-orphaned-VMDK.ps1:30 char:55
+ $searchResult = $dsBrowser.SearchDatastoreSubFolders( <<<< $rootPath,
$searchSpec)
Thanks very much for the help!
There's something fishy going on
I could reproduce the problem with PowerCLI 4 in a vSphere environment.
@VMware Could this be a bug ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Carter confirms this is a bug, although it's not clear if it's a PowerCLI or a API bug.
The bypass is to leave out the details property completely.
In this script the details of the files (.vmdk) that are returned are not used in the script.
Attached a "vSphere" version of the script (with the "details" property left out).
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The script runs without any runtime errors now and the output of the CSV file looks awesome. I could definitely see a use to schedule this once a Month as part of my health scripts, but sadly, there is still a couple of problems. All of the vmdk files show 0 in size and a ModDate of 1/1/0001 12:00:00 AM.
I appreciate you help very much and I hate to bother you more, but is there any chance you can dig a little deeper to resolve that issue?
Thanks very much.
Hi,
All of the vmdk files show 0 in size and a ModDate of 1/1/0001 12:00:00 AM.
This is caused by the the bypass of the details property completely.
I've modified the script to workaround the bug LucD mentioned so I hope this will solve your task.
Regards,
Yasen
Thanks Yasen.
Where can we find more info on \[VMware.Vim.VIConvert\] ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome. Thank you both very much! It seems to work perfectly now. This will be very handy indeed.