Catching Password Complexity Errors from Set-ADAccountPassword within SMA

Most of the time, I’d like to figure out complete solution before publishing a blog post. There are times however where an error doesn’t make sense to me…..this is one of those times.

$strClientUser="samaccountname"
Try{
    $inSecNewPassword = "Password"
    $secNewPassword = ConvertTo-SecureString -String $inSecNewPassword -AsPlainText -Force 
    #Try set password
    Set-ADAccountPassword -Identity $strClientUser -NewPassword $secNewPassword -Confirm:$false -reset -ErrorAction Stop
}Catch [Exception]{
        "Password doesn't meet complexity requirements"
}

This code works as expected in native powershell….
This code also works as expected in a PS Workflow….
This code does NOT work in a Service Management Automation PS Workflow.

When this code is run within a SMA workflow, the error displayed but never caught. This is not an issue with Try{}Catch [Exception]{} blocks in SMA….I have used them plenty of times (like if a file is in use). So what happens if we modify the code a little and be a little more specific about what error we want to catch:

$strClientUser="samaccountname"
Try{
    $inSecNewPassword = "Password"
    $secNewPassword = ConvertTo-SecureString -String $inSecNewPassword -AsPlainText -Force 
    #Try set password
    Set-ADAccountPassword -Identity $strClientUser -NewPassword $secNewPassword -Confirm:$false -reset -ErrorAction Stop
}Catch [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException]{
        "Password doesn't meet complexity requirements"
}

Once again, this works as expected in native powershell….
This code also works in a PS Workflow….
This code now fails with an error that may be a little more helpful in SMA:

Runbook definition is invalid. Could not find type Microsoft.ActiveDirectory.Management.ADPasswordComplexityException. Load the type(s) and try again.

This would make sense why our exception is never caught…..SMA doesn’t know what to do with it….

Now we could always throw it into an inlinescript{} and it would work….but I want to keep my runbook as a workflow if possible…even if it is just for the speed gain.

Here is another example that works quite fine as an inlinescript:

#Try set the password
$inSecNewPassword = "Password"
$secNewPassword = ConvertTo-SecureString -String $inSecNewPassword -AsPlainText -Force 
$hashReturn = InlineScript{
            Try{    
                $credADAM = $Using:credCredential
                $strClientUser = $Using:strClientUser
                $secNewPassword = $Using:secNewPassword
                $ReturnValue = Set-ADAccountPassword -Identity $strClientUser -NewPassword $secNewPassword -Confirm:$false -reset -Credential $credADAM -ErrorAction Stop
                $strReturn = "Successfully set user password for ${strClientUser}"
                $strSeverity = "Informational"
                $boolError = $false
            }Catch [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException]{
                $boolError = $true
                $strException = $_.Exception.Message
                $strReturn = "Error: Unable to set user password for ${strClientUser}...with error ${strException}"
                $strSeverity = "Error"
            }
            Return @{"boolError" = $boolError; "strReturn" = $strReturn; "strSeverity" = $strSeverity}
        }
        $boolError = $hashReturn.boolError
        $strReturn = $hashReturn.strReturn
        $strSeverity = $hashReturn.strSeverity

So the question becomes…..how do we import the correct type information into our workflow so that we can capture the correct error? Please feel free to comment with your thoughts on this. I’ll also post back if I figure this out….


 

Update Feb 24 with another work around
I stumbled across another work around for this. Rather than adding “-ErrorAction Stop” after the “Set-ADAccountPassword” command (which doesn’t work), I did have success setting my global error action preference to Stop and then resetting it back to the previous value:

    $strClientUser="samaccountname"
    $OldErrorActionPref = $ErrorActionPreference; $ErrorActionPreference = "Stop";
    Try{
        $inSecNewPassword = "Password"
        $secNewPassword = ConvertTo-SecureString -String $inSecNewPassword -AsPlainText -Force
        #Try set password
        Set-ADAccountPassword -Identity $strClientUser -NewPassword $secNewPassword -Confirm:$false -reset -ErrorAction Stop
    }Catch [Exception]{
            "Password doesn't meet complexity requirements"
    }
    $ErrorActionPreference = $OldErrorActionPref

This is still crumby, but should allow you to eliminate a few more inline scripts from your runbooks.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s