PowerShell: Script for Loop through Files and Folders


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

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

To get a list of child objects (files and folders) in a directory, use the Get-Childtem PowerShell cmdlet. This is the most popular file system cmdlet.

There are several aliases for Childtem: 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 get a list of files in the C:\PS directory, run the command:

Get-ChildItem -Path ‘C:\PS’                     

it displays a list of objects located on the roof of the specified directory. You can also display the contents of child directories (subdirectories) by using the -Recurse parameter:
Get-ChildItem -Path ‘C:\PS’ –Recurse
The content of each subdirectory is displayed as shown below:

Let’s look at the general structure of Each loop when using the Get-ChildItem cmdlet:
Get-ChildItem –Path “C:\PS”
Foreface-Object {#Do something with $_.FullName}

You can also use 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|
For each-Object {Remove-Item $_.FullName -WhatIF}
The script found 3 files with the *.log extension and indicated that they could be deleted by this script.

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 $}

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):

move loop through files 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 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 for each 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}

Leave a Reply

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

Enter Captcha Here :