Users enrolled in any multifactor authentication policy within Adaxes.
I want a script to query MFA enrollment status, then add only enrolled users to an AD group.
Here is a script I found that should generate a CSV file with all user enrollment status, however it does not run either within Adaxes as a custom scheduled task as an action of type "Run a program or PowerShell script" or via PowerShell directly. Email functionality in the script is ignored as I'm only trying to write a CSV. The errors will be posted below the script.
Script:
$ouDNs = @("CN=Users,DC=domain,DC=com", "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
# CSV file settings
$csvFilePath = "C:\tools\enrollment-report.csv" # TODO: modify me
$removeCSVFile = $False # TODO: modify me
# Mail settings
$to = "recipient@domain.com" # TODO: modify me
$from = "noreply@localhost" # TODO: modify me
$smtpServer = "mailserver.domain.com" # TODO: modify me
$subject = "Password Self-Service statistics" # TODO: modify me
$message = "Password Self-Service statistics" # TODO: modify me
function GetUserGuids($dn, $list)
{
$searcher = $Context.BindToObjectByDN($dn)
$searcher.Criteria = New-AdmCriteria "user"
$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
$reportRecords = New-Object System.Collections.ArrayList
$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
$reportRecord = [PSCustomObject][ordered]@{
"Name" = $userDisplayName
"Parent" = $userParentCanonicalName
"Enrolled" = $userIsEnrolled
"Effective Policy" = $effectivePolicyName
"Date/Time" = $eventDate
"Enrollment Invitation" = $enrollmentInvitation
}
$reportRecords.Add($reportRecord)
}
# Export to CSV
$reportRecords | Sort-Object @sortParameters | Export-csv -NoTypeInformation -Path $csvFilePath
# Send mail
#Send-MailMessage -To $to -from $from -SmtpServer $smtpServer -Subject $subject -Body $message -Attachments $csvFilePath
if ($removeCSVFile)
{
# Remove temporary file
Remove-Item $csvFilePath -Force
}
Errors running within Adaxes:
The term 'New-AdmCriteria' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. Stack trace: at GetUserGuids, <No file>: line 21 at <ScriptBlock>, <No file>: line 83
Exception calling "ExecuteSearch" with "0" argument(s): "Search filter is not specified. Parameter name: searchParameters" Stack trace: at GetUserGuids, <No file>: line 28 at <ScriptBlock>, <No file>: line 83