Empty folder size value should be set to zero

We use the following instruction to calculate a folder size

gci c:\my_folder | measure Length -sum

However, if the folder is empty, this instruction returns an error. This happens in PowerShell 5 to PowerShell 7. The error message is:

Measure-Object: Cannot process argument because the value of argument “Property” is not valid. Change the value of the “Property” argument and run the operation again.

IMO, Measure-Object’s behaviour is correct. So the culprit is the folder object returned by PowerShell. The size property of folder object should be set to zero by default.

How to make PowerShell developer take a look at this issue? Could someone file a report?

Thanks

I cannot reproduce this error with Get-ChildItem as it just returns null. Get-Item does return the error, however, in PowerShell Core. Since Length is a property of files, I’d consider this expected behavior. If you feel the need to report an issue, just go to Github and report it. Personally, I would just code for the condition:

if ($length = (Get-ChildItem 'c:\my_folder' | Measure Length -Sum -ErrorAction SilentlyContinue).Sum) {
    $length
} else {
    0
}

I don’t know why you can’t reproduce this error. I get it all the time. From Win 10 to Windows Server 2016 to 2019. All the time.

You said length is a property of file object. OK. But that doesn’t mean we can’t add this property to folder object.

Thanks for your code. I knew I could make a larger code to cope with this empty folder situation, but that makes the code very cumbersome. The advantage of using PowerShell is that we could use very compact code to do a lot of works. If we are forced to use cumbersome, better call the language InfirmityShell rather than PowerShell :grinning_face_with_smiling_eyes:

I’ve just filed on Github at https://github.com/PowerShell/PowerShell/issues/14449

It was not possible to paste image here so I couldn’t show you the error. But here’s the image:

just playing around, what you’re running into is gci is returning nothing when the folder is empty, thus there is nothing in the pipeline for the measure cmdlet to act upon.

get-childitem p|get-member

you’ll see “nothing” is returned, so you will need to handle the empty folders with a logical check as shown.

when there are items in your directory you will see all the data return

get-childitem c:\temp|get-member

otherwise, if you feel it should work differently, you need to submit a bug on the repo.

[quote quote=280503]just playing around, …
[/quote]

Well, you have not been playing enough… because…

[quote quote=280503]just playing around, what you’re running into is gci is returning nothing when the folder is empty, thus there is nothing in the pipeline for the measure cmdlet to act upon.

get-childitem p|get-member
[/quote]

That’s not true. The pipeline has an object, but the object has no property called length.

 

I have replied this point already to AdminOfThings45. There’s no point in repeating it.

<p style="text-align: left;">I knew I could make a larger code to cope with this empty folder situation, but that makes the code very cumbersome. The advantage of using PowerShell is that we could use very compact code to do a lot of works. If we are forced to use cumbersome, better call the language InfirmityShell rather than PowerShell</p>

Let me see if I can help. It looks like you have the following structure:

C:\temp\p\p

and this directory has nothing in it. Does this look correct?

PS C:\Users\micha\testfolder> gci p


    Directory: C:\Users\micha\testfolder\p


Mode                 LastWriteTime         Length Name                                                                                       
----                 -------------         ------ ----                                                                                       
d-----        12/18/2020   8:44 AM                p                                                                                          



PS C:\Users\micha\testfolder> gci .\p\p

PS C:\Users\micha\testfolder>

Assuming my test environment matches yours, I think I might understand the issue. When you run Get-ChildItem against a directory the default view (text returned to the screen) includes a column heading called “Length” but that property only applies to files and NOT directories, so if the directory you run Get-Childitem against only has directories and no files, that column heading will still be present but no values. To illustrate this I put a simple text file in the .\p directory.

PS C:\Users\micha\testfolder> gci p


    Directory: C:\Users\micha\testfolder\p


Mode                 LastWriteTime         Length Name                                                                                       
----                 -------------         ------ ----                                                                                       
d-----        12/18/2020   8:44 AM                p                                                                                          
-a----        12/18/2020   8:46 AM              5 Foo.txt                                                                                    

To further illustrate I’ll pipe the results to Get-Member. Notice there are two object types displayed in this result System.IO.FileInfo and System.IO.DirectoryInfo. The FileInfo object has a length property but the DirectoryInfo object does not.

