Creating random password via PowerShell Script

Hello everyone, my client hasn’t the password module management and they want to set up randomly the first access password and send it via email. I know that Sailpoint offers 2 standard ways (without using the password module management) that we don’t like (static password, dynamic known password) because they are not secure. So we are opting to use the PowerShell script executed inside the IQServer. I know that we need to create a “Create After Rule” to call the PowerShell Script. The Powershell script should generate randonmly the password for each newly created user and than send it trough email using STMP. But how is possible to handle possible errors like mails that are not sent for some internal problems? Or how we can handle a possible problem of the SMTP server that may goes down? Anyone experienced with generating password trough PowerShell script can help me? There are some templetes available? Thanks

try-catch block is the way to capture the SMTP related errors and retry n times to send email, if the error persist you can store those users in a log file and later execute the script to send it manually. You can also do a Test-NetConnection before you perform the actual process and provide more informative log details.

thanks, do you have an example of powershell script to perform that?

Please also note that if you create a user in AD without a password, the AD account is disabled by default (which is what you want!) and so must be (and can only be) enabled after the password is set.

Also be sure to set the password flag so that user must change password after login.

thanks for your advice :), I’m currently looking for an example from anyone that has already implemented it to have a starting point :slight_smile:

This is a sample code snippet, you can build on top of it.

try {
    Send-MailMessage -To "[email protected]" -From "[email protected]" -Subject "Password Email" -Body "This is a password email." -SmtpServer "smtp.example.com" -ErrorAction Stop
} catch {
		if ($_.Exception.Message -eq "Unable to connect to the remote server"){
        #Log the required user details
    }
}

Hi @s_tartaglione

Refer this :

Might help!

Thanks

Thanks you guys, I was uploading the connector after rule in order to call properly the powershell script inside the IQService, but i’m not able to pass the script of the API for uploading the after connector rule. This is my rule, i don’t understand what is going wrong:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
 <Rule language="beanshell" name="SSetPassword AfterCreateRule" type="ConnectorAfterCreate">
  <Attributes>
   <Map>
    <entry key="ObjectOrientedScript" value="true" />
    <entry key="disabled" value="false" />
    <entry key="extension" value=".ps1" />
    <entry key="program" value="powershell.exe" />
    <entry key="timeout" value="300" />
   </Map>
  </Attributes>
  <Description>
   This is an IQService afterScript - On a successful provisioning event, this after script should be used as the starting point to
            initiate a separate PowerShell script residing on the client's IQService server.

            Configuration tasks include the following:
             - Set a proper location for the $logFile variable.
             - Set the proper script location and name for the $command variable.
             - Set the $enableDebug flag to $true or $false to toggle debug mode.
  </Description>
  <Source>
<![CDATA[

$logDate = Get-Date -UFormat "%Y%m%d"
$logFile = "c:\SailPoint\Scripts\Logs\ConnectorAfterCreate_$logDate.log"
$command = "c:\SailPoint\Scripts\ADSource-AfterCreate.ps1"
$enableDebug = $true

#====================-------Helper functions-------====================
function LogToFile([String] $info) {
    $info | Out-File $logFile -Append
}

#====================-------Get the request object-------====================
Try{
    if($enableDebug) {
        LogToFile("Entering SailPoint rule")
    }

    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);
    $requestAsString = $env:Request

    if($enableDebug) {
        LogToFile("Request as XML object is: $requestAsString")
    }

    #Call the client script
    $command = -join ($command, " -requestString '$requestAsString'")
    Invoke-Expression $command

}Catch{
 $ErrorMessage = $_.Exception.Message
   $ErrorItem = $_.Exception.ItemName
   LogToFile("Error: Item = $ErrorItem -> Message = $ErrorMessage")
}

if($enableDebug) {
    LogToFile("Exiting SailPoint rule")
}

]]>
  </Source>
 </Rule>

Hi @s_tartaglione,

This is how your rule should look like :

{
    "description": "Executes PowerShell commands on the IQService component after a source account is created.",
    "type": "ConnectorAfterCreate",
    "signature": {
        "input": [],
        "output": null
    },
    "sourceCode": {
        "version": "1.0",
        "script": "$logDate = Get-Date -UFormat \"%Y%m%d\"\r\n$logFile = \"c:\\SailPoint\\Scripts\\Logs\\ConnectorAfterCreate_$logDate.log\"\r\n$command = \"c:\\SailPoint\\Scripts\\ADSource-AfterCreate.ps1\"\r\n$enableDebug = $true\r\n\r\n#====================-------Helper functions-------====================\r\nfunction LogToFile([String] $info) {\r\n    $info | Out-File $logFile -Append\r\n}\r\n\r\n#====================-------Get the request object-------====================\r\nTry{\r\n    if($enableDebug) {\r\n        LogToFile(\"Entering SailPoint rule\")\r\n    }\r\n\r\n    Add-type -path utils.dll;\r\n $sReader = New-Object System.IO.StringReader([System.String]$env:Request);\r\n $xmlReader = [System.xml.XmlTextReader]([sailpoint.utils.xml.XmlUtil]::getReader($sReader));\r\n $requestObject = New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader);\r\n    $requestAsString = $env:Request\r\n\r\n    if($enableDebug) {\r\n        LogToFile(\"Request as XML object is: $requestAsString\")\r\n    }\r\n\r\n    #Call the client script\r\n    $command = -join ($command, \" -requestString '$requestAsString'\")\r\n    Invoke-Expression $command\r\n\r\n}Catch{\r\n $ErrorMessage = $_.Exception.Message\r\n   $ErrorItem = $_.Exception.ItemName\r\n   LogToFile(\"Error: Item = $ErrorItem -> Message = $ErrorMessage\")\r\n}\r\n\r\nif($enableDebug) {\r\n    LogToFile(\"Exiting SailPoint rule\")\r\n}"
    },
    "attributes": {
        "ObjectOrientedScript": "true",
        "extension": ".ps1",
        "sourceVersion": "1.0",
        "disabled": "false",
        "program": "powershell.exe",
        "timeout": "300"
    },
    "id": "2d93c02498184d83a6fc914a0af8a279",
    "name": "AD_Password_After_Create_Rule"
}

The piece after CDATA[ needs to be JSON escaped (I normally use Free Online JSON Escape / Unescape Tool - FreeFormatter.com) and the escaped part needs to be placed into the “script” section of the rule.

You can easily have this rule created with the VSCode extension without having to make actual API calls :

1 Like