Powershell Try Catch invoke-sqlcmd - powershell

I am having problems catching an error in PowerShell when a connection fails to a SQL Server using Invoke-Sqlcmd. This is some generic code to demonstrate the issue:
CLS
$server = "Localhost\fake"
try
{
Invoke-Sqlcmd -Query "SELECT DB_NAME() as [Database]" -Server $server
}
catch
{
Write-Host "Error connecting to server " $server
}
I get the following error:
Invoke-Sqlcmd : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name
is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
I was expecting to get the one line statement: "Error connecting to server Localhost\fake"

It would appear that error is considered non-terminating which is a bit odd. Try the Invoke-SqlCommand with an additional parameter: -ErrorAction Stop. If there error is non-terminating, this will convert it to a terminating error that you can catch.

Posting additional info to supplement the answer by #KeithHill as an answer since it is too long for a comment.
If the error record was created by the Write-Error commandlet it is non-terminating and subject to the behavior specified by the -ErrorAction argument or the $ErrorActionPreference system variable. Errors using throw are terminating. See the documentation for Write-Error (Note that PowerShell 4.0 and below do not have the -Exception parameter mentioned in the web page.) and about_Throw in the PowerShell help system.
If you want to add custom error information and make it a terminating error, throw from your catch block as follows:
catch
{
throw (New-Object System.Exception "Error connecting to server $($server).", $_.Exception)
}
You can use Write-Error if you want termination to behave as specified by the -ErrorAction argument. In PowerShell 4.0 and below the Write-Error commandlet does not allow a -Exception argument and therefore will not provide an InnerException. That means that the caller would have to examine the collection in the $Error system variable if it needs to determine the original exception. In later versions you can Use Write-Error -Message "Some additional error information." -Exception $_.Exception in your catch block.

Try
CLS
$server = "Localhost/fake"
try
{
Invoke-Sqlcmd -Query "SELECT DB_NAME() as [Database]" -Server $server
}
catch
{
$_ | Out-Null
Write-Host "Error connecting to server " $server
}
This will capture the error and redirect it to null and display your write-host

Related

How can I check internet connection with PowerShell

I have a PowerShell script that need to check if there is internet connectivity before running the rest of the script. For the example using Test-Connection
if (Test-Connection example.com) {
Write-Host "Connection available"
# do-other things
} else {
Write-Host "No internet connection"
Exit
}
The problem with this approach is if there is no connection it gives this error message:
Testing connection to computer 'example.com' failed: Cannot resolve the | target name. and then the actual message follows No internet connection but the idea was to have it move to the else clause not giving that error message when there no connection.
For example when there is no internet connection the error message No internet connection is printed, that's it, nothing else. How can I achieve this.
Test-Connection doesn't seem to have something that we can catch with try-catch, but there is a -Quiet parameter that may do what you want. It translates the output to a simple boolean.
Testing without and with an internet connection:
Per #mukunda's answer, Test-Connection has a -Quiet switch that ignores errors and returns a boolean result - see the documentation for Test-Connection for the details.
Note there's some perhaps unexpected behaviour if you're testing multiple sites in a single call:
If any ping to a given target succeeds, $True is returned
In other words, even if some sites fail you'd still get $true returned.
Note that in general you can also suppress errors in cmdlets with -ErrorAction "SilentlyContinue", and check the return value after:
$result = Test-Connection -Ping "www.example.org" -ErrorAction "SilentlyContinue";
if ($null -eq $result)
{
Write-Host "No internet connection"
Exit
}
else
{
Write-Host "Connection available"
# do-other things
}

Powershell Try Catch on Get-Printer

