Business.com aims to help business owners make informed decisions to support and grow their companies. We research and recommend products and services suitable for various business types, investing thousands of hours each year in this process.
As a business, we need to generate revenue to sustain our content. We have financial relationships with some companies we cover, earning commissions when readers purchase from our partners or share information about their needs. These relationships do not dictate our advice and recommendations. Our editorial team independently evaluates and recommends products and services based on their research and expertise. Learn more about our process and partners here.
Learn how to automate repetitive business tasks using PowerShell's "for," "foreach," "while" and other loop types.
A PowerShell “for” loop is a core scripting tool that lets you execute a block of code multiple times. Whether you’re automating system tasks or processing data, understanding how to write a “for” loop in Windows PowerShell — and how it compares to other loop types — can streamline your scripting and make it more efficient.
In this guide, we’ll walk through how to use “for,” “foreach” and “ForEach-Object” loops, along with “while,” “do-while” and “do-until.” We’ll also share expert-backed tips for using each effectively and flag a few common pitfalls to watch for.

The “for” loop in PowerShell follows a specific syntax structure that makes it both powerful and easy to understand. “For” loops are typically used to run a block of code a set number of times, whether you’re stepping through an array or repeating the same task. Siva Padisetty, who worked on the development of PowerShell when he was a director at Microsoft in the early 2000s, explained that this construct is especially useful when you know exactly how many times you want to do something.
A “for” loop is constructed using three main components:
The basic syntax follows this pattern:
For (initialization; condition; increment) {
# Commands to execute
}
The following example shows a basic “for” loop used to create a multiplication table:
For ($i=0; $i -le 10; $i++) {
“10 * $i = ” + (10 * $i)
}
You can also use “for” loops to step through array values by starting at the first index and incrementing until the array length is reached. The array index is specified by placing the variable inside square brackets immediately after the array name, as shown below:
$colors = @(“Red”,”Orange”,”Yellow”,”Green”,”Blue”,”Indigo”,”Violet”)
For ($i=0; $i -lt $colors.Length; $i++) {
$colors[$i]
}
Using loops in PowerShell starts with understanding the different loop types and choosing the one that best fits your task. In many cases, more than one approach will work, so the goal is to pick the option that balances performance with readability.
To implement a loop in PowerShell:
Here are three realistic business scenarios that show how “for” loops work in PowerShell. Each example highlights how loops can automate everyday tasks, helping teams save time and reduce manual errors.
This example shows how you might process payroll information for multiple employees, such as employee data records used for payroll calculations. The loop ensures each record is handled consistently, helping reduce the risk of missed payments or data entry errors.
# Process payroll data for 50 employees
$employeeCount = 50
For ($i = 1; $i -le $employeeCount; $i++) {
Write-Host “Processing employee ID: $i”
# Add payroll calculation logic here
}
Accounting and finance teams often need to generate reports for each month of the year. This “for” loop automates that process, ensuring no months are skipped and the formatting remains consistent.
# Generate reports for 12 months
For ($month = 1; $month -le 12; $month++) {
$monthName = (Get-Date -Year $currentYear -Month $month -Day 1).ToString(“MMMM”)
Write-Host “Generating report for $monthName”
# Add report generation logic here
}
This example shows how to process files across multiple departments. The loop iterates through a predefined array of department names, ensuring each one is handled consistently — a useful pattern when onboarding new employees or reorganizing shared drives.
# Process multiple department files
$departments = @(“Sales”,”Marketing”,”HR”,”Finance”,”Operations”)
For ($i = 0; $i -lt $departments.Length; $i++) {
Write-Host “Processing files for: $($departments[$i])”
# Add file processing logic here
}
PowerShell includes several loop types beyond the “for” loop, each designed for different use cases. Choosing the right one depends on your data, performance needs and how you want to structure your script.
The “foreach” loop in PowerShell is a language construct that lets you iterate over all items in a collection and run a block of code for each item.
Unlike the “ForEach-Object” cmdlet described below, the “foreach” loop loads the entire collection into memory before processing. This makes it faster for in-memory collections, but potentially more memory-intensive when working with large datasets.
The basic syntax follows this pattern:
foreach ($item in $collection) {
# Code to execute for each item
}
PowerShell automatically creates the $item variable during each iteration, assigning it to the current value in the collection. This makes it easy to work with arrays, lists and other collections without manually tracking your position.
This loop type is a strong fit when you have a defined list of items that need the same processing, such as updating employee records, generating invoices or working through a batch of customer orders.
Here’s a simple example:
$employees = @(“John Doe”, “Jane Smith”, “Bob Johnson”)
foreach ($employee in $employees) {
Write-Host “Processing payroll for: $employee”
# Add payroll processing logic here
}
The “foreach” loop is well-suited to scenarios where you have a defined collection and need to apply consistent operations to each item, whether that’s renaming files in a directory, updating database records or sending templated notifications. Because it processes the entire collection in memory, it typically runs faster than “ForEach-Object” for smaller datasets.

