PowerShell: Script for Loop through Files and Folders

In this article, we will take a look at examples of using constructions to loop through all files and folders on a disk or in a specific directory (using the For-Each and Get-ChildItem statements). You can widely use them in your PowerShell scripts.

Usually, the task of iterating over all file system objects in a directory arises when you need to perform a certain action with all nested objects. For example, you need to delete, copy, move files, add or replace lines in all files in the specific directory by some criteria.

To get a list of child objects (folders and files) in a directory, use the Get-ChildItem PowerShell cmdlet. This is the most popular file system cmdlet. There are several aliases for ChildItem: gci, dir, ls.

The Get-ChildItem cmdlet displays a list of child (nested) objects on a specified drive or directory. The path to the directory is specified through the –Path attribute.


For example, to list the files in the C:\PS directory, run the command:

Get-ChildItem -Path ‘C:\PS’

powershell get-childitem foreach

However, it displays a list of objects located in the root of the specified directory. You can also display the contents of child directories (subdirectories) using the –Recurse parameter:

Get-ChildItem -Path ‘C:\PS’ –Recurse

As you can see, the contents of each subdirectory are displayed sequentially.

get-childitem foreach

Now, let’s look at the general structure of the ForEach loop when using the Get-ChildItem cmdlet:

Get-ChildItem –Path "C:\PS" |

Foreach-Object {

#Do something with $_.FullName


Also, you can use such a loop structure (but we like it less):

foreach($file in Get-ChildItem $SomeFolder)


# Do something


For example, you can delete all files with the *.log extension in the specified directory and all subfolders (we won’t really delete the files from disk by adding the parameter WhatIF):

Get-ChildItem –Path "C:\PS\" -Recurse -Filter *.log


Foreach-Object {

Remove-Item $_.FullName -WhatIF


The script found 3 files with the *.log extension and indicated that they could be deleted by this script.

powershell foreach file in folder

Delete files older than xx days using PowerShell

Consider a script that deletes files older than 10 days in a directory (it can be used when you need to clean up the logs folder, or public network folders). We use the Where-Object cmdlet to filter objects:

Get-ChildItem C:\ps\ -Recurse |

Where-Object { $_.CreationTime -lt ($(Get-Date).AddDays(-10))} |

ForEach-Object { remove-Item $_.FullName –whatif }

Remove empty directories recursively with PowerShell

Or you can loop through all subdirectories and empty folders and subfolders if any exist:

Get-ChildItem C:\ps\ -Recurse -Force -ea 0 |Where-Object {$_.PsIsContainer -eq $True} |{$_.getfiles().count -eq 0} |

ForEach-Object {

$_ | del -Force


Find large files and move it to a different folder

The following example will find all * .iso files over 1 GB on the system drive C: and move them to another partition.

First, let’s set the required file size (1 GB):


Now let’s loop through files and move them to the target directory:

Get-ChildItem C:\* -Include *.iso -Recurse |Where-Object { $_.Length -gt $filesize} |ForEach-Object { Move-Item $_.FullName D:\ISO -whatif}

Loop through text files in a directory using PowerShell

The following file loop example allows to find files containing the text ‘flush_log’ or ‘error’ for all *.log files in the directory, and saves the found lines to files with a new extension (_outlog):

$files = Get-ChildItem C:\ps\ -Recurse *.log

foreach ($f in $files){

$outfile = $f.FullName + "_outlog"

Get-Content $f.FullName | Where-Object { ($_ -match 'flush_log' -or $_ -match 'error') } | Set-Content $outfile


Such a PowerShell script can be useful when searching for specific event entries in log files and filtering out all that is unnecessary. Also, you can use this PS code in other scenarios when you need loop through files, read the contents, and do something with it.

Find out which user is locking a file in a shared folder

You can use a foreach loop to find the user opening a specific file on a network share via SMB. In this example, we’ll connect to a remote computer (SMB host) using CIMSession and loop through the open files:


$sess = New-CIMSession –Computername ny-fs01

$files = Get-SMBOpenFile -CimSession $sess

foreach ($file in $files)


if ($file.path -like $filename)


$file | select path, ClientUserName | fl



I enjoy technology and developing websites. Since 2012 I'm running a few of my own websites, and share useful content on gadgets, PC administration and website promotion.
Latest posts by Cyril Kardashevsky (see all)


  1. This was a great help. Had to write a basic file sync to push files newer than N to remote cloud destination. Works great!

  2. It seems that the remove empty directories is not working, because an expression is only allowed as the first element of a pipeline.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.