2

I am using Powershell and I am trying to compare the free space of a drive to the size of files I want to put onto the drive, but it doesn't seem to like the comparison and I get the error below. I'm wondering if the name preceding each value is causing the issue. If this is the case, is there a way to properly compare these values while retaining the name, or would I have to store the named values as a separate variable?

Cannot compare "@{Zipped Space (GB)=65.6897087870166}" to "@{Free Space (GB)=-19.7659684484825}" because the objects are not the
same type or the object "@{Zipped Space (GB)=65.6897087870166}" does not implement "IComparable".
At G:\ManuallyCopyFiles.ps1:31 char:8
+ while ($zippedSize -gt $freeSpace)
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
    + FullyQualifiedErrorId : PSObjectCompareTo

$freeSpace = (Get-ChildItem -Path "\\filler\C$\Users\filler\blah\" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Free Space (GB)";Expression={465-$_.Sum/1gb}})

$zippedSize = (Get-ChildItem -Path $dest -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Zipped Space (GB)";Expression={0+$_.Sum/1gb}})

#Checks to see if there is enough space for the zipped files; if not, it deletes the oldest folder until there is enough space.

while ($zippedSize -gt $freeSpace)
{
    Get-ChildItem $remotePath | Sort CreationTime | Select -First 1 | Remove-Item

    $freeSpace = (Get-ChildItem -Path "\\filler\C$\Users\filler\blah\" -Recurse -Force -ErrorAction SilentlyContinue |
    Measure-Object -Property Length -Sum |
    Select-Object @{Name="Free Space (GB)";Expression={465-$_.Sum/1gb}})
}
Zalkar
  • 21
  • 3
  • 3
    Seems like you need `$zippedSize.'Zipped Space (GB)' -gt $freeSpace.'Free Space (GB)'` since those properties have the values you want to compare. – AdminOfThings Aug 11 '21 at 14:45

2 Answers2

1

AdminOfThings correctly points out that you need to access the properties on the (single-property custom) objects you're creating in order to compare the numbers of interest; to quote from his comment: $zippedSize.'Zipped Space (GB)' -gt $freeSpace.'Free Space (GB)'

Without that, you're trying to compare two objects of type [pscustomobject], which aren't comparable[1], resulting in the error you're seeing; a simple repro of the error condition:

# FAILS, because two [pscustomobject] instances cannot be compared with 
#    -gt / -ge / -lt / -le
# (and not meaningfully with -eq / -ne, which doesn't fail, but tests
#  *reference equality*, i.e. only if the operands are the *very same instance*).
[pscustomobject] @{ foo = 1 } -gt [pscustomobject] @{ foo = 2 }

Generally, to make Select-String output just a value, you must use the -ExpandProperty parameter, even if you're only selecting one property - see this answer.

However, in your case, where you're creating a calculated property, it seems that you don't need an intermediate object at all and therefore don't need Select-Object- just use an expression to calculate the values (numbers) of interest:

$freeSpace = 465 - (Get-ChildItem -Path "\\filler\C$\Users\filler\blah" -Recurse -Force -ErrorAction SilentlyContinue |
                      Measure-Object -Property Length -Sum).Sum / 1gb

$zippedSize = (Get-ChildItem -Path $dest -Recurse -Force -ErrorAction SilentlyContinue |
                Measure-Object -Property Length -Sum).Sum / 1gb

[1] For an object to be comparable to other objects of the same or, thanks to PowerShell's automatic type conversions, compatible types, its type must implement the System.IComparable or interface or its generic equivalent, System.IComparable<T>. Both interfaces have just one method, named Convert, which indicates whether the two objects being compared are equal or a less-than or greater-than relationship.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Since you're not really dealing with Zipped files the variable names are misleading to say the least (Get-ChildItem can not read the contents of zipped files).

You may want something more like this:

$Src = '\\ComputerMentor2\CMShared\NAS-Downloads\'
$Files = Get-ChildItem -LiteralPath $Src -File -Recurse
$Size = 0
ForEach ($File in $Files) { $Size += $File.Length}

"There were $($Files.Count) files found.`nConsisting of $Size bytes"

Sample Output:

There were 70 files found.
Consisting of 2819056460 bytes

This will give you a byte count which you can then convert to any other measurement you wish.

Since you are trying to see if the files will fit on a drive you may want to round the individual file sizes up to the nearest sector boundary since that is the space they will consume on the drive when actually copied.

Dharman
  • 30,962
  • 25
  • 85
  • 135
RetiredGeek
  • 2,980
  • 1
  • 7
  • 21