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