I have implemented custom web services to generate a passcode. Two different methods (reset password, unlock account) will use this passcode.
The script code is slightly the same as described in the SDK.
I have developed and tested the webservices in a native AD environment. The following URLs will work fine:
localhost/.../spc
localhost/.../spc
But the same webservices in a AD LDS will not work. An error occured while the codeline "$connection = $global.GetDirectoryConnectionByName($domain)" is executed.
The variable $domain contains the value for the connected domain to PWM.
localhost/.../spc
localhost/.../spc
I don't know where is is the error. A service request was not helpful, the answer was "We do not support the SDK or any of the sample scripts "
Here is the complete powershell scriptcode:
try {
#----------Constants----------
#Passcode length
$PASSCODE_LENGTH = 12
#Passcode lifetime in minutes
$PASSCODE_LIFETIME = 1440 #(1 day)
#Uncomment these lines to send e-mail to a user, if he has e-mail address
#Variable $PASSCODE will contain user's passcode, all other variables are available too
#$EMAIL_SUBJECT = 'Passcode'
#$EMAIL_BODY = 'Your passcode is $PASSCODE'
#Set this parameter to $true to produce a more verbose XML-formatted output
#Set this parameter to $false to output just a passcode
$XML=$false
#----------Web service body----------
$log = @()
#Parse request parameters - domain and user name
$domain = $Request.QueryString["domain"]
$userName = $Request.QueryString["user"]
$requestType = $Request.QueryString["request"]
#If parameters are missing, throw an exception
if ("$domain" -eq "") {
throw "Domain not specified!"
}
if ("$userName" -eq "") {
throw "User name not specified!"
}
if ("$requestType" -eq "") {
throw "Request type not specified!"
}
#Obtain Password Manager connection to the specified domain
$connection = $global.GetDirectoryConnectionByName($domain)
#If there is none, throw an exception
if ("$connection" -eq "") {
throw "Connection to domain $domain not found in Password Manager!"
}
$log += "Found connection to domain $domain, alias=$($connection.AliasName)"
#Find user by name in the specified domain
#$user = $global.GetUserByName($connection, $userName, [string[]]("objectGUID", "mail"))
#Find user by mail in the specified Domain
$userattribute = 'mail'
$user = $global.GetUserByAttribute($connection, $userattribute, $userName, [string[]]("objectGUID", "mail", "samaccountname","description"))
#If user not found, throw an exception
if ($user -eq $null) {
throw "User $userName not found in domain $domain!"
}
$log += "Found user $userName in domain $domain, GUID=$($user.objectGUID)"
#Obtain user's GUID
$userId = $user.objectGUID
#Generate a passcode for a user
$PASSCODE= $global.GeneratePasscode($PASSCODE_LENGTH)
$log += "Generated passcode $PASSCODE"
#Assign passcode to a user
$global.QAProfileAssignPasscode($connection, $userId, $passcode, $PASSCODE_LIFETIME)
$log += "Passcode assigned to user $userName"
if ($EMAIL_SUBJECT -ne "" -and $EMAIL_BODY -ne "")
{
#Send e-mail with passcode, if user has an e-mail address
if ($user.mail -ne "")
{
$log +="Sending passcode to $($user.mail)"
$subject = $ExecutionContext.InvokeCommand.ExpandString($EMAIL_SUBJECT)
$body = $ExecutionContext.InvokeCommand.ExpandString($EMAIL_BODY)
$global.EmailUserHtml($mail, $subject, $body)
}
else
{
$log +="User account has no mail, will not send e-mail with passcode"
}
}
$log += "Passcode assignment completed successfully"
#$URL = "localhost/.../EntryPoint + $userName + "&IdentificationDomain=" + $Domain + "&WorkflowId=EA71182A-AD10-4A0B-AD1D-E1E7BC9331B8&Passcode=" + $passcode
#URL to use the passcode to generate a temp Password and Change it in Domain without workflow
#$URL = "localhost/.../uc +$userName + "&domain=" +$Domain + "&passcode=" + $passcode
if ("$requestType" -eq "unlock") {
$URL = "localhost/.../ua +$userName + "&domain=" +$Domain + "&passcode=" + $passcode
}
if ("$requestType" -eq "reset") {
$URL = "localhost/.../rpt +$userName + "&domain=" +$Domain + "&passcode=" + $passcode
}
if ("$requestType" -ne "unlock" -and "$requestType" -ne "reset") {
throw "Request type: $requestType unknown!"
}
$log += $URL
#Output response
if ($XML) {
#Set Content-Type header to XML for XML output
$Response.Headers.Add("Content-Type", "text/xml")
#Generate an XML document
$doc = [xml]"<Response><Passcode/><Log/></Response>"
$doc.Response.Passcode = $PASSCODE
$logElement = $doc.SelectSingleNode("//Log")
$log | %{
$entry = $doc.CreateElement("Entry")
$entry.InnerText = $_
$logElement.AppendChild($entry)
}
#Output response
$Response.Write($doc.InnerXml)
}
else
{
#Set Content-Type header to plain text for output
$Response.Headers.Add("Content-Type", "text/plain")
#Output passcode
$Response.Write($PASSCODE)
$Response.Write([char]13)
$Response.Write($URL)
}
} catch {
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$Response.Write($ErrorMessage + " " + $FailedItem)
}