PS C:\Users\micha\testfolder> gci p | Get-Member


   TypeName: System.IO.DirectoryInfo

Name                      MemberType     Definition                                                                                          
----                      ----------     ----------                                                                                          
LinkType                  CodeProperty   System.String LinkType{get=GetLinkType;}                                                            
Mode                      CodeProperty   System.String Mode{get=Mode;}                                                                       
Target                    CodeProperty   System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutr...
Create                    Method         void Create(), void Create(System.Security.AccessControl.DirectorySecurity directorySecurity)       
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)                                     
CreateSubdirectory        Method         System.IO.DirectoryInfo CreateSubdirectory(string path), System.IO.DirectoryInfo CreateSubdirecto...
Delete                    Method         void Delete(), void Delete(bool recursive)                                                          
EnumerateDirectories      Method         System.Collections.Generic.IEnumerable[System.IO.DirectoryInfo] EnumerateDirectories(), System.Co...
EnumerateFiles            Method         System.Collections.Generic.IEnumerable[System.IO.FileInfo] EnumerateFiles(), System.Collections.G...
EnumerateFileSystemInfos  Method         System.Collections.Generic.IEnumerable[System.IO.FileSystemInfo] EnumerateFileSystemInfos(), Syst...
Equals                    Method         bool Equals(System.Object obj)                                                                      
GetAccessControl          Method         System.Security.AccessControl.DirectorySecurity GetAccessControl(), System.Security.AccessControl...
GetDirectories            Method         System.IO.DirectoryInfo[] GetDirectories(), System.IO.DirectoryInfo[] GetDirectories(string searc...
GetFiles                  Method         System.IO.FileInfo[] GetFiles(string searchPattern), System.IO.FileInfo[] GetFiles(string searchP...
GetFileSystemInfos        Method         System.IO.FileSystemInfo[] GetFileSystemInfos(string searchPattern), System.IO.FileSystemInfo[] G...
GetHashCode               Method         int GetHashCode()                                                                                   
GetLifetimeService        Method         System.Object GetLifetimeService()                                                                  
GetObjectData             Method         void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serializat...
GetType                   Method         type GetType()                                                                                      
InitializeLifetimeService Method         System.Object InitializeLifetimeService()                                                           
MoveTo                    Method         void MoveTo(string destDirName)                                                                     
Refresh                   Method         void Refresh()                                                                                      
SetAccessControl          Method         void SetAccessControl(System.Security.AccessControl.DirectorySecurity directorySecurity)            
ToString                  Method         string ToString()                                                                                   
PSChildName               NoteProperty   string PSChildName=p                                                                                
PSDrive                   NoteProperty   PSDriveInfo PSDrive=C                                                                               
PSIsContainer             NoteProperty   bool PSIsContainer=True                                                                             
PSParentPath              NoteProperty   string PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\micha\testfolder\p               
PSPath                    NoteProperty   string PSPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\micha\testfolder\p\p                   
PSProvider                NoteProperty   ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem                                        
Attributes                Property       System.IO.FileAttributes Attributes {get;set;}                                                      
CreationTime              Property       datetime CreationTime {get;set;}                                                                    
CreationTimeUtc           Property       datetime CreationTimeUtc {get;set;}                                                                 
Exists                    Property       bool Exists {get;}                                                                                  
Extension                 Property       string Extension {get;}                                                                             
FullName                  Property       string FullName {get;}                                                                              
LastAccessTime            Property       datetime LastAccessTime {get;set;}                                                                  
LastAccessTimeUtc         Property       datetime LastAccessTimeUtc {get;set;}                                                               
LastWriteTime             Property       datetime LastWriteTime {get;set;}                                                                   
LastWriteTimeUtc          Property       datetime LastWriteTimeUtc {get;set;}                                                                
Name                      Property       string Name {get;}                                                                                  
Parent                    Property       System.IO.DirectoryInfo Parent {get;}                                                               
Root                      Property       System.IO.DirectoryInfo Root {get;}                                                                 
BaseName                  ScriptProperty System.Object BaseName {get=$this.Name;}                                                            


   TypeName: System.IO.FileInfo

Name                      MemberType     Definition                                                                                          
----                      ----------     ----------                                                                                          
LinkType                  CodeProperty   System.String LinkType{get=GetLinkType;}                                                            
Mode                      CodeProperty   System.String Mode{get=Mode;}                                                                       
Target                    CodeProperty   System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutr...
AppendText                Method         System.IO.StreamWriter AppendText()                                                                 
CopyTo                    Method         System.IO.FileInfo CopyTo(string destFileName), System.IO.FileInfo CopyTo(string destFileName, bo...
Create                    Method         System.IO.FileStream Create()                                                                       
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)                                     
CreateText                Method         System.IO.StreamWriter CreateText()                                                                 
Decrypt                   Method         void Decrypt()                                                                                      
Delete                    Method         void Delete()                                                                                       
Encrypt                   Method         void Encrypt()                                                                                      
Equals                    Method         bool Equals(System.Object obj)                                                                      
GetAccessControl          Method         System.Security.AccessControl.FileSecurity GetAccessControl(), System.Security.AccessControl.File...
GetHashCode               Method         int GetHashCode()                                                                                   
GetLifetimeService        Method         System.Object GetLifetimeService()                                                                  
GetObjectData             Method         void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serializat...
GetType                   Method         type GetType()                                                                                      
InitializeLifetimeService Method         System.Object InitializeLifetimeService()                                                           
MoveTo                    Method         void MoveTo(string destFileName)                                                                    
Open                      Method         System.IO.FileStream Open(System.IO.FileMode mode), System.IO.FileStream Open(System.IO.FileMode ...
OpenRead                  Method         System.IO.FileStream OpenRead()                                                                     
OpenText                  Method         System.IO.StreamReader OpenText()                                                                   
OpenWrite                 Method         System.IO.FileStream OpenWrite()                                                                    
Refresh                   Method         void Refresh()                                                                                      
Replace                   Method         System.IO.FileInfo Replace(string destinationFileName, string destinationBackupFileName), System....
SetAccessControl          Method         void SetAccessControl(System.Security.AccessControl.FileSecurity fileSecurity)                      
ToString                  Method         string ToString()                                                                                   
PSChildName               NoteProperty   string PSChildName=Foo.txt                                                                          
PSDrive                   NoteProperty   PSDriveInfo PSDrive=C                                                                               
PSIsContainer             NoteProperty   bool PSIsContainer=False                                                                            
PSParentPath              NoteProperty   string PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\micha\testfolder\p               
PSPath                    NoteProperty   string PSPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\micha\testfolder\p\Foo.txt             
PSProvider                NoteProperty   ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem                                        
Attributes                Property       System.IO.FileAttributes Attributes {get;set;}                                                      
CreationTime              Property       datetime CreationTime {get;set;}                                                                    
CreationTimeUtc           Property       datetime CreationTimeUtc {get;set;}                                                                 
Directory                 Property       System.IO.DirectoryInfo Directory {get;}                                                            
DirectoryName             Property       string DirectoryName {get;}                                                                         
Exists                    Property       bool Exists {get;}                                                                                  
Extension                 Property       string Extension {get;}                                                                             
FullName                  Property       string FullName {get;}                                                                              
IsReadOnly                Property       bool IsReadOnly {get;set;}                                                                          
LastAccessTime            Property       datetime LastAccessTime {get;set;}                                                                  
LastAccessTimeUtc         Property       datetime LastAccessTimeUtc {get;set;}                                                               
LastWriteTime             Property       datetime LastWriteTime {get;set;}                                                                   
LastWriteTimeUtc          Property       datetime LastWriteTimeUtc {get;set;}                                                                
Length                    Property       long Length {get;}                                                                                  
Name                      Property       string Name {get;}                                                                                  
BaseName                  ScriptProperty System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Remove($this.Name.Length...
VersionInfo               ScriptProperty System.Object VersionInfo {get=[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullNam...

Note length is the size of the file. If you’d like to view the sum of size of the files contained in a directory, I can help with that, but windows does not calculate a size (length) for a directory. This is a Windows thing NOT a PowerShell thing.

https://docs.microsoft.com/en-us/dotnet/api/system.io.fileinfo.length?view=net-5.0