I have a little function to get all printer objects from a print server, the cmdlet throws an error if the spooler service is not available (e.g. the hostname is wrong). I want to catch that error message with a try catch, but it wont catch? Can someone explain this behavior to me?
Code:
Function GetAllPrinters
{
param
(
[Parameter(Mandatory=$true)]
[string]$PrintServerHostName
)
try {
$Printers = Get-Printer -ComputerName $PrintServerHostName
}
catch {
Write-Host "Could not receive information from the print server $PrintServerHostName."
exit 1001
}
return $Printers
}
Error Message:
Get-Printer : Der Spoolerdienst ist nicht erreichbar. Stellen Sie sicher, dass der Spoolerdienst ausgeführt wird.
In C:\Users\f.zedler\Desktop\GetPrintServerStatus.ps1:34 Zeichen:21
+ $Printers = Get-Printer -ComputerName $PrintServerHostName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (MSFT_Printer:ROOT/StandardCimv2/MSFT_Printer) [Get-Printer], CimException
+ FullyQualifiedErrorId : HRESULT 0x800706ba,Get-Printer
You're running into the concept of a Terminating versus a non-terminating error.
Some functions can throw an error but still continue without any issues, they might just throw an error to the error stream and keep on trucking. We'd call these a non-terminating error.
Others could leave you in a bad situation or cause issues, and it'd be better for them to error and stop. We call these terminating errors.
Terminating error have the nice value-add in that they are capable of triggering a try/catch block, while most other errors will not.
This function seems to be throwing a non-terminating error, which ignores try/catch blocks. You can override this though, by specifying a choice for -ErrorAction, which is a common parameter, one that's available for all cmdlets.
Your choices are this:
Inquire - ask you to continue or not
Continue - keep on trucking but write out error messages
SilentlyContinue - keep on trucking but sweep the error under the rug (silently!)
STOP - this is the one you want
So, in conclusion, since it looks like your function is ignoring your try/catch block, try and add -ErrorAction STOP. That will probably solve this problem.
Get-Printer -ErrorAction Stop
Try it with Get-Printer -ComputerName $PrintServerHostName -ErrorAction Stop or set $erroractionpreference to stop.
FYI
on my script below, I had to move the "-erroraction stop" option before the first pipe symbol.
$e=Get-Printer -ComputerName $lbpclist.SelectedItem -ErrorAction stop | Where-Object {$_.Name -like $txtPrinterName.Text

Power Shell Error Trapping

I can't figure out why powershell will not trap errors when running a script against office365 (Exchange online). I receive the raw error message each time, despite my try and catch blocks.
Foreach ($groups in $groups)
{
try
{
Add-DistributionGroupMember "$Groups" -Member "$UserName" -BypassSecurityGroupManagerCheck -ErrorAction Stop
#write-host "Added user $userName to $Groups";
}
Catch
{
Write-Output "`t $userName is already a member of $Groups."
}
}
Having the same issue here. We're seeing the error block but not the custom error message in the catch.
I need to trap when users can't be added (couldn't find the user) or any other specific error and dump these accounts to a CSV file...
EDIT:
Of course the moment I post this I find the answer... Adding -ErrorAction STOP makes it work properly, otherwise it simply shows the message and I guess doesn't return an errorcode... The actual message can be caught using this Catch
Catch{
Echo $User $_.exception.Message
}

try, catch doesent seem to work

I have the following code which I thought would allow me to catch an error and instead of generating the error write out "An Error Occurred".
Unfortunately, it still shows the error "Failed to restart the computer: Access is denied" instead.
I know why this is happening but I want to be able to catch the error and reformat it. What am I doing wrong?
try {
Restart-Computer -ComputerName MFG-KY-PC74 -Force
} catch {
Write-Host "An Error Occurred"
}
In PowerShell there are terminating and non-terminating errors. The former terminate script execution (if not caught) and can be caught by try..catch, the latter don't terminate script execution (so there's nothing to catch). The error you're receiving is a non-terminating one, so you need to make it a terminating error by appending -ErrorAction Stop to the statement:
try {
Restart-Computer -ComputerName MFG-KY-PC74 -Force -ErrorAction Stop
} catch {
write-host "An Error Occurred"
}
Alternatively you can set $ErrorActionPreference = "Stop" if you want all errors to become terminating errors.
See this article on the Scripting Guy blog for more information.

Exchange anagement Shell catch enable-mailbox error

I have script that creates user accounts and establishes an e-mail address for those accounts. All 'create-commands' are surrounded by a try/catch block to catch errors and add a message to the output log. This works fine... except for the enable-mailbox command
try {
Enable-Maibox (.. parameters ...)
}
catch {
$errorsEncountered = $true
Write-Output "Error establishing e-mail address for $($UserData.username)"
}
when the enable-mailbox command fails... the catch-part is skipped. Why is this? And how can I fix this?
Non-termineting errors are not catched. Use '-ErrorAction Stop' to make the errors terminating errors.
Enable-Maibox (.. parameters ...) -ErrorAction Stop
I could be wrong but "Enable-Maibox" looks mis-spelled.