Home > Software engineering >  PowerShell is not returning correct value when using Measure-Object to find a size of a Directory
PowerShell is not returning correct value when using Measure-Object to find a size of a Directory

Time:11-11

enter image description hereI have a bunch of folders sitting out on a couple of servers. I'm trying to clean them up to free up disk space. I'm trying to find directories that haven't been touched in 7 years or more. Since the folder structure is set up a certain way, I want to display folders by Name, Size, and Last Write Time. So far I have this code.

Get-ChildItem -Path $HDriveServer1 -Depth 1 -Directory -Force | Where-Object { $_.LastWriteTime -le (Get-Date).AddYears(-7)} | Select-Object Name,@{Name='Size';Exp={(Get-ChildItem -Recurse -File -Force | Measure-Object -Property Length -Sum).Sum / 1MB}},LastWriteTime | Out-File $report

The name and last time written seem to output correctly, however the size all show the same values. This is the output I am seeing and can't figure out why the size is the same.

Any ideas? Thanks!

Output of code

CodePudding user response:

As AdminOfThings points out, the Get-ChildItem call nested in your calculated property (@{Name=...}) lacks an input path and therefore operates on the current directory rather than the one specified by the pipeline input object.

The robust way to provide this input directory, which is reflected in the automatic $_ variable, to the nested Get-ChildItem call via the pipeline:

Get-ChildItem -Path $HDriveServer1 -Depth 1 -Directory -Force | 
  Where-Object { $_.LastWriteTime -le (Get-Date).AddYears(-7)} | 
    Select-Object Name,
                  @{
                    Name = 'Size'
                    Expression = {
                      ($_ | Get-ChildItem -Recurse -File -Force | Measure-Object -Property Length -Sum).Sum / 1MB
                    }
                  },
                  LastWriteTime |
     Out-File $report

While you would expect Get-ChildItem -LiteralPath $_ to be equivalent to
$_ | Get-ChildItem, in Windows PowerShell it situationally isn't, because $_ is stringified as an argument, and sometimes stringifies to its file name only, not the full path.

An alternative is to use Get-ChildItem -LiteralPath $_.FullName.

This problem has been corrected in PowerShell (Core) 7 .

See this answer for more information.

  • Related