We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.

Script Repository

Self-Service Password Resets

February 18, 2021 Views: 3500

The below scripts can be used to create reports on password resets made by users themselves. The reports can be delivered in 3 different formats: an HTML or CSV report sent by e-mail or a PDF file saved to a certain file share.

Note: To schedule the report, create a scheduled task configured for the Domain-DNS object type that runs the script and assign it over any of your AD domains. To add the script to a scheduled task, use the Run a program or PowerShell script action.

HTML Report

This script creates and emails the report in the HTML format.

Parameters:

  • $to - Specifies a comma separated list of recipients of the report.
  • $subject - Specifies the email message subject.
  • $reportHeader - Specifies the email message header. In the header, the {0} placeholder will be replaced with the date when the report was generated.
  • $reportFooter - Specifies the email message footer.
Edit Remove
PowerShell
$to = "recipient@domain.com" # TODO: modify me
$subject = "Self-Service Password Resets Report" # TODO: modify me
$reportHeader = @"
<b>Self-Service Password Resets Report. Generated: {0} </b><br/><br/>
<table border="1">
    <tr>
        <th>Name</th>
        <th>Parent</th>
        <th>Success</th>
        <th>Policy</th>
        <th>Date/Time</th>
    </tr>
"@ # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

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

# Regenerate the Password Resets Report
$passwordSelfServiceStatistics.ResetReportCache("ADM_PSSREPORTTYPE_RESETPWD")
$reportIsBeingGenerated = $True

# Get the Password Resets Report
do 
{
    try
    {
        $report = $passwordSelfServiceStatistics.GetReport("ADM_PSSREPORTTYPE_RESETPWD")
        $reportIsBeingGenerated = $False
    }
    catch [System.Runtime.InteropServices.COMException]
    {
        if ($_.Exception.ErrorCode -eq "-2147024875")
        {
            # Report is being generated. Wait 10 seconds
            Start-Sleep -Seconds 10
        }
        else
        {
            $reportIsBeingGenerated = $False
            $Context.LogMessage($_.Exception.Message, "Error")
            return
        }
    }
}
while ($reportIsBeingGenerated)

# Add the date when the report was generated
$reportHeader = $reportHeader -f $report.GenerateDate

# Add the report records
$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)
    $eventDate = $record.EventDate
    
    # Get policy information
    $policyPath = $NULL
    $policyName = $NULL
    $policyInfo = $record.GetEnrollmentPolicyInfo([ref]$policyPath, [ref]$policyName)
    
    # Add the information to the report
    if ($record.IsSuccessfull)
    {
        $isSuccessfull = "<td bgcolor='green'>True</td>"
    }
    else
    {
        $isSuccessfull = "<td bgcolor='red'>False</td>"
    }
    $reportHeader += "<td>$userDisplayName</td><td>$userParentCanonicalName</td>$isSuccessfull<td>$policyName</td><td>$eventDate</td></tr>"
}

# Build the report
$reportHeader += "</table>"
$htmlBody = $reportHeader + $reportFooter

# Send the report
$Context.SendMail($to, $subject, $NULL, $htmlBody)

PDF Report

This script creates a PDF file with a report on a certain file share.

Parameters:

  • $pdfFilePath - Specifies a UNC path to the PDF file that will be created by the script.
  • $reportHeader - Specifies the report header. In the header, the {0} placeholder will be replaced with the date when the report was generated.
Note: The script relies on a third-party PowerShell module Out-PTSPDF PDF File Generator for generating PDF files. Download and install it on the computer where Adaxes service runs before running the script.
Edit Remove
PowerShell
Import-Module PDFTools

$pdfFilePath = "\\Server\Share\Report.pdf" # TODO: modify me
$reportHeader = "Self-Service Password Resets Report. Generated: {0}" # TODO: modify me

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

# Regenerate the Password Resets Report
$passwordSelfServiceStatistics.ResetReportCache("ADM_PSSREPORTTYPE_RESETPWD")
$reportIsBeingGenerated = $True

# Get the report
do 
{
    try
    {
        $report = $passwordSelfServiceStatistics.GetReport("ADM_PSSREPORTTYPE_RESETPWD")
        $reportIsBeingGenerated = $False
    }
    catch [System.Runtime.InteropServices.COMException]
    {
        if ($_.Exception.ErrorCode -eq "-2147024875")
        {
            # Report is being generated. Wait 10 seconds
            Start-Sleep -Seconds 10
        }
        else
        {
            $reportIsBeingGenerated = $False
            $Context.LogMessage($_.Exception.Message, "Error")
            return
        }
    }
}
while ($reportIsBeingGenerated)

# Add the date when the report was generated
$reportHeader = $reportHeader -f $report.GenerateDate

