1

I am trying to catch an error nicely, as I would do in Java. The program is similar to this:

try
{
    New-Object System.DirectoryServices.DirectoryEntry($SearchString, $username, $pass)
    Write-Ouput "Continue program"
}
catch
{
    Write-Output "Some error"
}

The exception is never captured. In fact, the catch method executes when everything goes well. From the different errors I can get, it doesn't look like an exception is raised:

format-default : The following exception occurred while retrieving member "distinguishedName": "The server is not operational.
"
    + CategoryInfo          : NotSpecified: (:) [format-default], ExtendedTypeSystemException
    + FullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand


format-default : The following exception occurred while retrieving member "distinguishedName": "The user name or password is 
incorrect.
"
    + CategoryInfo          : NotSpecified: (:) [format-default], ExtendedTypeSystemException
    + FullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand
 

How can I capture these errors in a more user-friendly way?

Maybe in this case it is not possible.


After some testing, I think the problem is that no exception is raised for some reason, despite of what the error message says. So that is why I can't capture it. I have also tried to use getType, close and other methods but I get the same error:

The following exception occurred while retrieving member "GetType": "The user name or password is incorrect.
"
...

This solution does not seem to work either, same behaviour.

Question related.

user1156544
  • 1,725
  • 2
  • 25
  • 51

4 Answers4

0

need add 'erroraction'

try

    {
        New-Object System.DirectoryServices.DirectoryEntry($SearchString, $username, $pass) -ErrorAction Stop
        Write-Ouput "Continue program"
    }
    catch
    {
        $Err = $error[0]
        Write-Output $Err.Exception
    }
OlegK
  • 1
  • 1
  • Mmmm... I placed the `-ErrorAction` option, but still not going to the `Catch` block. It shows the error as usual – user1156544 Oct 06 '20 at 17:40
0

You could also just default back to this...

If ($(New-Object System.DirectoryServices.DirectoryEntry($SearchString, $username, $pass)) -eq $false)
{Write-Verbose 'Continue program' -Verbose}
Else {Write-Warning -Message 'Something went wrong with your directory command'}
# Results
<#
WARNING: Something went wrong with your directory command
#>

... though like you try/catch is my preference. I am not in an ADDS environment to test the try/catch one at this time.

Know that you are not the only one stressed out by this. See: Powershell DirectoryService object error neither caught nor trapped

Yet, after a bit of digging at my notes on ADDS (ADSI stuff from back in the day) in the past, here's the real deal on this namespace. The result is not really $true or $false, unlike System.DirectoryServices.AccountManagement; with what you are using, is provided with incorrect credentials you get the error. If the credentials are correct the returned object will contain a valid result, the result is Boolean output.

So, if you really want to stick with Try/Catch, do this instead:

try
{
    $AuthResult = [bool](New-Object System.DirectoryServices.DirectoryEntry($SearchString, $username, $pass)).distinguishedName -ne 'False'
    'Continue program'
}
catch {Write-Warning -Message 'Bad credentials passed'}
# Resuls
<#
WARNING: Bad credentials passed
#>

You of course, if so inclined you can trap error data and output as needed.

Yet, that is not much different than what the check provided in the If/Then. So, your choice.

postanote
  • 15,138
  • 2
  • 14
  • 25
  • It is not about formatting the error, it's about capturing the error. I tried your code, whose `try` block is the same as mine, and on error it does not go to the catch block. It prints the error – user1156544 Oct 06 '20 at 17:42
  • Even with the `$ErrorActionPreference = 'Stop'` I'm still getting the error and not executing my catch.. Anyway this seems the same as using the `-ErrorAction Stop` as in the other answer, which dodn't work either. Is it possible that this kind of error has to be treated differently? – user1156544 Oct 06 '20 at 18:03
0

I managed to do it with this solution:

$o = New-Object DirectoryServices.DirectoryEntry ($path, $user, $pass)

if ($path -eq 'LDAP://') { 'Computer is not member of a domain.' } elseif ($o.DistinguishedName) { 'Invalid user credentials.' } But if for some reason you must retrieve the actual error message, you can do it like this:

$o = New-Object DirectoryServices.DirectoryEntry ($path, $user, $pass)

try { $o | Out-Default } catch { $_.Exception.InnerException.Message }

user1156544
  • 1,725
  • 2
  • 25
  • 51
0

This worked for me. The object will instantiate even though there might be an error that won't show up until you try to use it later. Using this, you can set a boolean to whether the distinguishedName was set or not:

$Entry = New-Object System.DirectoryServices.DirectoryEntry($SearchString, $username, $pass)
$succeeded = [bool]$Entry.distinguishedName
if ($succeeded)
{
     Write-Ouput "Continue program"
}
else
{
     Write-Output "Some error"
}
KoZm0kNoT
  • 462
  • 6
  • 9