The “ForEach-Object” cmdlet is most useful when you need to repeat the same task for each item in a collection.
“Imagine you have a basket of different fruits: an apple, a banana and an orange. You want to take each fruit out one at a time and take a bite,” Padisetty said. “The ‘ForEach-Object’ loop is like saying, ‘For each fruit in my basket, I’ll take it out and take a bite.'”
In many cases, the “ForEach-Object” cmdlet is the most practical way to loop through a collection of objects. In its simplest form, it requires an input object and a script block that defines the action to perform on each item.
You can pass input either by specifying parameters directly or by piping objects into the cmdlet.
The following examples show both approaches:
$myDocuments = Get-ChildItem “$env:USERPROFILE\Documents” -File
$myDocuments | ForEach-Object { $_.FullName }
ForEach-Object -InputObject $myDocuments -Process { $_.FullName }
In some cases, you may want to run actions before or after the loop executes. The “-Begin” and “-End” parameters let you define script blocks that run immediately before or after the “-Process” block. This is useful when initializing variables or performing cleanup tasks around the loop.

PowerShell also supports loops that run based on a condition rather than a fixed number of iterations. These loops continue running based on a condition — either while it remains true or until it becomes true. Both “while” and “do-while” loops run as long as a condition evaluates to $true, while “do-until” loops run until the condition evaluates to $true.
“Do-while” and “do-until” loops share a similar structure: they begin with the do keyword followed by a script block, then end with a condition (while or until). The following examples produce the same result, only the condition is reversed:
$i = 1
Do {
$i
$i++
}
While ($i -le 10)
$i = 1
Do {
$i
$i++
}
Until ($i -gt 10)
$i = 1
While ($i -le 10) {
$i
$i++
}
Any of these loop types — “while,” “do-while” and “do-until” — can also run indefinitely. “While” and “do-while” loops will continue when the condition is set to $true, while “do-until” loops continue when the condition is set to $false.
“The key difference from ‘do-while’ is that ‘do-until’ keeps going until something becomes true, while ‘do-while’ keeps going as long as something is true,” Padisetty said.
In some situations, you may need to exit a loop early based on something other than the loop’s condition. In those cases, you can use the break keyword. The example below uses an infinite loop and exits once a condition is met:
$i = 1
While ($true) {
$i
$i++
if ($i -gt 10) {
break
}
}
Which PowerShell loop you use depends on what you’re trying to accomplish. Padisetty outlined when each loop is most appropriate.
Here’s a quick way to think about when to use each loop type:
Loop | When to use it |
|---|---|
for | Use when you know exactly how many times something should run. |
foreach | Use when you have a collection of items and want to process each one the same way. |
ForEach-Object | Use when working with a pipeline or streaming data and you want to process each item as it’s passed through. |
while | Use when you want something to keep running as long as a condition is true. |
do-while | Use when you want to run something at least once and then continue while a condition is true. |
do-until | Use when you want something to keep running until a condition becomes true. |
PowerShell loops are especially useful for automating repetitive tasks that would otherwise take up valuable time and increase the risk of human error. The following examples show how loops can streamline common business workflows.
Businesses often need to organize large volumes of files based on date, size or other criteria. This example uses a “ForEach-Object” loop to group files by year and month, helping automate routine file organization tasks.
# Organize files by date
Get-ChildItem “C:\Documents” -File | ForEach-Object {
$yearMonth = $_.LastWriteTime.ToString(“yyyy-MM”)
# Move files into folders named by year and month
}
Monthly sales reporting can be automated with “for” loops to ensure consistent formatting and full coverage across all time periods. This helps reduce the risk of missed months or inconsistent reports.
# Process monthly sales data
For ($month = 1; $month -le 12; $month++) {
# Calculate monthly totals and generate reports
Write-Host “Processing month $month sales data”
}
IT teams can use “ForEach-Object” loops to monitor multiple servers at once, helping ensure consistent health checks across systems without manual intervention.
# Monitor server health across multiple systems
$servers = @(“Server1”, “Server2”, “Server3”)
$servers | ForEach-Object {
# Check disk space, memory usage and services
Write-Host “Checking health of $_”
}
Database administrators can automate backups across multiple databases to help ensure nothing goes awry and everything follows consistent naming and storage rules.
# Backup multiple databases
$databases = Get-SqlDatabase
$databases | ForEach-Object {
# Create backup for each database
Write-Host “Backing up database: $($_.Name)”
}
Keep these guidelines in mind to build efficient, maintainable loops that hold up in real-world business environments:
Selecting the right loop helps keep your script efficient and easier to read. Here’s a guide:
Small changes inside a loop can have a big impact on performance. Consider the following:
Incorporating error handling into your loops is essential. Without it, a single failed operation can halt an entire script and disrupt automated workflows. Using a simple try/catch block helps keep things running and provides meaningful feedback when something goes wrong. For example:
$items | ForEach-Object {
try {
# Loop operations here
}
catch {
Write-Error “Error processing item: $_”
}
}
Avoid generic names like $i or $x. Instead, use descriptive names that reflect what the loop is working with, such as $service or $report.
Explain the loop’s purpose and expected behavior, and document any complex logic within it so others (and even your future self) can easily understand and maintain your script.
Verify your loop logic before running it against large datasets, and use the -WhatIf parameter when available to test changes safely.
Understanding common pitfalls can save time and help prevent system issues. Here are a few issues you may encounter and how to fix them:
# Bad: Infinite loop
While ($true) {
# Missing break condition
}
# Good: Safe loop with exit condition
$counter = 0
While ($condition -and $counter -lt 1000) {
$counter++
# Loop logic here
}
# Common mistake: Misses the last item
For ($i = 0; $i -lt $array.Length – 1; $i++) {
# Loop logic here
}
# Process files one at a time instead of loading everything into memory
Get-ChildItem -Path “C:\LargeFolder” | ForEach-Object {
# Process each file here
}
When loops don’t behave as expected, a few simple debugging techniques can help you quickly identify and fix the issue. These approaches make it easier to track what’s happening during each iteration and catch problems early.
When presenting PowerShell loop code in articles or documentation, proper formatting improves readability and helps ensure your content displays correctly across platforms:
This ensures code is clearly separated from the surrounding text and displays correctly.
# Loop from 1 to 5
for ($i = 1; $i -le 5; $i++) {
Write-Host “Number $i”
}
Adding a language label enables syntax highlighting and makes the code easier to read.
# PowerShell for loop
for ($i = 0; $i -lt 10; $i++) {
Write-Host $i
}
If you can’t use a code block, place the code in a paragraph and format it with a monospace font, a light gray background and padding to improve readability.
Use short titles to give readers context before they review the code (for example, PowerShell for loop processing an array). Add comments within the code to improve readability and help explain what each section does.
Mark Fairlie and Sean Peek contributed to this article. Source interviews were conducted for a previous version of this article.