Script Repository


Self-Service Password Resets

April 12, 2017
1537

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 CSV file that will be created by the script;
  • $reportHeader - specifies the email message 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 report sender.
  • $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 )
No results found.
Leave a comment