none
DirectoryService object error not catched neither trapped RRS feed

  • Question

  • This is part of my script:

    Trap {Write-Output 'Authentication Error trapped'}
    Try {New-Object System.DirectoryServices.DirectoryEntry $strDistinguishedName,$strUsername,$strPlainPassword -ErrorAction stop}
    Catch{Write-Output 'Authentication Error catched'}
    Write-Output 'Script has not trapped nor catched the error but continued'

    The error is just terminating the script and I found no way to catch or trap the error.

    The script does even not write the last line which means it has completely exited the script.

    Here is the whole output:

    PS C:\Temp> & .\test.ps1
    format-default : The following exception occurred while retrieving member "distinguishedName": "Logon failure: unknown user name or bad password.
    "
        + CategoryInfo          : NotSpecified: (:) [format-default], ExtendedTypeSystemException
        + FullyQualifiedErrorId : CatchFromBaseGetMember,Microsoft.PowerShell.Commands.FormatDefaultCommand
    
    PS C:\Temp>

    The error type is:

    PS C:\Temp> $Error[0].GetType()
    IsPublic IsSerial Name                                     BaseType                                                                                                                                                             
    -------- -------- ----                                     --------                                                                                                                                                             
    True     True     CmdletInvocationException                System.Management.Automation.RuntimeException                                                                                                                        
    PS C:\Temp> 

    I tried :

    • Catch or Trap [System.Exception]
    • Catch or Trap [System.Management]
    • to remove the -ErrorAction parameter
    • to use the $ErrorActionPreference variable

    Has anybody an idea?

    Friday, March 31, 2017 4:19 PM

Answers

  • This is how you would have to do this:

    Try { 
    	if($adsiobject = New-Object System.DirectoryServices.DirectoryEntry( $strDistinguishedName, $strUsername, $strPlainPassword)){
    		Write-Host 'Script found object'
    		$adsiobject  # this will throw an exception if the call failed.
      Write-Host 'object is good.' }else{ Write-Host 'AD object not found' } } Catch { Write-Host $_
    }


    \_(ツ)_/






    • Edited by jrv Friday, March 31, 2017 6:13 PM
    • Marked as answer by Luc Fullenwarth Saturday, April 1, 2017 6:59 PM
    Friday, March 31, 2017 6:05 PM

All replies

  • I am not certain of the exact cause, but my guess is that the error occurs after the try/catch (you shouldn't combine trap with try/catch) when PowerShell attempts to output the object. That is, the object create doesn't fail (no error to catch there), but when it tries to outputs the object, then the error occurs.

    -- Bill Stewart [Bill_Stewart]

    Friday, March 31, 2017 4:32 PM
    Moderator
  • Hello Bill,

    I first tried Try/Catch, then I tried Trap, and because none worked I tried with both.

    Normally, one should take over the other.
    Being mutual exclusive seems not to be the problem.


    Friday, March 31, 2017 4:51 PM
  • This is how you would have to do this:

    Try { 
    	if($adsiobject = New-Object System.DirectoryServices.DirectoryEntry( $strDistinguishedName, $strUsername, $strPlainPassword)){
    		Write-Host 'Script found object'
    		$adsiobject  # this will throw an exception if the call failed.
      Write-Host 'object is good.' }else{ Write-Host 'AD object not found' } } Catch { Write-Host $_
    }


    \_(ツ)_/






    • Edited by jrv Friday, March 31, 2017 6:13 PM
    • Marked as answer by Luc Fullenwarth Saturday, April 1, 2017 6:59 PM
    Friday, March 31, 2017 6:05 PM
  • Note also that the call does not use DistinguishedName it uses LDAP Path,  Add "LDAP://" to the name.


    \_(ツ)_/

    Friday, March 31, 2017 6:20 PM
  • Sadly, because the object returned is only boolean, there is no way to make the distinction between a non-existent object, a bad username or a bad password.
    Saturday, April 1, 2017 7:02 PM
  • Not at all true.   The account either exists or doesn't.

    You can also use account searcher.

    add-type -AssemblyName System.DirectoryServices.AccountManagement
    
    $pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
    	'Domain',
    	'Testnet',
    	'dc=testnet,dc=local',
    	'Negotiate',
    	'testnet\administrator',
    	'AdminPassWord'
    )
    try {
    	[System.DirectoryServices.AccountManagement.Principal]::FindByIdentity($pc, $usertofind)
    }
    Catch{
    	Write-Host $_
    }
    

    .


    \_(ツ)_/

    Saturday, April 1, 2017 8:20 PM
  • Woaow JRV!!!

    With your answer, you led me directly to an object which is exactly achieving  what I was seeking for...

    In fact I didn't want to search a user in Active Directory, but only validate credentials.

    Now I can do this, and it works fine for me:

    Add-Type -AssemblyName System.DirectoryServices.AccountManagement
    
    $objContextType=[System.DirectoryServices.AccountManagement.ContextType]::Domain
    $objADConnector=New-Object System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $objContextType,$strDomainControllerFQDN,$strDomainName
    $objADConnector.ValidateCredentials($strUsername,$strPlainPassword)

    Many thanks JRV!

    Tuesday, April 4, 2017 1:42 PM