Over time we can make many files and folders on our system and different applications can produce even more so it is very important to have an overview of the folders and the files numbers, sizes, and handling so we can avoid that our system has been overloaded.
We want to use Get-ChildItem and Measure-Object PowerShell CmdLets to get the folder size and count files and subfolders in it.
- Get-ChildItem CmdLet gets the files and folders from the system but can also read Windows Registry and has aliases:
- gci
- dir
- ls
- Measure-Object CmdLet does the mathematics calculations for us such as:
- Sum,
- Average,
- Maximum,
- Minimum,
- Standard deviation,
- Count the number of items,
- Even all stats at once.
In addition, to connect remotely to servers and get the folder size on the remote servers we will use Invoke-Command PowerShell CmdLet which I will explain shortly.
In this article, we will see many different PowerShell examples that will give us information about the folder size on our system both locally and on remote servers.
Table of Contents
How To Get Folder Size And File Count On The Local Machine Using PowerShell
To get the folder size and count of items (subfolders and files) within the specified folder we will use the following PowerShell CmdLets: Get-ChildItem, Measure-Object, and Select-Object.
Here is the example that will be explained afterwards in more details.
Get-ChildItem -Path "C:\Temp" -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object Sum, Count
Here is the result of the above example call.
Sum value is in bytes and it is the same if we look at folder properties using Windows Explorer as you can see on the screenshot below.
Get-ChildItem PowerShell CmdLet will look for all the subfolders and files using the following parameters:
- Path parameter points to the folder for which we want to get data.
- Recurse parameter tells PowerShell to include subfolders and files in the specified folder for the Path parameter.
- Force parameter tells PowerShell to include hidden and system files as well if they exist.
- ErrorAction with the value SilentlyContinue will continue if for whatever reason we cannot read some file or folder, maybe due to lack of permissions or file is locked by some process, etc.
Measure-Object PowerShell CmdLet will do the math for us and calculate the size of folder and how many items (folders and files) are in it using the following parameters:
- Property parameter defines which property we want to do the calculation for. In this case that is the Length property which is the size of the file in bytes.
- Sum switch parameter defines the sum-up of the property chosen in the previous parameter. Basically, this is a mathematical operation applied to the size of each file in order to get a folder size.
NOTE: Different versions of windows have different calculations for the value of “Size on disk” as you can read in this article explained.
How To Get Folder Size And File Count On The Remote Machine Using PowerShell
In order to get Folder Size and Files or Folders count on remote machines, we need to fulfill some prerequisites so let’s get them away first.
Remote Machine Connection – Prerequisites
First, we need to enable remoting on all computers that we want to connect remotely since we will use Invoke-Command PowerShell CmdLet. Enabling remoting is out of the scope of this article but I will mention some tricks I have implemented on my stand-alone installation.
Second, we will keep the encrypted credential’s password in an external file which I will show you how to make in a bit.
Example – Explained
In order to get Folder Size and Files or Folders count on remote machines, we have used several PowerShell CmdLets Invoke-Command, New-Object, Get-Content, ConvertTo-SecureString, Get-ChildItem, Measure-Object, and Select-Object.
We can see the example but I hope that the below explanation is useful especially for new PowerShell scripters.
$computer = 'LAPTOP-0U37BBBD'
$path = "C:\Temp"
$scriptblock = { param ($parampath) Get-ChildItem -Path $parampath -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(MB)";Expression={("{0:N2}" -f($_.Sum/1mb))}}, Count }
$EncryptedPasswordFile = "C:\Users\user_name\Documents\PSCredential\Invoke-Command.txt"
$username="user_name"
$password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$Credentials = New-Object System.Management.Automation.PSCredential($username, $password)
$params = @{ 'ComputerName'=$computer;
'ScriptBlock'=$scriptblock;
'Credential'=$Credentials;
'ArgumentList'=$path }
$foldersize = Invoke-Command @params
$foldersize
Here is the result of above example code:
So let me explain to you all the CmdLets and parameters used and why. To remotely connect to servers we will use Invoke-Command CmdLet with the following parameters:
- The ComputerName parameter is the name of the computer that we are connecting remotely to.
- The ScriptBlock parameter is the brain and holds all the commands that will run and return Folder size and Items count.
- The Credential parameter holds the user name and password and we will explain in a bit how to keep the password encrypted in an external file.
- The ArgumentList parameter holds all the input parameters for the ScriptBlock parameter
Credentials are very important in making the connection to the remote computer. We create a separate credential object using New-Object CmdLet and System.Management.Automation.PSCredential.
We need first to save our password in encrypted file using the the following code:
Read-Host -AsSecureString | ConvertFrom-SecureString |
Out-File -FilePath "C:\Users\dekib\Documents\PSCredential\Invoke-Command.txt"
Here is the screenshot with dialog to type a password.
Now, whenever we need a user name and password for a credential we have our password encrypted and saved externally. We can reuse saved password as I have shown in the example above using Get-Content and ConvertTo-SecureString CmdLets.
$EncryptedPasswordFile = "C:\Users\user_name\Documents\PSCredential\Invoke-Command.txt"
$username="user_name"
$password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$Credentials = New-Object System.Management.Automation.PSCredential($username, $password)
INFO: I have stand-alone enabled Remoting. That means everything that I show is on the same computer. For that reason, I have used this approach of keeping my credentials. You have to find out which solution is right for your environment.
Let’s now focus on the Script Block variable which has all the PowerShell CmdLets that will actually calculate and present to us Folder Size and Items count. Within the script block, we use three PowerShell CmdLets Get-ChildItem, Measure-Object, and Select-Object.
NOTE: In the script block we have used a param PowerShell keyword that is used to pass the path to the folder externally using the ArgumentList parameter of Invoke-Command CmdLet.
Get-ChildItem CmdLet is used to list all the folders, files, and subfolders of the specified folder in the Path parameter and the following parameters used:
- The Path parameter points to the folder in which we want to get data.
- The Recurse parameter tells PowerShell to include subfolders and files in the subfolders.
- The Force parameter tells PowerShell to include hidden and system files or folders if they exist.
- The ErrorAction parameter with a value SilentlyContinue will continue if for whatever reason we cannot read some file, maybe due to lack of permissions or file is locked by some process, etc. This can happen even with administrator privileges.
Measure-Object CmdLet is used to calculate Folder size and count the number of items (files and folders) in the specified folder using the following parameters:
- The Property specifies the property used to do the calculation. In this case, we will use the Length property which is nothing but the file size in bytes
- The Sum switch parameter tells PowerShell which mathematical operation to use and since we want the size of the folder then the sum is the correct one.
Select-Object CmdLet is used to present the result and convert bytes into megabytes for the folder size.
- Name changes the result column name from Sum into Size(MB) so it is more appropriate and has a better description.
- Expression divides values in bytes with one megabyte (1mb) so we can get the result in megabytes instead of bytes. In addition, we format (-f) the result using Expression {0:N2} in order to get the result with two decimal places.
- Count property returns a number of items (subfolders and files) within the specified folder in the Path parameter.
REMEMBER: I have used a stand-alone enabled remoting environment (remoting on the single computer) and if I do not provide the correct credentials remoting will return the error like on the screenshot below. Configuring PowerShell Remoting can be sometimes very tricky so be patient
INFO: If you want to learn more about how to convert string to script block please read the article “How To Convert String To Script Block Using PowerShell” where I have explained the whole concept in more detail.
How To Get Folder Size In Kilo, Mega, Gigabytes Using PowerShell
Let’s how to get folder size in different sizes and finally all of them together side by side.
How To Get Folder Size In Kilobytes Using PowerShell
To get the folder size in kilobytes we will use Get-ChildItem, Measure-Object, and Select-Object PowerShell CmdLets by pipelining (“|”) the result from one to another.
Here is the example code that will return folder size in kilobytes [kB].
Get-ChildItem -Path "C:\Temp" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(KB)";Expression={$_.Sum/1kb}}
Here is the result of the folder size in kilobytes. Notice that the result has many decimal places so in the next example, we will format the result to get with just two decimal places.
Let me just quickly go through each of CmdLets and parameters used with it and why we have used them.
Get-ChildItem CmdLet will list the files and folders within the folder specified in the Path parameter (C:\Temp folder in this case).
- The Recurse parameter force the command to recursively go through each subfolder within a folder specified in the Path parameter.
- The Force parameter will read hidden and system files which would be skipped otherwise.
- The ErrorAction parameter with value SilentlyContinue tells the PowerShell engine just to move on if an error occurs. This is very useful since sometimes even with Administrator privileges some files can be locked or used by some process and our call would be stopped without giving us the result.
Measure-Object CmdLet will do the math for us and sum up all the file sizes.
- The Property parameter tells PowerShell to read the value from the Length property of each object (file) send through the pipeline that is within the folder (C:\Temp).
- The Sum switch parameter will do the sum of all length values in all files within the folder (C:\Temp).
Select-Object CmdLet is used to present the result and convert bytes into kilobytes for the folder size.
- Name changes the result column name from Sum into Size(kB) so it is more describable.
- Expression divides values in bytes with one kilobyte (1kB) so we can get the result in kilobytes instead of bytes.
In this example, we will just format our result to return with two decimal places only. For that, we will use in Expression -f for formatting and format pattern for two decimal places “{0:N2}”.
Get-ChildItem -Path "C:\Temp" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(KB)";Expression={("{0:N2}" -f($_.Sum/1kb))}}
Here we can see the same result but little bit better formatted with just two decimal places.
REMEMBER: In this example, we have used PowerShell Pipeline extensively and it is a very important concept. I highly encourage you to read my article PowerShell Pipeline Concept Explained With Awesome Examples with many examples that will explain in detail PowerShell Pipelining.
How To Get Folder Size In Megabytes Using PowerShell
To get the folder size in megabytes we will use Get-ChildItem, Measure-Object, and Select-Object PowerShell CmdLets by pipelining (“|”) the result from one to another.
Here is the example code that will return folder size in megabytes [MB].
Get-ChildItem -Path "C:\Temp" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(MB)";Expression={$_.Sum/1mb}}
Here is the result of the folder size in megabytes. Notice that the result has many decimal places so in the next example, we will format the result to get with just two decimal places.
Let me just quickly go through each of CmdLets and parameters used with it and why we have used them.
Get-ChildItem CmdLet will list the files and folders within the folder specified in the Path parameter (C:\Temp folder in this case).
- The Recurse parameter force the command to recursively go through each subfolder within a folder specified in the Path parameter.
- The Force parameter will read hidden and system files which would be skipped otherwise.
- The ErrorAction parameter with value SilentlyContinue tells the PowerShell engine just to move on if an error occurs. This is very useful since sometimes even with Administrator privileges some files can be locked or used by some process and our call would be stopped without giving us the result.
Measure-Object CmdLet will do the math for us and sum up all the file sizes.
- The Property parameter tells PowerShell to read the value from the Length property of each object (file) send through the pipeline that is within the folder (C:\Temp).
- The Sum switch parameter will do the sum of all length values in all files within the folder (C:\Temp).
Select-Object CmdLet is used to present the result and convert bytes into kilobytes for the folder size.
- Name changes the result column name from Sum into Size(MB) so it is more describable.
- Expression divides values in bytes with one megabyte (1MB) so we can get the result in megabytes instead of bytes.
In this example, we will just format our result to return with two decimal places only. For that, we will use in Expression -f for formatting and format pattern for two decimal places “{0:N2}”.
Get-ChildItem -Path "C:\Temp" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(MB)";Expression={("{0:N2}" -f($_.Sum/1mb))}}
Here we can see the same result but little bit better formatted with just two decimal places.
How To Get Folder Size In Gibabytes Using PowerShell
To get the folder size in Gigabytes we will use Get-ChildItem, Measure-Object, and Select-Object PowerShell CmdLets by pipelining (“|”) the result from one to another.
Here is the example code that will return folder size in gigabytes [GB].
Get-ChildItem -Path "C:\Windows" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(GB)";Expression={$_.Sum/1gb}}
Here is the result of the folder size in gigabytes. Notice that the result has many decimal places so in the next example, we will format the result to get with just two decimal places.
Let me just quickly go through each of CmdLets and parameters used with it and why we have used them.
Get-ChildItem CmdLet will list the files and folders within the folder specified in the Path parameter (C:\Windows folder in this case).
- The Recurse parameter force the command to recursively go through each subfolder within a folder specified in the Path parameter.
- The Force parameter will read hidden and system files which would be skipped otherwise.
- The ErrorAction parameter with value SilentlyContinue tells the PowerShell engine just to move on if an error occurs. This is very useful since sometimes even with Administrator privileges some files can be locked or used by some process and our call would be stopped without giving us the result.
Measure-Object CmdLet will do the math for us and sum up all the file sizes.
- The Property parameter tells PowerShell to read the value from the Length property of each object (file) send through the pipeline that is within the folder (C:\Windows).
- The Sum switch parameter will do the sum of all length values in all files within the folder (C:\Windows).
Select-Object CmdLet is used to present the result and convert bytes into kilobytes for the folder size.
- Name changes the result column name from Sum into Size(GB) so it is more describable.
- Expression divides values in bytes with one gigabyte (1GB) so we can get the result in gigabytes instead of bytes.
In this example, we will just format our result to return with two decimal places only. For that, we will use in Expression -f for formatting and format pattern for two decimal places “{0:N2}”.
Get-ChildItem -Path "C:\Windows" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(GB)";Expression={("{0:N2}" -f($_.Sum/1gb))}}
Here we can see the same result but little bit better formatted with just two decimal places.
How To Get Folder Size In kB, MB, GB Using PowerShell
If for whatever reason we want to have folder size in kilobytes, megabytes, and gigabytes well-formatted using PowerShell here is the example code:
Get-ChildItem -Path "C:\Windows" -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(kB)";Expression={("{0:N2}" -f($_.Sum/1kb))}},
@{Name="Size(MB)";Expression={("{0:N2}" -f($_.Sum/1mb))}},
@{Name="Size(GB)";Expression={("{0:N2}" -f($_.Sum/1gb))}} |
Out-GridView
Here is the same result in three different sizes (kB, MB, GB).
How To Count Files And Folders Using PowerShell
Let’s see how we can count files and folders within the specified folder using PowerShell. Thanks to the readers question I am adding this section to the article.
How To Count Files Using PowerShell
Here is the line of code that will count all the files within the specified folder:
Get-ChildItem -Path "C:\Temp" -File -Recurse -Name -Force -ErrorAction SilentlyContinue | Measure-Object | Select-Object @{Name='File(s) Count';Expression={$_.count}}
Here is the result of above call:
You already know that the same result can be seen using Windows Explorer Properties like in the screenshot below.
Let me just quickly explain all the parameters and CmdLets used in this example.
Get-ChildItem CmdLet is used to list all the files within folders and subfolders. Here is the explanation of each parameter used:
- Path parameter points to the folder which subfolders we want to list in the result.
- File parameter will as result return only files and no folders.
- Recurse parameter will go through all subfolders
- Name parameter gets the names of the files
- Force parameter will include hidden and system files if they exist
- ErrorAction parameter with value SilentlyContinue specifies to PowerShell to continue if an error occurs so we can get the result without interruption. Sometimes even with Admin privileges execution can be stopped since the file might be locked or occupied by some process.
Result is pipelined to Measure-Object CmdLet. Its only purpose is to count the files for us. Finally we make the property name of the result to be readable using Select-Object CmdLet and expression feature.
How To Count Folders Using PowerShell
Here is the line of code that will count all the subfolders within the specified folder:
Get-ChildItem -Path "C:\Temp" -Directory -Recurse -Name -Force -ErrorAction SilentlyContinue | Measure-Object | Select-Object @{Name='Folder(s) Count';Expression={$_.count}}
Here is the result of above call:
You already know that the same result can be seen using Windows Explorer Properties like in the screenshot below.
Let me just quickly explain all the parameters and CmdLet used in this example
Get-ChildItem CmdLet is used to list all the subfolders and here is the explanation of each parameter used:
- Path parameter points to the folder which subfolders we want to list in the result.
- Directory parameter will as result return only folders and no files.
- Recurse parameter will go through all subfolders
- Force parameter will include hidden and system subfolders if they exist
- ErrorAction parameter with value SilentlyContinue specifies to PowerShell to continue if an error occurs so we can get the result without interruption. Sometimes even with Admin privileges execution can be stopped since the file might be locked or occupied by some process.
Result is pipelined to Measure-Object CmdLet. Its only purpose is to count the folders for us. Finally we make the property name of the result to be readable using Select-Object CmdLet and expression feature.
How To Count Both Files And Folders Using PowerShell
If you want ot have the result of both number of files and subfolders within specified folder using PowerShell as one result. Here is the solution provided:
$result = Get-ChildItem -Path "C:\Temp" -Directory -Recurse -Name -Force -ErrorAction SilentlyContinue | Measure-Object | Select-Object @{Name='Folder(s) Count';Expression={$_.count}}
$f = Get-ChildItem -Path "C:\Temp" -File -Recurse -Name -Force -ErrorAction SilentlyContinue | Measure-Object | Select-Object @{Name='File(s) Count';Expression={$_.count}}
$result | Add-Member -NotePropertyName "File(s) Count" -NotePropertyValue $f.'File(s) Count'
$result
Here is the result of above lines of code:
You already know that the same result can be seen using Windows Explorer Properties like in the screenshot below.
In this example, we use the lines of code from previous two examples. Here we just use Add-Member CmdLet to have the results in one row. This will provide the result for us that shows both number of folders and files within specified folder using PowerShell.
How To Get The Size Of Each Subfolder Using PowerShell
This is an interesting example that will go through each subfolder of the specified folder (C:\Temp) and calculate the size of each subfolder. For this example, we are using several PowerShell CmdLets (Get-ChildItem, Select-Object, ForEach-Object, New-Object, Measure-Object) combined with PowerShell Pipeline and a little bit of nesting.
Here is the example code and we hope it will be useful to many of you.
Get-ChildItem -path "C:\Temp" -Directory -Recurse |
Select-Object FullName |
ForEach-Object -Process{New-Object -TypeName PSObject -Property @{Name =$_.FullName;Size = (Get-ChildItem -path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum ).Sum/1kb}} |
Select-Object Name, @{Name="Size(KB)";Expression={("{0:N2}" -f($_.Size))}}
Here is the result set of previous example call.
Let me quickly explain what we have done.
First, we use Get-ChildItem and pass the value for the Path parameter specifying the folder which subfolders’ sizes we want to calculate. Recurse parameter specify that we go through all subfolders within C:\Temp folder. Directory parameter tells PowerShell to look only for folders and no files.
With Select-Object CmdLet we specify that result will further send to the PowerShell Pipeline value of FullName property which is the path to the subfolders.
ForEach-Object CmdLet accepts each subfolder and continues further processing. First, it can look intimidating how we have implemented several PowerShell CmdLets within ForEach-Object CmdLet but do not worry we will explain each of them.
New-Object CmdLet is used to keep the values for the Subfolder path and size as a PowerShell object that we will eventually see as a result. Subfolder path = Name is the FullName property value from previous PowerShell CmdLet. The Size property we calculate using Get-ChildItem and Measure-Object CmdLets.
Get-ChildItem CmdLet in Path parameter has a Subfolder path value. The Recurse parameter is specified since we want to take into account the subfolders of the subfolder. The Force parameter has been specified since we want to take into account hidden and system folders if exist. The ErrorAction parameter with the value SilentlyContinue specifies to PowerShell to continue if an error occurs so we can get the result without interruption. Sometimes even with Admin privileges execution can be stopped since the file might be locked or occupied by some process.
As we know Measure-Object CmdLet will do the math for us and calculate the subfolder size. The Property parameter specifies that Length property should be used and that is basically file size in bytes. The Sum switch parameter basically is operation since we want to sum up all the file sizes in order to get the subfolder size.
NOTE: We have divided the value with 1kb in order to get the folder size in kilobytes and not as default in bytes. In the same way, we can use 1mb, and 1gb to get folder size in megabytes and gigabytes respectively.
If you want to get a more detailed explanation please read the subheadings:
How To Get Folder Size In Megabytes Using PowerShell
How To Get Folder Size In Gibabytes Using PowerShell
Finally, we use Select-Object CmdLet once more in order to format (-f) the result to be a number with two decimal places {0:N2}. In addition, we label the subfolder size column with the appropriate name Size(KB).
REMEMBER: In this example, we have used PowerShell Pipeline extensively and it is a very important concept. I highly encourage you to read my article PowerShell Pipeline Concept Explained With Awesome Examples with many examples that will explain in detail PowerShell Pipelining.
How To Get Folders and Subfolders Older Than X Days
In order to get folders and subfolders older than a certain number of days, we have used Get-ChildItem, Where-Object, Get-Date, Select-Object, Out-GridView PowerShell CmdLets.
Here is the sample code:
Get-ChildItem -Path "C:\Temp" -Directory -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object {$_.CreationTime -LT (Get-Date).AddDays(-10)} |
Select-Object Name, FullName, Parent, CreationTime, LastWriteTime, CreationTimeUTC, LastWriteTimeUtc, Attributes |
Out-GridView
Here is the result presented as grid.
We can see that the New folder is less than 10 days old and not in the result as we expect according to the criteria applied.
So let’s go now through each CmdLet and their parameters in order to understand the above code.
Get-ChildItem CmdLet is used to list all the subfolders and here is the explanation of each parameter used:
- Path parameter points to the folder which subfolders we want to list in the result.
- Directory parameter will as result return only folders and no files.
- Recurse parameter will go through all subfolders
- Force parameter will include hidden and system subfolders if they exist
- ErrorAction parameter with value SilentlyContinue specifies to PowerShell to continue if an error occurs so we can get the result without interruption. Sometimes even with Admin privileges execution can be stopped since the file might be locked or occupied by some process.
Where-Object CmdLet is used to filter out the subfolders older than X number of days. For comparison (-LT less than) we use the Creation Date of the folder.
Get-Date CmdLet uses the AddDays method with value -10 meaning that we want to include subfolders older than 10 days.
Select-Object CmdLet is used to prepare the result set with several properties
Out-GridView CmdLet is used to present the result in grid (table)
How To List Folder And Subfolders Names Using PowerShell
In this example code, we will list all folders and subfolders of the root folder (C:\Temp in this example)
Get-ChildItem -Path "C:\Temp" -Directory -Recurse -Name -Force -ErrorAction SilentlyContinue
Here is the result set.
Get-ChildItem CmdLet is used to list all the subfolders and here is the explanation of each parameter used:
- Path parameter points to the folder which subfolders we want to list in the result.
- Directory parameter will as result return only folders and no files.
- Recurse parameter will go through all subfolders
- Name parameter gets only the names of the folders and subfolders
- Force parameter will include hidden and system subfolders if they exist
- ErrorAction parameter with value SilentlyContinue specifies to PowerShell to continue if an error occurs so we can get the result without interruption. Sometimes even with Admin privileges execution can be stopped since the file might be locked or occupied by some process.
How To List File Names Within Folder and Subfolders Using PowerShell
This example is the opposite of the previous example and here we will list only files and not folders or subfolders.
Get-ChildItem -Path "C:\Temp" -File -Recurse -Name -Force -ErrorAction SilentlyContinue
Here is the result set of above example code.
Get-ChildItem CmdLet is used to list all the files within folders and subfolders. Here is the explanation of each parameter used:
- Path parameter points to the folder which subfolders we want to list in the result.
- File parameter will as result return only file names and no folders.
- Recurse parameter will go through all subfolders
- Name parameter gets the names of the files
- Force parameter will include hidden and system files if they exist
- ErrorAction parameter with value SilentlyContinue specifies to PowerShell to continue if an error occurs so we can get the result without interruption. Sometimes even with Admin privileges execution can be stopped since the file might be locked or occupied by some process.
How To List Hidden Folders Or Files Within Folder Using PowerShell
It can happen that we have some hidden folders or files so it is important to list them as well as needed. Get-ChildItem CmdLet has the appropriate parameters to do exactly what we need.
Get-ChildItem -path "C:\Temp" -Hidden -Recurse
Here is the result set with only hidden files or folders.
NOTE: In the Mode column of the result we can see the letter “h” which is an attribute for hidden.
Get-ChildItem CmdLet is used to list all the files or folders within folders and subfolders. Here is the explanation of each parameter used:
- Path parameter points to the folder which subfolders and files we want to list in the result.
- Hidden parameter will as a result return hidden or system files or folders.
- Recurse parameter will go through all subfolders
How To List Read-Only Folders Or Files Within Folder Using PowerShell
If we have read-only folders or files and want to list just them we can again use Get-ChildItem CmdLet with the following parameters:
- Path parameter points to the folder which subfolders we want to list in the result.
- ReadOnly parameter will as a result return read-only files.
- Recurse parameter will go through all subfolders
Get-ChildItem -Path "C:\Temp" -ReadOnly -Recurse
Here is the result with read-only file:
NOTE: In the Mode column of the result we can see the letter “r” which is an attribute for read-only files.
How To List System Folders Or Files Within Folder Using PowerShell
If we have system folders or files and want to list just them we can again use Get-ChildItem CmdLet with the following parameters:
- Path parameter points to the folder which subfolders we want to list in the result.
- System switch parameter will as a result return system folders or files.
Get-ChildItem -Path "C:\Windows" -System
Here is the result set with only system folders and files.
NOTE: In the Mode column of the result we can see the letter “s” which is an attribute for system folders or files.
How To Get Folder Dates Using PowerShell
To get the dates when subfolders have been created, last time accessed, or last time something is written in them we can use Get-ChildItem CmdLet with the following parameters:
- Path parameter points to the folder which subfolders we want to list in the result.
- Directory switch parameter will as a result return only subfolders but no files or second level folders. For further levels, we need to use the Recurse parameter.
Get-ChildItem -Path "C:\Temp" -Directory |
Select-Object Name, CreationTime, LastAccessTime, LastWriteTime
Here is the result (date is in format mm/dd/yyyy hh:mm:ss):
To do the same thing but this time only for specified folder we can use Get-Item CmdLet with Path parameter pointing to the specified folder (C:\Temp folder in this example):
Get-Item -Path "C:\Temp" |
Select-Object Name, CreationTime, LastAccessTime, LastWriteTime
Here is the result (date is in format mm/dd/yyyy hh:mm:ss):
How To Use Folder Size PowerShell Examples – Tips
There are many possible applications of Folder Size script and it depends on your system and which applications you use so I can recommend a few implementations.
- If you use applications that might create files in ASP Temp files it would be smart to check folder size and do the necessary clean up in the following location:
- C:\Windows\Microsoft.NET\Framework*\v*\Temporary ASP.NET Files
- Sometimes it is useful to check the folder size of a certain user’s temporary folder:
- C:\Users\user_name\AppData\Local\Temp
- If you need to check the user’s profile folder size
- C:\Users\user_name\
If you have any suggestions for more implementations please leave it in the comments at the bottom of this article or send me an email using the contact form.
How To Write Own CmdLet For Folder Size Using PowerShell
In this part of the article, I will show you my own CmdLet created to do the same task but I will not go into details like in my other articles since the code in this CmdLet reuses many ideas already presented to you.
INFO: To learn how to create your own CmdLets please read this article with step by step approach “How To Create A Custom PowerShell CmdLet (Step By Step)“.
Get-FolderSize CmdLet – Explained
Get-FolderSize CmdLet gets folder size and item (files and folders) count within the specified folder for the list of servers and this CmdLet belongs to Efficiency Booster PowerShell Project. This project is the library of different CmdLets that can help us IT personal to do our everyday tasks more efficiently and accurately.
Source code for Get-FolderSize CmdLet can be downloaded from this zip file so please feel free to download it and it would be easier for you to follow me along.
Get-FolderSize CmdLet is part of the Common module and if you have downloaded the source code it can be found in the folder …\[My] Documents\WindowsPowerShell\Modules\03common
INFO: If you want to know how to install and configure Efficiency Booster PowerShell Project files please read the following article: How To Install And Configure PowerShell: CmdLets, Modules, Profiles.
In the following example, we have used a text file (OKFINservers.txt) where we have a list of servers to remotely connect to them and get the folder size
Here is one example call to the Get-FolderSize CmdLet:
Get-FolderSize -filename "OKFINservers.txt" -path "C:\Temp" -errorlog -client "OK" -solution "FIN" |
Select-Object 'Environment', 'Logical Name', 'Server Name', 'Folder path', 'Size(MB)', 'Items count', 'IP', 'Collected' |
Out-GridView
Here is the result of the above call:
We can PowerShell pipeline result from Get-FolderSize CmdLet into Save-ToExcel CmdLet and get a result set as an Excel Sheet:
Get-FolderSize -filename "OKFINservers.txt" -path "C:\Temp" -errorlog -client "OK" -solution "FIN" -Verbose |
Save-ToExcel -errorlog -ExcelFileName "Get-FolderSize_Temp" -title "Get folder size in Financial solution for " -author "Dejan Mladenovic" -WorkSheetName "User Temp Folder size" -client "OK" -solution "FIN"
Here is the Excel Sheet result:
INFO: To learn how to save results from CmdLets into Excel sheet please read the dedicated article “How To Create, Write And Save An Excel File Using PowerShell“
Get-FolderSize CmdLet – Source Code
DISCLAIMER: Get-FolderSize function is part of the Efficiency Booster PowerShell Project and as such utilize other CmdLets that are part of the same project. So the best option for you in order for this function to work without any additional customization is to download the source code of the whole project from here.
INFO: My best advice to every PowerShell scripter is to learn writing own PowerShell Advanced Functions and CmdLets and I have written several articles explaining this, so please read them. How To Create A Custom PowerShell CmdLet (Step By Step). Here I explain how to use PowerShell Add-on Function to be faster in writing PowerShell Functions How To Write Advanced Functions Or CmdLets With PowerShell (Fast).
Here is the source code of the whole Get-FolderSize CmdLet:
<#
.SYNOPSIS
Get the size of folder and number of items (subfolders and files) in folder.
.DESCRIPTION
Get the size of folder and number of items (subfolders and files) in folder.
List of servers is in txt file in 01servers folder or list of strings with names of computers.
CmdLet has two ParameterSets one for list of computers from file and another from list of strings as computer names.
Errors will be saved in log folder PSLogs with name Error_Log.txt. Parameter errorlog controls logging of errors in log file.
Get-FolderSize function uses Get-ChildItem PowerShell function to get size of folder and Invoke-Command to remotely connect to
the servers and do the calculation.
Result shows following columns: Environment (PROD, Acceptance, Test, Course...),
Logical Name (Application, web, integration, FTP, Scan, Terminal Server...), Server Name,
Folder path, Size(MB), Items count, IP
.PARAMETER computers
List of computers that we want to get Last bootup time from. Parameter belongs to default Parameter Set = ServerNames.
.PARAMETER filename
Name of txt file with list of servers that we want to check Last bootup time. .txt file should be in 01servers folder.
Parameter belongs to Parameter Set = FileName.
.PARAMETER path
Absolute folder path that we want to find size of.
.PARAMETER errorlog
Switch parameter that sets to write to log or not to write to log. Error file is in PSLog folder with name Error_Log.txt.
.PARAMETER client
OK - O client
BK - B client
etc.
.PARAMETER solution
FIN - Financial solution
HR - Human resource solution
etc.
.EXAMPLE
Get-FolderSize -path "C:\Windows\Microsoft.NET\Framework*\v*\Temporary ASP.NET Files" -client "OK" -solution "FIN"
Description
---------------------------------------
Test of default parameter with default value ( computers = 'localhost' ) in default ParameterSet = ServerName.
.EXAMPLE
Get-FolderSize -client "OK" -solution "FIN" -Verbose
Description
---------------------------------------
Test of Verbose parameter. NOTE: Notice how localhost default value of parameter computers replaces with name of server.
.EXAMPLE
'ERROR' | Get-FolderSize -client "OK" -solution "FIN" -errorlog
Description
---------------------------------------
Test of errorlog parameter. There is no server with name ERROR so this call will fail and write to Error log since errorlog switch parameter is on. Look Error_Log.txt file in PSLogs folder.
.EXAMPLE
Get-FolderSize -computers 'APP100001' -client "OK" -solution "FIN" -errorlog
Description
---------------------------------------
Test of computers parameter with one value. Parameter accepts array of strings.
.EXAMPLE
Get-FolderSize -computers 'APP100001', 'APP100002' -client "OK" -solution "FIN" -errorlog -Verbose
Description
---------------------------------------
Test of computers parameter with array of strings. Parameter accepts array of strings.
.EXAMPLE
Get-FolderSize -hosts 'APP100001' -client "OK" -solution "FIN" -errorlog
Description
---------------------------------------
Test of computers paramater alias hosts.
.EXAMPLE
Get-FolderSize -computers (Get-Content( "$home\Documents\WindowsPowerShell\Modules\01servers\OKFINservers.txt" )) -client "OK" -solution "FIN" -errorlog -Verbose
Description
---------------------------------------
Test of computers parameter and values for parameter comes from .txt file that has list of servers.
.EXAMPLE
'APP100001' | Get-FolderSize -client "OK" -solution "FIN" -errorlog
Description
---------------------------------------
Test of pipeline by value of computers parameter.
.EXAMPLE
'APP100001', 'APP100002' | Get-FolderSize -client "OK" -solution "FIN" -errorlog -Verbose
Description
---------------------------------------
Test of pipeline by value with array of strings of computers parameter.
.EXAMPLE
'APP100001', 'APP100002' | Select-Object @{label="computers";expression={$_}} | Get-FolderSize -client "OK" -solution "FIN" -errorlog
Description
---------------------------------------
Test of values from pipeline by property name (computers).
.EXAMPLE
Get-Content( "$home\Documents\WindowsPowerShell\Modules\01servers\OKFINservers.txt" ) | Get-FolderSize -client "OK" -solution "FIN" -errorlog -Verbose
Description
---------------------------------------
Test of pipeline by value that comes as content of .txt file with list of servers.
.EXAMPLE
Help Get-FolderSize -Full
Description
---------------------------------------
Test of Powershell help.
.EXAMPLE
Get-FolderSize -filename "OKFINservers.txt" -errorlog -client "OK" -solution "FIN" -Verbose
Description
---------------------------------------
This is test of ParameterSet = FileName and parameter filename. There is list of servers in .txt file.
.EXAMPLE
Get-FolderSize -file "OKFINserverss.txt" -errorlog -client "OK" -solution "FIN" -Verbose
Description
---------------------------------------
This is test of ParameterSet = FileName and parameter filename. This test will fail due to wrong name of the .txt file with warning message "WARNING: This file path does NOT exist:".
.INPUTS
System.String
Computers parameter pipeline both by Value and by Property Name value and has default value of localhost. (Parameter Set = ComputerNames)
Filename parameter does not pipeline and does not have default value. (Parameter Set = FileName)
.OUTPUTS
System.Management.Automation.PSCustomObject
Get-FolderSize returns PSCustomObjects
Result shows following columns: Environment (PROD, Acceptance, Test, Course...),
Logical name (Application, web, integration, FTP, Scan, Terminal Server...), Server name, OS, LastBootUpTime, IP
.NOTES
FunctionName : Get-FolderSize
Created by : Dejan Mladenovic
Date Coded : 10/19/2020 19:06:41
More info : http://improvescripting.com/
.LINK
Get Folder Size And File Count Using PowerShell Examples
Get-ChildItem
Measure-Object
Invoke-Command
#>
Function Get-FolderSize {
[CmdletBinding(DefaultParametersetName="ServerNames")]
param (
[Parameter( ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName="ServerNames",
HelpMessage="List of computer names separated by commas.")]
[Alias('hosts')]
[string[]]$computers = 'localhost',
[Parameter( ParameterSetName="FileName",
HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")]
[string]$filename,
[Parameter( Mandatory=$true,
HelpMessage="Absolute folder path that we want to measure size of.")]
[string]$path,
[Parameter( Mandatory=$false,
HelpMessage="Write to error log file or not.")]
[switch]$errorlog,
[Parameter(Mandatory=$true,
HelpMessage="Client for example OK = O client, BK = B client")]
[string]$client,
[Parameter(Mandatory=$true,
HelpMessage="Solution, for example FIN = Financial, HR = Human Resource")]
[string]$solution
)
BEGIN {
if ( $PsCmdlet.ParameterSetName -eq "FileName") {
if ( Test-Path -Path "$home\Documents\WindowsPowerShell\Modules\01servers\$filename" -PathType Leaf ) {
Write-Verbose "Read content from file: $filename"
$computers = Get-Content( "$home\Documents\WindowsPowerShell\Modules\01servers\$filename" )
} else {
Write-Warning "This file path does NOT exist: $home\Documents\WindowsPowerShell\Modules\01servers\$filename"
Write-Warning "Create file $filename in folder $home\Documents\WindowsPowerShell\Modules\01servers with list of server names."
break;
}
}
}
PROCESS {
foreach ($computer in $computers ) {
if ( $computer -eq 'localhost' ) {
$computer = $env:COMPUTERNAME
}
$computerinfo = Get-ComputerInfo -computername $computer -client $client -solution $solution
$hostname = $computerinfo.hostname
$env = $computerinfo.environment
$logicalname = $computerinfo.logicalname
$ip = $computerinfo.ipaddress
try {
Write-Verbose "Processing: $computer - $env - $logicalname"
Write-Verbose "Start Invoke-Command processing..."
$foldersize = $null
$folderpath = $path
Write-Verbose "Folder path: $folderpath"
#$scriptblock = { param ($parampath) Get-ChildItem -Path $parampath -Recurse | Measure-Object -Property Length -Sum | Select-Object @{Name="Size(MB)";Expression={("{0:N2}" -f($_.Sum/1mb))}}, Count }
#IMPORTANT - DO NOT use formatting ("{0:N2}" -f($_.Sum/1mb)) of expression if you want to explicit convert to decimal data type. (see down in properties variable)
$scriptblock = { param ($parampath) Get-ChildItem -Path $parampath -Recurse -Force |
Measure-Object -Property Length -Sum |
Select-Object @{Name="Size(MB)";Expression={$_.Sum/1mb}}, Count }
##REPLACE THIS VALUE!!
$EncryptedPasswordFile = "C:\Users\dekib\Documents\PSCredential\Invoke-Command.txt"
##REPLACE THIS VALUE!!
$username="user_name"
$password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$Credentials = New-Object System.Management.Automation.PSCredential($username, $password)
$params = @{ 'ComputerName'=$computer;
'ErrorAction'='Stop';
'ScriptBlock'=$scriptblock;
'Credential'=$Credentials;
'ArgumentList'=$path }
$foldersize = Invoke-Command @params
Write-Verbose "Finish Invoke-Command processing..."
if ( $foldersize ) {
$properties = @{ 'Environment'=$env;
'Logical name'=$logicalname;
'Server name'=$computer;
'Folder path'=$path;
'Size(MB)'=[decimal]$foldersize."Size(MB)";
'Items count'=[int]$foldersize.Count;
'IP'=$ip;
'Collected'=(Get-Date -UFormat %Y.%m.%d' '%H:%M:%S)}
$obj = New-Object -TypeName PSObject -Property $properties
$obj.PSObject.TypeNames.Insert(0,'Report.FolderSize')
Write-Output $obj
}
Write-Verbose "Finished processing: $computer - $env - $logicalname"
} catch {
Write-Warning "Computer failed: $computer - $env - $logicalname"
Write-Warning "Error message: $_"
if ( $errorlog ) {
$errormsg = $_.ToString()
$exception = $_.Exception
$stacktrace = $_.ScriptStackTrace
$failingline = $_.InvocationInfo.Line
$positionmsg = $_.InvocationInfo.PositionMessage
$pscommandpath = $_.InvocationInfo.PSCommandPath
$failinglinenumber = $_.InvocationInfo.ScriptLineNumber
$scriptname = $_.InvocationInfo.ScriptName
Write-Verbose "Start writing to Error log."
Write-ErrorLog -hostname $computer -env $env -logicalname $logicalname -errormsg $errormsg -exception $exception -scriptname $scriptname -failinglinenumber $failinglinenumber -failingline $failingline -pscommandpath $pscommandpath -positionmsg $pscommandpath -stacktrace $stacktrace
Write-Verbose "Finish writing to Error log."
}
}
}
}
END {
}
}
#region Execution examples
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Temp" -errorlog -client "OK" -solution "FIN" | Select-Object 'Environment', 'Logical Name', 'Server Name', 'Folder path', 'Size(MB)', 'Items count', 'IP', 'Collected' | Out-GridView
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Windows\Microsoft.NET\Framework*\v*\Temporary ASP.NET Files" -errorlog -client "OK" -solution "FIN" -Verbose | Select-Object 'Environment', 'Logical Name', 'Server Name', 'Folder path', 'Size(MB)', 'Items count', 'IP', 'Collected' | Out-GridView
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Users\user_name\AppData\Local\Temp" -errorlog -client "OK" -solution "FIN" -Verbose | Select-Object 'Environment', 'Logical Name', 'Server Name', 'Folder path', 'Size(MB)', 'Items count', 'IP', 'Collected' | Out-GridView
<#
#Test ParameterSet = ServerName
Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN"
Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog
Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog -Verbose
Get-FolderSize -computers 'APP100001' -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog
Get-FolderSize -computers 'APP100001', 'APP100002' -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog -Verbose
Get-FolderSize -hosts 'APP100001' -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog
Get-FolderSize -computers (Get-Content( "$home\Documents\WindowsPowerShell\Modules\01servers\OKFINservers.txt" )) -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog -Verbose
#Pipeline examples
'APP100001' | Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog
'APP100001', 'APP100002' | Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog -Verbose
'APP100001', 'APP100002' | Select-Object @{label="computers";expression={$_}} | Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog
Get-Content( "$home\Documents\WindowsPowerShell\Modules\01servers\OKFINservers.txt" ) | Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog -Verbose
'ERROR' | Get-FolderSize -path "C:\Users\user_name\AppData\Local\Temp" -client "OK" -solution "FIN" -errorlog
#Test CmdLet help
Help Get-FolderSize -Full
#SaveToExcel
Get-FolderSize -filename "OKFINservers.txt" -path "C:\Temp" -errorlog -client "OK" -solution "FIN" -Verbose | Save-ToExcel -errorlog -ExcelFileName "Get-FolderSize_Temp" -title "Get folder size in Financial solution for " -author "Dejan Mladenovic" -WorkSheetName "User Temp Folder size" -client "OK" -solution "FIN"
#SaveToExcel and send email
Get-FolderSize -filename "OKFINservers.txt" -path "C:\Temp" -errorlog -client "OK" -solution "FIN" -Verbose | Save-ToExcel -sendemail -errorlog -ExcelFileName "Get-FolderSize_Temp" -title "Get folder size in Financial solution for " -author "Dejan Mladenovic" -WorkSheetName "User Temp Folder size" -client "OK" -solution "FIN"
#Test ParameterSet = FileName
Get-FolderSize -filename "OKFINservers.txt" -path "C:\Users\user_name\AppData\Local\Temp" -errorlog -client "OK" -solution "FIN" -Verbose
Get-FolderSize -filename "OKFINserverss.txt" -path "C:\Users\user_name\AppData\Local\Temp" -errorlog -client "OK" -solution "FIN" -Verbose
#>
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Windows\Microsoft.NET\Framework*\v*\Temporary ASP.NET Files" -errorlog -client "OK" -solution "FIN" -Verbose | Out-GridView
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Users\user_name\AppData\Local\Temp" -errorlog -client "OK" -solution "FIN" -Verbose | Out-GridView
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Windows\Microsoft.NET\Framework*\v*\Temporary ASP.NET Files" -errorlog -client "OK" -solution "FIN" -Verbose | Save-ToExcel -sendemail -errorlog -ExcelFileName "Get-FolderSize_ASP_Cache" -title "Get ASP cache size in Financial solution for " -author "Dejan Mladenovic" -WorkSheetName "ASP.NET cache size" -client "OK" -solution "FIN"
#Get-FolderSize -filename "OKFINservers.txt" -path "C:\Users\user_name\AppData\Local\Temp" -errorlog -client "OK" -solution "FIN" -Verbose | Save-ToExcel -sendemail -errorlog -ExcelFileName "Get-FolderSize_Agresso_Temp" -title "Get Temp folder size in Financial solution for " -author "Dejan Mladenovic" -WorkSheetName "Temp folder size" -client "OK" -solution "FIN"
#endregion
Useful PowerShell Folder Size Articles
Here are some useful articles and resources: