ganapa2000
Enthusiast
Enthusiast

Group-Object : You cannot call a method on a null-valued expression.

Jump to solution

Hi,

I am getting the below error, while I execute the below script for getting the orphaned disks info

Please help

Group-Object : You cannot call a method on a null-valued expression.
At D:\orphaned_vmdk.ps1:191 char:76
+ ... VmwOrphan | Group-Object -Property {$_.Folder.Split(']')[0].TrimStart ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidResult: (@{Datastore=FAS...e=; HWVersion=}:PSObject) [Group-Object], RuntimeException
+ FullyQualifiedErrorId : ExpressionEvaluation,Microsoft.PowerShell.Commands.GroupObjectCommand

 

function Get-VmwOrphan{

[CmdletBinding(SupportsShouldProcess=$True)]
param(
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[PSObject[]]$Datastore,
[String[]]$ExcludeFolder,
[Switch]$Delete
)

Begin{
$flags = New-Object VMware.Vim.FileQueryFlags
$flags.FileOwner = $true
$flags.FileSize = $true
$flags.FileType = $true
$flags.Modification = $true

$qFloppy = New-Object VMware.Vim.FloppyImageFileQuery
$qFolder = New-Object VMware.Vim.FolderFileQuery
$qISO = New-Object VMware.Vim.IsoImageFileQuery
$qConfig = New-Object VMware.Vim.VmConfigFileQuery
$qConfig.Details = New-Object VMware.Vim.VmConfigFileQueryFlags
$qConfig.Details.ConfigVersion = $true
$qTemplate = New-Object VMware.Vim.TemplateConfigFileQuery
$qTemplate.Details = New-Object VMware.Vim.VmConfigFileQueryFlags
$qTemplate.Details.ConfigVersion = $true
$qDisk = New-Object VMware.Vim.VmDiskFileQuery
$qDisk.Details = New-Object VMware.Vim.VmDiskFileQueryFlags
$qDisk.Details.CapacityKB = $true
$qDisk.Details.DiskExtents = $true
$qDisk.Details.DiskType = $true
$qDisk.Details.HardwareVersion = $true
$qDisk.Details.Thin = $true
$qLog = New-Object VMware.Vim.VmLogFileQuery
$qRAM = New-Object VMware.Vim.VmNvramFileQuery
$qSnap = New-Object VMware.Vim.VmSnapshotFileQuery

$searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$searchSpec.details = $flags
$searchSpec.Query = $qFloppy,$qFolder,$qISO,$qConfig,$qTemplate,$qDisk,$qLog,$qRAM,$qSnap
$searchSpec.sortFoldersFirst = $true

$fileMgr = Get-View FileManager
$excludeFilter = $ExcludeFolder -join '|'
}

Process{
foreach($ds in $Datastore){
if($ds.GetType().Name -eq "String"){
$ds = Get-Datastore -Name $ds
}

# Only shared VMFS datastore
if($ds.Type -eq "VMFS" -and $ds.Accessible){
Write-Verbose -Message "$(Get-Date)`t$((Get-PSCallStack)[0].Command)`tLooking at $($ds.Name)"

# Define file DB
$fileTab = @{}

# Get datastore files
$dsBrowser = Get-View -Id $ds.ExtensionData.browser
$rootPath = "[" + $ds.Name + "]"
$searchResult = $dsBrowser.SearchDatastoreSubFolders($rootPath, $searchSpec) | Sort-Object -Property {$_.FolderPath.Length}
foreach($folder in $searchResult){
foreach ($file in $folder.File){
$filler = ''
if($folder.FolderPath[-1] -eq ']'){$filler = ' '}
elseif($folder.FolderPath[-1] -ne '/'){$filler = '/'}
$key = "$($folder.FolderPath)$filler$($file.Path)"
#if($key -notmatch $excludeFilter){
if($excludeFilter -eq '' -or ($excludeFilter -ne '' -and $key -notmatch $excludeFilter)){
$fileTab.Add($key,$file)

$folderKey = "$($folder.FolderPath.TrimEnd('/'))"
if($fileTab.ContainsKey($folderKey)){
$fileTab.Remove($folderKey)
}
}
else{
Write-Verbose -Message "$(Get-Date)`t$((Get-PSCallStack)[0].Command)`tExcluding $key"
}
}
}

# Get VM inventory
Get-VM -Datastore $ds | %{
$_.ExtensionData.LayoutEx.File | %{
if($fileTab.ContainsKey($_.Name)){
$fileTab.Remove($_.Name)
}
}
}

# Get Template inventory
Get-Template | where {$_.DatastoreIdList -contains $ds.Id} | %{
$_.ExtensionData.LayoutEx.File | %{
if($fileTab.ContainsKey($_.Name)){
$fileTab.Remove($_.Name)
}
}
if($fileTab.ContainsKey($_.ExtensionData.Config.Files.VmPathName)){
$fileTab.Remove($_.ExtensionData.Config.Files.VmPathName)
}
}

# Remove system files & folders from list
$systemFiles = $fileTab.Keys | where{$_ -match "] \.|vmkdump"}
$systemFiles | %{
$fileTab.Remove($_)
}

# Organise remaining files
if($fileTab.Count){
$fileTab.GetEnumerator() | %{
$obj = [ordered]@{
Datastore = $ds.Name
Name = $_.Value.Path
Path = $_.Name
Size = $_.Value.FileSize
CapacityKB = $_.Value.CapacityKb
CapacityGB = $_.Value.FileSize/1024/1024
Modification = $_.Value.Modification
Owner = $_.Value.Owner
Thin = $_.Value.Thin
Extents = $_.Value.DiskExtents -join ','
DiskType = $_.Value.DiskType
HWVersion = $_.Value.HardwareVersion
}
New-Object PSObject -Property $obj
if($Delete){
If ($PSCmdlet.ShouldProcess($_.Name,"Remove Folder/File")){
$fileMgr.DeleteDatastoreFile($_.Name,$ds.Datacenter.ExtensionData.MoRef)
}
}
}
Write-Verbose -Message "$(Get-Date)`t$((Get-PSCallStack)[0].Command)`tFound orphaned files on $($ds.Name)!"
}
else{
Write-Verbose -Message "$(Get-Date)`t$((Get-PSCallStack)[0].Command)`tNo orphaned files found on $($ds.Name)."
}
}
}
}
}

$reportlocation = ".\Orphaned_VMDKs.xlsx"
foreach($ds in (Get-Cluster -Name MyClus | Get-Datastore | Get-VmwOrphan | Group-Object -Property {$_.Folder.Split(']')[0].TrimStart('[')})){
$ds.Group | Export-Excel -Path $reportlocation -WorkSheetname $ds.Name -AutoSize -AutoFilter -FreezeTopRow -verbose
}

 

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

The objects returned by Get-VmwOrphan do not contain a property Folder, hence the error.

If I interpret correctly what you are trying to do, the code at the end should be

$reportlocation = ".\Orphaned_VMDKs.xlsx"
    
Get-Cluster -Name MyClus | Get-Datastore | Get-VmwOrphan |
Group-Object -Property Datastore -PipelineVariable group |
ForEach-Object -Process {
        Export-Excel -InputObject $group.Group -Path $reportlocation -WorksheetName $group.Name -AutoSize -AutoFilter -FreezeTopRow -Verbose
}
    


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

View solution in original post

0 Kudos
2 Replies
LucD
Leadership
Leadership

The objects returned by Get-VmwOrphan do not contain a property Folder, hence the error.

If I interpret correctly what you are trying to do, the code at the end should be

$reportlocation = ".\Orphaned_VMDKs.xlsx"
    
Get-Cluster -Name MyClus | Get-Datastore | Get-VmwOrphan |
Group-Object -Property Datastore -PipelineVariable group |
ForEach-Object -Process {
        Export-Excel -InputObject $group.Group -Path $reportlocation -WorksheetName $group.Name -AutoSize -AutoFilter -FreezeTopRow -Verbose
}
    


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

View solution in original post

0 Kudos
ganapa2000
Enthusiast
Enthusiast

oh ok, got it.

Thank you LucD, that worked.

0 Kudos