Tee-Object

Unlocking the Power of Tee-Object in PowerShell

Welcome back to Wahmans PowerShell Blog! Today we’re diving deep into a handy cmdlet that every PowerShell user should have in their toolbox — Tee-Object. This cmdlet may seem simple at first glance, but with a bit of creativity, it can become a versatile tool for both debugging and scripting automation.

The official description from Microsoft states:

Tee-Object saves command output in a file or variable and also sends it down the pipeline.

So what does this really mean? Think of Tee-Object as a way to create a “copy” of the output mid-pipeline so you can store it for later — in a file or a variable — while still passing it along for further processing. This is particularly useful when you want to log output without disrupting your pipeline workflow.

Beginner to Advanced Examples

1. Out-File Alternative for Logging

Let’s say you’re listing all services and want to save the output while continuing to pipe it to another command. Here’s how it works:

Get-Service | Tee-Object -FilePath .\services.txt | Where-Object { $_.Status -eq 'Running' }

This saves the entire list of services to services.txt, but still allows you to filter and process only running services.

2. Saving Output to a Variable While Continuing the Pipeline

$runningServices = Get-Service | Tee-Object -Variable allServices | Where-Object { $_.Status -eq 'Running' }

This stores all services in $allServices, while continuing the pipeline to store the filtered subset in $runningServices.

3. Logging While Formatting Output

This approach logs raw data to a file but displays clean, formatted output to the console:

Get-Process | Tee-Object -FilePath .\processLog.txt | Sort-Object CPU -Descending | Select-Object -First 10 | Format-Table Name, CPU -AutoSize

You get the top CPU-consuming processes in a nice table, while still keeping a full log of all processes.

4. Debugging Complex Pipelines

During script development, you may want to inspect data mid-pipeline:

Get-ChildItem -Recurse | Where-Object { !$_.PSIsContainer } | Tee-Object -Variable files | Where-Object { $_.Length -gt 1MB }

This lets you capture all files in $files before continuing on to filter those larger than 1MB.

Wrap-Up

Tee-Object is much more than just a command for saving log files — it’s a way to build more maintainable, debuggable, and understandable PowerShell pipelines. Use it to capture data mid-flow without breaking your pipeline logic.

Happy scripting, and I will see you in the next post!

Leave a Reply

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