Hiding Warnings in dbatools.

Words: 726

Time to read: ~ 4 minutes

Warning by default

dbatools warns by default.

From what we’ve seen, beginners to PowerShell do not want to be greeted by a sea of red when they use, mis-use, or abuse a dbatools command.

PowerShell errors normally contain useful information on what went wrong. With this information, the “what went wrong” can be fixed.

That being said, if you are writing PowerShell scripts and not raising valid error messages then I highly advise you to go back and fix that.

dbatools raises these error messages as friendly warning messages since we’ve found people will read a warning message quicker than they will read an error message.

Enabling Errors.

dbatools has a common parameter called -EnableException which changes this behaviour. When you use this switch parameter with a dbatools command, it should change the lovely, user-friendly warning to a lovely-but-unfairly-treated error message.

Here is the default process that raises a warning.

# Get the first backup from this path.
$BackupPath = (Get-ChildItem -Path D:\BACKUPS\ -Filter *.bak)[0]

# Restore it to a SQL Server instance that does not exist.
$BackupPath | Restore-DbaDatabase -SqlInstance DoesNotExist -OutputScriptOnly
Works on PowerShell 7.0

Here is the process when we use -EnableException that raises an error.

# Restore to a SQL Server instance that does not exist with errors.
$BackupPath | Restore-DbaDatabase -SqlInstance DoesNotExist -OutputScriptOnly -EnableException
Even shows the line.

Hiding the messages.

Depending on whether you use the default parameters or add in -EnableException parameter, you have ways to hide these messages.

Hiding default warnings

# Create a splat to save me typing over and over again.
$RestoreParam = @{
    SqlInstance      = 'DoesNotExist'
    OutputScriptOnly = $true
}

# Warnings actions
$WarningToDo = @{
    WarningAction   = 'SilentlyContinue'
    WarningVariable = 'RestoreWarning'
}

# Hide and capture the warning.
$BackupPath | Restore-DbaDatabase @RestoreParam @WarningToDo
Warning! Warning!

Here we can see that the warning message was not output but it was captured to our variable called “RestoreWarning”.

Hiding Errors

Errors are slightly different and I’ll show you why, although you can do the same thing, I use a try ... catch ... block instead.

I also don’t try and hide errors but relay them out.

try {
    $BackupPath | Restore-DbaDatabase @RestoreParam -EnableException
} catch {
    "Error happened! Here is the error message"
    $_
}
Try and catch

I was originally worried that the above method meant that you couldn’t reference the error that just occurred like we could with the warning methods and $RestoreWarning but I had forgotten about the $error variable!

# What was the latest error that we had?
$Error[0]
Tada

I highly recommend that you capture that latest error message though $RestoreError = $Error[0] because the next error will be put on that stack and our error will be pushed down!

Hide the error

However, you can hide the error message that is raised by either an empty catch block or an -ErrorVariable.

Empty catch block

Please don’t do this.

I’m happy that PSScriptAnalyzer has a way to check for empty catch blocks so it is incentive to not do this. However it is possible.

# Empty catch = Boo!
try {
    $BackupPath | Restore-DbaDatabase @RestoreParam -EnableException
} catch {

}
Nothing!

Do I like it? No. It is possible? Yes.

ErrorVariable

I mentioned that capturing errors with -ErrorVariable is a bit different and I’m going to show you why.

First let’s show that using -ErrorVariable can work to capture the error stream and stop it showing on the console.

$BackupPath | Restore-DbaDatabase @RestoreParam @ErrorsToDo -EnableException
Captured!

And now here is the difference between -WarningVariable and -ErrorVariable.

# Count the number of objects in these variables.
$RestoreWarning.Count
$RestoreError.Count
order by int or string, it works…

Let’s take a look at $RestoreError so.

2 different types of objects
All the info

If you are wondering why this is I believe it’s because when we use -WarningVariable method we are letting dbatools do the commands, bubble up the main error into a single warning, and then we are capturing that warning message.

When we use -ErrorVariable method, we are saying “give me everything”, there is no bundling happening, and we are seeing all the errors that occur – including internal functions and cmdlets that dbatools use.

All in All

I like the way that dbatools shows errors as warnings by default for everyday and beginning users.

I appreciate the fact that dbatools allows us to turn of that behaviour for our scripts and tool making purposes.

However, if you want nothing, you can have that too.

Finally, like everything, know your tools so you can get the most use out of them!

Author: Shane O'Neill

DBA, T-SQL and PowerShell admirer, Food, Coffee, Whiskey (not necessarily in that order)...

2 thoughts on “Hiding Warnings in dbatools.”

Leave a Reply

%d bloggers like this: