We’re currently managing 1Password items via an afterCreate PS Rule to AD domains for customer. We need to, however, change this to only trigger on LCS changes: newValue:active
Is anyone familiar with how I can leverage the afterModify PS rule for AD conectors to trigger only when identities enter the “active” lifecycle state? I am familiar that this case is probably possible to solve using Privileged Task Automation, we do not have the “new” VA’s however and we will not be upgrading any time soon.
Current solution: afterCreate rule - triggers script on AD creation
Proposed solution: afterModify rule - triggers script on identity lifecyclestate - newValue: active
@Swegmann do you have an extensionattribute in AD that stores the ISC status of the user? If so, you could create a powershell script that triggers when it is modified to active.
@SebastianWilmsen Get the operation type in the Aftermodify script like below,
# Parse the XML request string from the environment variable
$sReader = New-Object System.IO.StringReader([System.String]$env:Request)
$xmlReader = [System.xml.XmlTextReader]([sailpoint.utils.xml.XmlUtil]::getReader($sReader))
$requestObject = New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader)
# Get the operation type (e.g., "Disable", "Modify", "Enable", etc.)
$operation = $requestObject.Operation.ToString()
# --- Your Custom Logic Here ---
# Only execute your custom logic for the 'Disable' operation
if ($operation -ieq "Enable") {
Create a new Identity attribute named as “LCS State“. Map the same transform as that attached to “CloudlifeCycleState“ identity attribute
Map this new “LCS State“ identity attribute to one the extension attributes in AD. Lets say name of extension attribute is “extensionAttribute10“
Enable the attribute sync for this
Develop a PowerShell Script which is “After Modify AD PowerShell“.
Use the logic in AfterModify PowerShell Script as below.
foreach ($attrib in $requestObject.AttributeRequests) {
LogToFile "Attr in request: Name=$($attrib.Name) Op=$($attrib.Operation) Value=$($attrib.Value)" "Debug"
if ($attrib.Name -eq "extensionAttribute10" -and $attrib.Value) {
$newLCS= $attrib.Value
LogToFile "New extensionAttribute10 from request: $newLCS"
}
}
In this way, your script and respectively child logic of Password Creation will work only when the LCS state of the user ins changed to active.
Also, using a dedicated LCS state identity attribute and mapping it to a dedicated account attribute in AD in the form of “extensionAttribute“ will not trigger this in infinite loop.
all of your replies are valid solutions, except I don’t want to provision another attribute to AD.
What I have done now is a mix of AfterCreate and AfterModify scripts. The AfterModify script only runs on enable operations, where we run the password script on the server side:
if person has already received an OTP password in the past → don’t generate a new one.
The AfterCreate script only runs if IIQDisabled = false.
AfterModify script:
$command = "C:\SailPoint\Scripts\<censored>
function Get-AccountRequestOpFromXml([string] $xml) {
if ([string]::IsNullOrWhiteSpace($xml)) { return $null }
$m = [regex]::Match($xml, '(?is)<AccountRequest\b[^>]*\bop\s*=\s*"(Create|Modify|Enable|Disable|Delete|Unlock)"')
if ($m.Success -and $m.Groups.Count -ge 2) {
return $m.Groups[1].Value
}
return $null
}
try {
# Parse request (no logging unless we actually trigger)
Add-Type -Path "utils.dll"
$sReader = New-Object System.IO.StringReader([System.String]$env:Request)
$xmlReader = [System.Xml.XmlTextReader]([SailPoint.Utils.Xml.XmlUtil]::getReader($sReader))
$requestObject = New-Object SailPoint.Utils.Objects.AccountRequest($xmlReader) | Out-Null
$requestAsString = $env:Request
# Gate: only Enable
$rawOp = Get-AccountRequestOpFromXml $requestAsString
if (-not $rawOp -or -not $rawOp.Equals("Enable", [System.StringComparison]::OrdinalIgnoreCase)) {
return
}
# From here on, we ARE doing something → start logging
$timestamp = Get-Date -UFormat "%Y%m%d_%H%M%S_%3N"
$logFile = "C:\SailPoint\Scripts\Logs\AfterModify_Enable_$timestamp.log"
function LogToFile([String] $info) {
try { $info | Out-File $logFile -Append -Encoding utf8 } catch {}
}
$uniqueId = [guid]::NewGuid().ToString()
$env:UNIQUE_ID = $uniqueId
LogToFile("[$(Get-Date -Format 'u')] AfterModify trigger matched (Enable). UNIQUE_ID=$uniqueId")
LogToFile("AccountRequest op (raw) = '$rawOp'")
# If you *really* want, log request XML here — but be careful with secrets
LogToFile("Request as XML: $requestAsString")
# Escape single quotes to avoid malformed command strings
$escapedRequest = $requestAsString.Replace("'", "''")
$fullCommand = "$command -requestString '$escapedRequest'"
LogToFile("Executing command: $fullCommand")
Invoke-Expression $fullCommand
}
catch {
# Optional: if you want *errors only* logging, create a separate error log here.
# If you prefer absolute silence on non-trigger events, keep this empty.
}