2

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 $?.

2

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.

  • Thanks seven years later this proved sage advice. – Yolo Perdiem Dec 25 '20 at 16:47
1

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.

1

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

try
{
    Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false
}
catch
{
    # 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} )

if(-not($results))
{
    # more unicorns
    Write-Host ("Something awful happened: {0}" -f $Error[0])
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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