# Add the report records
$records = $report.Records
$report = @()
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)
    $eventDate = $record.EventDate
    
    # Get policy information
    $policyPath = $NULL
    $policyName = $NULL
    $policyInfo = $record.GetEnrollmentPolicyInfo([ref]$policyPath, [ref]$policyName)

    $reportEntry = New-Object PSObject
    $reportEntry | Add-Member -Name Name -Value $userDisplayName -MemberType NoteProperty
    $reportEntry | Add-Member -Name Parent -Value $userParentCanonicalName -MemberType NoteProperty
    $reportEntry | Add-Member -Name Success -Value $record.IsSuccessfull -MemberType NoteProperty
    $reportEntry | Add-Member -Name Policy -Value $policyName -MemberType NoteProperty
    $reportEntry | Add-Member -Name "Date/Time" -Value $eventDate -MemberType NoteProperty
    
    $report += $reportEntry
}

# Write PDF file
$report | Out-PTSPDF -Path $pdfFilePath -AutoSize -FontSize 12 -Wrap -GroupBy Success -HeaderText $reportHeader -IncludeHeader

CSV Report

This script creates and emails the report as a CSV file. Also, the total number of Self-Service Password Resets, the number of successful and failed attempts is included directly into the notification message.

Parameters:

  • $csvFilePath - Specifies a full path to the CSV file containing the report.
  • $removeCsvFile - Specifies whether to remove the CSV file after sending.
  • $to - Specifies a comma separated list of recipients of the report.
  • $subject - Specifies the email message subject.
  • $from - Specifies the e-mail address from which the message will be sent.
  • $mailServer - Specifies the SMTP server to be used when sending the report.
  • $reportHeader - Specifies the email message header.
  • $reportFooter - Specifies the email message footer.
  • $operationStatusList - Specifies how to display successful and failed operations in the report.
Edit Remove
PowerShell
$csvFilePath = "C:\Scripts\PasswordResetReport.csv" # TODO: modify me
$removeCsvFile = $True # TODO: modify me

# E-mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Self-Service Password Resets Report" # TODO: Modify me
$from = "noreply@localhost" # TODO: Modify me
$mailServer = "mail.domain.com" # TODO: Modify me
$reportHeader = "<h1><b>Self-Service Password Resets Report</b></h1><br/>"
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
$operationStatusList = "
<ul>
    <li>Successful password resets: {0}</li>
    <li>Failed password resets: {1}</li>
</ul>" # TODO: Modify me

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

# Regenerate the Password Resets Report
$passwordSelfServiceStatistics.ResetReportCache("ADM_PSSREPORTTYPE_RESETPWD")
$reportIsBeingGenerated = $True

# Get the report
do 
{
    try
    {
        $report = $passwordSelfServiceStatistics.GetReport("ADM_PSSREPORTTYPE_RESETPWD")
        $reportIsBeingGenerated = $False
    }
    catch [System.Runtime.InteropServices.COMException]
    {
        if ($_.Exception.ErrorCode -eq "-2147024875")
        {
            # Report is being generated. Wait 10 seconds
            Start-Sleep -Seconds 10
        }
        else
        {
            $reportIsBeingGenerated = $False
            $Context.LogMessage($_.Exception.Message, "Error")
            return
        }
    }
}
while ($reportIsBeingGenerated)

# Add the date when the report was generated
$reportHeader = $reportHeader -f $report.GenerateDate

# Add the report records
$records = $report.Records
$report = New-Object "System.Collections.ArrayList"
$successfullResetsCount = 0
$failedResetsCount = 0

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)
    $eventDate = $record.EventDate
    
    # Get Password Self-Service Policy information
    $policyPath = $NULL
    $policyName = $NULL
    $policyInfo = $record.GetEnrollmentPolicyInfo([ref]$policyPath, [ref]$policyName)

    # Create report entry
    $reportEntry = New-Object PSObject -Property @{
        "Name" = $userDisplayName
        "Parent" = $userParentCanonicalName
        "Success" = $record.IsSuccessfull
        "Policy" = $policyName
        "Date/Time" = $eventDate
    }
    
    if ($record.IsSuccessfull)
    {
        $successfullResetsCount++
    }
    else
    {
        $failedResetsCount++
    }
    
    $report.Add($reportEntry)
}
$report | Export-Csv -Path $csvFilePath -NoTypeInformation

# Build html message
$operationStatusList = [System.String]::Format($operationStatusList, @($successfullResetsCount, $failedResetsCount))
$html = $reportHeader + $operationStatusList + $reportFooter

# Send message
Send-MailMessage -to $to -From $from -Body $html -BodyAsHtml -Attachments $csvFilePath -SmtpServer $mailServer -Subject $subject

if ($removeCsvFile)
{
    # Remove CSV File
    Remove-Item $csvFilePath -Force
}

Comments 0
Leave a comment
Loading...

Got questions?

Support Questions & Answers