Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How do I check for the success/failure of a pipeline from within the same executing script?

Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false

I don't need anything more than the equivalent of $?.

share|improve this question
up vote 2 down vote accepted

Agree with the try...catch approach, but the if ($?) {} works well too, but won't catch exceptions that would normally throw the script completely.

Either way, one of the strengths of PowerShell is also one of its weaknesses. I'm talking about pipelining. Yes, it's great that you can pass objects down the pipe, but when you're script is running in production, and you need to gracefully fail, create a meaningful log, return a meaningful return code, possibly SMS the person on standby and maybe even run a recovery job, a pipeline that has just barfed on the 50th object it came across, when there's another 70 to go isn't of much use.

In a production script, I'd strongly recommend staging your "pipe work". That is, use the power of the pipeline to gather your work queue (Get-VM | Where-Object, blah, blah), and shove this into an array of objects.

Then use a Foreach-Object to step through the objects in your work queue. Within the Foreach-Object, use your try...catch when it comes to things like Remove-Snapshot, and interrogate the returned exception object in order to provide your return code / log file / alert / recovery sequence, etc.

share|improve this answer

Well, Powershell has $?, so I'm assuming the problem is that it only populates on exit?

When you're dealing with errors in running code, the best practice is to use a Try/Catch block. Code inside a "Try" block will automatically fail over to "Catch" in the event of problems, and, even better, you can have different catch blocks for different exceptions, so you can handle different problems on the fly. Very cool.

share|improve this answer

As already pointed out, the safe approach is to use Try/Catch blocks:

    Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false
    # Rainbows, unicorns and error handling here

If you're assigning the output to a variable and want to test the output yourself, you can put the try/catch block in a subexpression, and have it default to $null or $false upon failure, like this:

$results = $( try{Get-Something "MaybeNonexisting"} catch{$false} )

    # more unicorns
    Write-Host ("Something awful happened: {0}" -f $Error[0])
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.