Script Repository


Users Password Self-Service information

October 10, 2019
1461

This script e-mails a report on all users and includes information about Password Self-Service enrollment. To schedule the report, create a Scheduled Task configured for the Domain-DNS object type.

Parameters:

  • $ouDNs - Specifies the distinguished names (DNs) of the Organizational Units in which users must be located to be included into the report. For infortion on how to get the DNs, see http://adaxes.com/sdk/?HowDoI.GetDnOfObject.html.
  • $reportType - specifies the type of report to be generated. The report can include only enrolled, only not enrolled or all users.
  • $to - specifies email addresses of the recipient(s) of the report;
  • $subject - specifies the email message subject;
  • $reportHeader - specifies the email message header;
  • $reportFooter - specifies the email message footer.
Edit Remove
PowerShell
$ouDNs = @("CN=Users,DC=domain,DC=com", "OU=Sales,DC=domain,DC=com") # TODO modify me. Set to @() for search all users

# $reportType = "Enrolled" # TODO: uncomment the type you need
# $reportType = "Not enrolled"
 $reportType = $NULL

# E-mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Password Self-Service statistics" # TODO: modify me
$reportHeader = "<b>Password Self-Service statistics.</b><br/><br/>" # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it was sent to you for notification purposes only.</i></p>" # TODO: modify me

function GetUserGuids($dn, $list)
{
    $searcher = $Context.BindToObjectByDN($dn)
    $searcher.SearchFilter = "(sAMAccountType=805306368)"
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.PageSize = 500
    $searcher.SetPropertiesToLoad(@("objectGUID"))
    
    try
    {
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()
        
        $searchResults | %%{[void]$list.Add([Guid]$_.Properties["objectGUID"].Value)}
    }
    finally
    {
        # Release resources
        if ($searchResultIterator){ $searchResultIterator.Dispose() }
    }
}

# Bind to the 'Password Self-Service Statistics' container
$passwordSelfServiceStatisticsPath = $Context.GetWellKnownContainerPath("PasswordSelfServiceStatistics")
$passwordSelfServiceStatistics = $Context.BindToObject($passwordSelfServiceStatisticsPath)

# Get the enrollment report
$reportIsBeingGenerated = $True
do
{
    try
    {
        $report = $passwordSelfServiceStatistics.GetReport("ADM_PSSREPORTTYPE_ENROLLMENT")
    }
    catch [System.Runtime.InteropServices.COMException]
    {
        if ($_.Exception.ErrorCode -eq "-2147024875")
        {
            # Report is being generated. Wait 10 seconds
            Start-Sleep -Seconds 10
            continue
        }
        else
        {
            $reportIsBeingGenerated = $False
            $Context.LogMessage($_.Exception.Message, "Error")
            return
        }
    }
    
    if ($report.GenerateDate -lt [System.Datetime]::UtcNow.AddHours(-1))
    {
        $passwordSelfServiceStatistics.ResetReportCache("ADM_PSSREPORTTYPE_ENROLLMENT")
    }
    else
    {
        $reportIsBeingGenerated = $False
    }
}
while ($reportIsBeingGenerated)

# Get user guids
$userGuids = New-Object "System.Collections.Generic.HashSet[System.Guid]"
foreach ($dn in $ouDNs)
{
    GetUserGuids $dn $userGuids
}

# Build the report
$html = New-Object "System.Text.StringBuilder"
[void]$html.Append($reportHeader)
[void]$html.Append("<table border='1' width='100%%'><tr>")
[void]$html.Append("<th>Name</th>")
[void]$html.Append("<th>Parent</th>")
[void]$html.Append("<th>Enrolled</th>")
[void]$html.Append("<th>Effective Policy</th>")
[void]$html.Append("<th>Date/Time</th>")
[void]$html.Append("<th>Enrollment Invitation</th>")
[void]$html.Append("</tr>")
$records = $report.Records
for ($i = 0; $i -lt $records.Count; $i++)
{
    $record = $records.GetRecord($i)
    
    # Get user information
    $userPath = $NULL
    $userDisplayName = $NULL
    $userParentCanonicalName = $NULL
    $userAccountIsEnabled = $NULL
    $userIsEnrolled = $NULL
    $userAccountIsExpired = $NULL
    $userInfo = $record.GetUserInfo([ref]$userPath, [ref]$userDisplayName, [ref]$userParentCanonicalName, 
        [ref]$userAccountIsEnabled, [ref]$userIsEnrolled, [ref]$userAccountIsExpired)
    
    $path = New-Object Softerra.Adaxes.Adsi.AdsPath $userPath
    $guid = [Guid]$path.Guid
    
    if ($userGuids.Count -ne 0 -and !$userGuids.Contains($guid))
    {
        continue
    }
    
    if (($reportType -eq "Enrolled" -and !$userIsEnrolled) -or 
        ($reportType -eq "Not enrolled" -and $userIsEnrolled))
    {
        continue
    }
    
    # Get event date
    $eventDate = $record.EventDate
    if ($eventDate -eq [DateTime]::MinValue)
    {
        $eventDate = $NULL
    }
    
    # Get policy information
    $policyPath = $NULL
    $policyName = $NULL
    $policyInfo = $record.GetEnrollmentPolicyInfo([ref]$policyPath, [ref]$policyName)
    
    if ($userIsEnrolled)
    {
        $userIsEnrolled = "Yes ($policyName)"
    }
    else
    {
        $userIsEnrolled = "No"
    }
    
    # Get invitation info
    $successSendDate = New-Object System.Datetime 0
    $errorMessage = $NULL
    $record.GetSendInvitationInfo([ref]$successSendDate, [ref]$errorMessage)
    if ([System.String]::IsNullOrEmpty($errorMessage) -and $successSendDate -ne [Datetime]::MinValue)
    {
        $enrollmentInvitation = $successSendDate
    }
    else
    {
        $enrollmentInvitation = $errorMessage
    }
    
    # Get effective policy information
    $effectivePolicyPath = $NULL
    $effectivePolicyName = $NULL
    $record.GetEffectivePolicyInfo([ref]$effectivePolicyPath, [ref]$effectivePolicyName)
    
    # Add information to the report
    [void]$html.Append("<tr><td>$userDisplayName</td><td>$userParentCanonicalName</td><td>$userIsEnrolled</td><td>$effectivePolicyName</td><td>$eventDate</td><td>$enrollmentInvitation</td></tr>")
}

[void]$html.Append("</table>")
[void]$html.Append($reportFooter)

# Send mail
$Context.SendMail($to, $subject, $NULL, $html.ToString())


Comments ( 0 )
avatar
Andrew Hancock
September 25, 2019

I'm not that great with Powershell and this worked great for us after a little tweaking to fit our environment.
Thanks!

Leave a comment