Hi,
I am getting the below error, when I try to execute the below script, please help
Error:
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: values"
At D:\myreports\list_orphaned_vmdk.ps1:90 char:1
+ New-Object PSObject -Property @{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: values"
At D:\myreports\list_orphaned_vmdk.ps1:90 char:1
+ New-Object PSObject -Property @{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
Script:
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.capacityGB = $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
CapacityGB = $file.CapacityKb/1024/1024
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
CapacityGB = $_.CapacityKB/1024/1024
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)
}
}
}
}
}
}
}
}
}
connect-viserver 10.10.10.10
Remove-OrphanedData -Datastore DS01
What type of datastore is that? VMFS, NFS...?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
its all VMFS
Looks like there might be a VMDK with an extent.
Let's try to find out what kind of file that is.
Can you add a Write-Host on line 90?
$folder.File | % {
Write-Host "Path: $($_.Path)" # Add this line
New-Object PSObject -Property @{
Folder = $folder.FolderPath
Name = $_.Path
Size = $_.FileSize
CapacityGB = $_.CapacityKB / 1024 / 1024
Thin = $_.Thin
Extents = [String]::Join(',', ($_.DiskExtents))
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Below the output after adding the requested line
Path: system.vmdk
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: values"
At D:\myreports\list_orphaned_vmdk.ps1:90 char:1
+ New-Object PSObject -Property @{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
Path: system.vmdk
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: values"
At D:\myreports\list_orphaned_vmdk.ps1:90 char:1
+ New-Object PSObject -Property @{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
Path: CentOS7.0_x86_64.vmdk
Path: system.vmdk
Extents Name Thin CapacityGB Folder Size
------- ---- ---- ---------- ------ ----
[VNX5200_DS01] CentOS7.0_x86_64/CentOS7.0_x86_64-flat.vmdk CentOS7.0_x86_64.vmdk False 20 [VNX5200_DS01] CentOS7.0_x86_64/ 21474836480
[VNX5200_DS01] ISO/SQL-ISO/New Folder/system-flat.vmdk system.vmdk False 8 [VNX5200_DS01] ISO/SQL-ISO/New Folder/ 8589934592
Do you know what this system.vmdk file might be?
How does it show in the datastore file browser?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Here is the screenshot from Datastore File Browser
Still not understand why a VMDK can have no disk extents.
I'll have to investigate.
As a fix, try replacing that part of the code with
Folder = $folder.FolderPath
Name = $_.Path
Size = $_.FileSize
CapacityGB = $_.CapacityKB / 1024 / 1024
Thin = $_.Thin
Extents = & {
if ($_.DiskExtents) {
[String]::Join(',', ($_.DiskExtents))
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
That worked without any error, but extents shows blank
Output
by the way, how can I execute this script for all the datastores in vCenter ?
The function accepts pipeline parameters, so you can do
Yes, I know, that's the effect of the bypass.
I'm still trying to figure out why a VMDK can have no extents.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference