Turn ExtendedTypeSystemException into string

1

I'm trying to turn an exception message into a string I can both throw and also write to the event manager, but having serious problems.

Have tried How can I get powershell exception descriptions into a string? this, but nothing on here works.

So this is what I use for validating credentials on a network:

$user = 'user'
$pass = 'pass'
$domain = "ldap://" + ( [ADSI]"" ).DistinguishedName

$creds = New-Object System.Management.Automation.PSCredential("$($env:USERDOMAIN)\$user", $(ConvertTo-SecureString $pass -AsPlainText -Force))

New-Object System.DirectoryServices.DirectoryEntry ($domain, $user, $creds.GetNetworkCredential().Password)

If the credentials are valid you'll get something back like :

distinguishedName : {DC=COMP}
Path              : LDAP://COMP

If there's an error, it'll be something like:

format-default : The following exception occurred while retrieving member
"distinguishedName": "Unknown error (0x80005000)"
     + CategoryInfo          : NotSpecified: (:) [format-default], ExtendedTypeSystemException
     + FullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand

About the only thing I can do with that ouput, is drop the format-default.

Any suggestions on how to get just the top line?

So far I've tried $PSItem, $_.ExceptionMessage, .ToString(), | Out-String, [string], on their own or as combinations.

powershell
asked on Stack Overflow Nov 12, 2019 by Graham Jordan • edited Nov 12, 2019 by Ansgar Wiechers

1 Answer

2

That error is a bit tricky, because it isn't thrown by New-Object, in fact, the object is created just fine. The error actually occurs at the point where PowerShell tries to display the object on the console and cannot find a property that the default display format for the object requires (in this case DistinguishedName). Hence it cannot be caught by putting the New-Object in a try..catch statement.

The error does appear in the automatic variable $error after it occurred, so you could check $error[0] for more information (e.g. use $error[0].Message to get just the error message), but you cannot suppress the error message without keeping the error from occurring in the first place (because it only occurs upon trying to display the object).

A better approach might be to capture the created object in a variable and then check for the presence of the property DistinguishedName.

$o = New-Object DirectoryServices.DirectoryEntry ($domain, $user, $pass)
if ($o.DistinguishedName) {
    'Invalid credentials'
}

BTW, creating a secure string from a plaintext password and then decrypting that again because you need the password in plain text is quite pointless.


Edit:

I looked into this issue some more and if for some reason you must get the actual error message from PowerShell's default output formatting, you can do it like this:

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

try {
    $o | Out-Default
} catch {
    $_.Exception.InnerException.Message
}
answered on Stack Overflow Nov 12, 2019 by Ansgar Wiechers • edited Nov 13, 2019 by Ansgar Wiechers

User contributions licensed under CC BY-SA 3.0