The script creates and emails an HTML-formatted report on business rules, custom commands, scheduled tasks and scheduled reports available in Adaxes service.
To generate the report on demand, you can create a custom command configured for the Domain object type that runs the script. To schedule the report, create a scheduled task and include any of your AD domains in the Activity Scope. To add the script to a command or task, use the Run a program or PowerShell script action.
Parameters:
- $enabledObjectsOnly - Specifies whether only enabled objects should be present in the report.
- $saveToFile - Specifies whether an HTML file will be saved to a folder.
- $sendMail - Specifies whether to deliver the report via email.
- $filePath - Specifies the path to the HTML file that will be created. This variable is taken into account only if the $saveToFile variable is set to True.
- $to - Specifies a comma separated list of recipients of the report.
- $subject - Specifies the email message subject.
- $reportHeader - Specifies the email message header.
- $reportFooter - Specifies the email message footer.
- $configurationObjectInfos - Specifies what information you want to include in your report.
PowerShell
# Report processing
$enabledObjectsOnly = $False # TODO: modify me
$saveToFile = $False # TODO: modify me
$sendMail = $True # TODO: modify me
$filePath = "\\Server\Scripts\Report.html" # TODO: modify me
# Email settings
$to = "recipient@example.com" # TODO: modify me
$subject = "Business Rules, Scheduled Tasks, Custom Commands and Scheduled Reports" # TODO: modify me
$reportHeader = "<h2><b><font style='text-transform: uppercase;'>Business Rules, Scheduled Tasks, Custom Commands and Scheduled Reports</font></b></h2>" # 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
$configurationObjectInfos = @{
"Custom Commands" = "CustomCommands", "adm-CustomCommand";
"Business Rules" = "BusinessRules", "adm-BusinessRule";
"Scheduled Tasks" = "ScheduledTasks", "adm-ScheduledTask";
"Reports \ Schedule" = "ReportSchedule", "adm-ReportScheduledTask";
} # TODO: comment out unnecessary
function GetActionsDescription ($conditionedActionsList, $actions, $objectType)
{
[void]$conditionedActionsList.Append("<ul style=""list-style: none;"">")
$actionDescriptions = New-Object System.Text.StringBuilder
for ($actionID = 0; $actionID -lt $actions.Count; $actionID++)
{
try
{
$action = $actions.GetObject($actionID)
}
catch
{
continue
}
$actionObject = $action.GetAction()
# Get action description
$actionDescription = $actionObject.CustomDescription
if ([System.String]::IsNullOrEmpty($actionDescription))
{
try
{
$actionDescription = $actionObject.GetOperationName("the $objectType", $NULL, "ADM_ACTIONNAMEFORMAT_SPECIFIC, ADM_ACTIONNAMEFORMAT_CAPITALLETTER")
}
catch
{
$actionDescription = "N/A"
}
}
[void]$actionDescriptions.Append("<li><font color='#28531C'>$actionDescription</font></li>")
}
if ($actionDescriptions.Length -ne 0)
{
[void]$conditionedActionsList.Append($actionDescriptions.ToString())
}
else
{
[void]$conditionedActionsList.Append("<li><font color='#57544A'>Do nothing</font></li>")
}
[void]$conditionedActionsList.Append("</ul>")
}
function BuildActionConditionsDescription ($conditionedActionsList, $objectType, $conditionedActionsCollection, $isElseIfBlock)
{
if ($isElseIfBlock)
{
$startConditionDescription = "Else if "
$endConditionDescription = " then"
$noConditionText = "$startConditionDescription <font color='#57544A'><no condition</font>>"
}
else
{
$startConditionDescription = "If "
$endConditionDescription = " then"
$noConditionText = "<font color='#1E50FF'>Always</font>"
}
for ($setID = 0; $setID -lt $conditionedActionsCollection.Count; $setID++)
{
try
{
$conditionedActions = $conditionedActionsCollection.GetObject($setID)
}
catch
{
continue
}
switch ($conditionedActions.ConditionsLogicalOperation)
{
"ADM_LOGICALOPERATION_OR"
{
$conditionsLogicalOperation = "OR"
}
"ADM_LOGICALOPERATION_AND"
{
$conditionsLogicalOperation = "AND"
}
default
{
$conditionsLogicalOperation = $NULL
}
}
# Conditions
$conditionDescriptions = New-Object System.Collections.ArrayList
$conditions = $conditionedActions.Conditions
for ($conditionID = 0; $conditionID -lt $conditions.Count; $conditionID++)
{
try
{
$condition = $conditions.GetObject($conditionID)
}
catch
{
continue
}
$conditionObject = $condition.GetCondition()
$conditionDescription = $conditionObject.GetDescription($NULL)
[void]$conditionDescriptions.Add("<font color='#1E50FF'>$conditionDescription</font>")
}
if ($conditionDescriptions.Count -ne 0)
{
$conditionDescriptions[0] = $startConditionDescription + $conditionDescriptions[0]
$conditionDescriptions[$conditionDescriptions.Count - 1] = $conditionDescriptions[$conditionDescriptions.Count - 1] + $endConditionDescription
$conditionDescriptionsString = "<li>" + ($conditionDescriptions -join " <u>$conditionsLogicalOperation</u></li><li>") + "</li>"
[void]$conditionedActionsList.Append($conditionDescriptionsString)
}
else
{
[void]$conditionedActionsList.Append("<li>$noConditionText</li>")
}
# Actions
GetActionsDescription $conditionedActionsList $conditionedActions.Actions $objectType
# Get ElseIf/Else blocks
if ($isElseIfBlock)
{
continue
}
BuildActionConditionsDescription $conditionedActionsList $objectType $conditionedActions.ElseIfConditionedActions $True
if ($conditionedActions.ElseActions.Count -ne 0)
{
[void]$conditionedActionsList.Append("<li>Else</li>")
GetActionsDescription $conditionedActionsList $conditionedActions.ElseActions $objectType
}
}
}
function GetActivityScopeItems ($configurationObject, $activityScopeItemsList)
{
# Get Activity Scope
$activityScopeItems = $configurationObject.ActivityScopeItems
if ($activityScopeItems.Count -eq 0)
{
[void]$activityScopeItemsList.Append("N/A")
}
else
{
[void]$activityScopeItemsList.Append("<ul style=""list-style: none;"">")
for ($scopeItemID = 0; $scopeItemID -lt $activityScopeItems.Count; $scopeItemID++)
{
try
{
$item = $activityScopeItems.GetObject($scopeItemID)
}
catch
{
continue
}
[void]$activityScopeItemsList.Append("<li>")
if ($item.Exclude)
{
[void]$activityScopeItemsList.Append("Exclude - ")
}
else
{
[void]$activityScopeItemsList.Append("Include - ")
}
$baseObjectClass = $NULL
switch ($item.Type)
{
"ADM_SCOPEBASEOBJECTTYPE_ALL_DIRECTORY"
{
$baseObjectName = "All objects"
}
"ADM_SCOPEBASEOBJECTTYPE_CONFIGURATION"
{
$baseObjectName = "Configuration objects"
}
default
{
$baseObjectGuid = [Guid]$item.Get("adm-ScopeBaseObjectGuid")
try
{
$baseObject = $Context.BindToObject("Adaxes://<GUID=$baseObjectGuid>")
$baseObjectName = $Context.GetDisplayNameFromAdsPath($baseObject.AdsPath)
}
catch
{
$baseObjectName = $baseObjectGuid
}
}
}
[void]$activityScopeItemsList.Append("$baseObjectName")
if ($baseObjectClass -eq "domainDNS")
{
$inheritance = "All Domain objects"
}
elseif (($item.Inheritance -eq "ADS_SCOPE_BASE") -and
($item.Type -ne "ADM_SCOPEBASEOBJECTTYPE_ALL_DIRECTORY") -and
($item.Type -ne "ADM_SCOPEBASEOBJECTTYPE_CONFIGURATION"))
{
$inheritance = "This object only"
}
else
{
switch ($item.Type)
{
"ADM_SCOPEBASEOBJECTTYPE_CONTAINER"
{
if ($item.Inheritance -eq "ADS_SCOPE_ONELEVEL")
{
$inheritance = "One level"
}
elseif ($item.Inheritance -eq "ADS_SCOPE_SUBTREE")
{
$inheritance = "Subtree"
}
}
"ADM_SCOPEBASEOBJECTTYPE_GROUP"
{
if ($item.Inheritance -eq "ADS_SCOPE_ONELEVEL")
{
$inheritance = "Direct members"
}
elseif ($item.Inheritance -eq "ADS_SCOPE_SUBTREE")
{
$inheritance = "All members"
}
}
"ADM_SCOPEBASEOBJECTTYPE_BUSINESSUNIT"
{
$inheritance = "All Unit members"
}
default
{
$inheritance = $NULL
}
}
}
if ($inheritance -ne $NULL)
{
[void]$activityScopeItemsList.Append(" - $inheritance")
}
[void]$activityScopeItemsList.Append("</li>")
}
[void]$activityScopeItemsList.Append("</ul>")
}
}
function GetRecurrencePattern($configurationObject)
{
$recurrencePattern = $configurationObject.GetRecurrencePattern()
$interval = $recurrencePattern.Interval
$patternStartDateTime = $recurrencePattern.PatternStartDateTime
$patternStartTime = $patternStartDateTime.ToString("hh:mm")
switch ($recurrencePattern.RecurrenceType)
{
"ADM_RECURRENCEPATTERNTYPE_NONE"
{
$recurrencePatternString = "None"
}
"ADM_RECURRENCEPATTERNTYPE_ONCE"
{
$recurrencePatternString = $patternStartDateTime.ToString("dddd, MMMM d, yyyy") + " at $patternStartTime"
}
"ADM_RECURRENCEPATTERNTYPE_HOURLY"
{
if ($interval -eq 1)
{
$recurrencePatternString = "Every hour"
}
else
{
$recurrencePatternString = "Every $interval hours"
}
}
"ADM_RECURRENCEPATTERNTYPE_DAILY"
{
if ($interval -eq 1)
{
$recurrencePatternString = "Every day at $patternStartTime"
}
else
{
$recurrencePatternString = "Every $interval days at $patternStartTime"
}
}
"ADM_RECURRENCEPATTERNTYPE_WEEKLY"
{
$dayOfWeekMask = $recurrencePattern.DayOfWeekMask
$days = @()
if ($dayOfWeekMask -band 1)
{
$days += "Sunday"
}
if ($dayOfWeekMask -band 2)
{
$days += "Monday"
}
if ($dayOfWeekMask -band 4)
{
$days += "Tuesday"
}
if ($dayOfWeekMask -band 8)
{
$days += "Wednesday"
}
if ($dayOfWeekMask -band 16)
{
$days += "Thursday"
}
if ($dayOfWeekMask -band 32)
{
$days += "Friday"
}
if ($dayOfWeekMask -band 64)
{
$days += "Saturday"
}
$weekDays = [System.String]::Join(", ", $days)
$recurrencePatternString = "Every $weekDays at $patternStartTime"
}
"ADM_RECURRENCEPATTERNTYPE_MONTHLY"
{
$dayOfMonth = $recurrencePattern.DayOfMonth
if ($dayOfMonth -eq -1)
{
$dayOfMonth = "last day"
}
$recurrencePatternString = "On the $dayOfMonth of every month at $patternStartTime"
}
"ADM_RECURRENCEPATTERNTYPE_MINUTELY"
{
if ($interval -eq 1)
{
$recurrencePatternString = "Every minute"
}
else
{
$recurrencePatternString = "Every $interval minutes"
}
}
}
return $recurrencePatternString
}
function BuildReport ($configurationContainer, $objectCategory, $records, $enabledObjectsOnly)
{
# Search configuration objects
$path = $Context.GetWellKnownContainerPath($configurationContainer)
$searcher = $Context.BindToObject($path)
if ($enabledObjectsOnly)
{
$searcher.SearchFilter = "(&(objectCategory=$objectCategory)(adm-Enabled=TRUE))"
}
else
{
$searcher.SearchFilter = "(objectCategory=$objectCategory)"
}
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500
try
{
$searchResultIterator = $searcher.ExecuteSearch()
$searchResults = $searchResultIterator.FetchAll()
$configurationContainerPathObject = New-Object "Softerra.Adaxes.Adsi.AdsPath" $path
foreach ($searchResult in $searchResults)
{
# Get object properties
$configurationObject = $Context.BindToObject($searchResult.AdsPath)
$configurationObjectPathPart = $searchResult.AdsPath.ToString().Replace($configurationContainerPathObject.DN, "")
$configurationObjectName = $Context.GetDisplayNameFromAdsPath($configurationObjectPathPart.Trim(","))
$description = $configurationObject.Description
$disabled = $configurationObject.Disabled
if ($configurationContainer -ne "ReportSchedule")
{
$groupBy = $configurationObject.ObjectType
$operationType = $configurationObject.OperationType
$operationTypeString = $operationType.SubString(0, 1).ToUpper() + $operationType.SubString(1, $operationType.Length - 1).ToLower()
switch ($configurationObject.ExecutionMoment)
{
"ADM_BUSINESSRULEEXECMOMENT_AFTER"
{
$executionMoment = "After"
}
"ADM_BUSINESSRULEEXECMOMENT_BEFORE"
{
$executionMoment = "Before"
}
}
# Get conditions and actions
$conditionedActionsList = New-Object System.Text.StringBuilder
[void]$conditionedActionsList.Append("<ul style=""list-style: none;"">")
BuildActionConditionsDescription $conditionedActionsList $groupBy $configurationObject.ConditionedActions $False
[void]$conditionedActionsList.Append("</ul>")
}
else
{
# Get scheduled reports
$groupBy = $configurationObjectName
$scheduledReportsList = New-Object System.Text.StringBuilder
$selfScheduledReportsList = New-Object System.Text.StringBuilder
$scheduledReports = $configurationObject.ScheduledReports
for ($reportID = 0; $reportID -lt $scheduledReports.Count; $reportID++)
{
$report = $scheduledReports.GetObject($reportID)
$reportName = $report.ReportData.Report.Get("Name")
$customTitle = $report.ReportData.CustomTitle
switch ($report.ReportData.Document.Type)
{
"ADM_REPORTDOCUMENTTYPE_PDF"
{
$format = "PDF"
}
"ADM_REPORTDOCUMENTTYPE_CSV"
{
$format = "CSV"
}
"ADM_REPORTDOCUMENTTYPE_HTML"
{
$format = "HTML"
}
"ADM_REPORTDOCUMENTTYPE_XLSX"
{
$format = "XLSX"
}
"ADM_REPORTDOCUMENTTYPE_RTF"
{
$format = "RTF"
}
default
{
$format = "Unknown"
}
}
$delivery = @()
if ($report.ReportData.Delivery.EmailDelivery.Enabled)
{
$delivery += "Email"
}
if ($report.ReportData.Delivery.FileDelivery.Enabled)
{
$delivery += "File"
}
$delivery = $delivery -join " | "
$activityScopeItemsList = New-Object System.Text.StringBuilder
GetActivityScopeItems $report $activityScopeItemsList
if ($report.ReportData.SelfScheduled)
{
[void]$selfScheduledReportsList.Append("<li><b>$reportName</b>")
[void]$selfScheduledReportsList.Append("<ul style=""list-style: none;"">")
[void]$selfScheduledReportsList.Append("<li><i><font color='#2E74B5'>Custom Title:</font></i> $customTitle</li>")
[void]$selfScheduledReportsList.Append("<li><i><font color='#2E74B5'>Format:</font></i> $format</li>")
[void]$selfScheduledReportsList.Append("<li><i><font color='#2E74B5'>Delivery:</font></i> $delivery</li>")
[void]$selfScheduledReportsList.Append("<li><font color='#2E74B5'><i>Recipients</i></font>: $($activityScopeItemsList.ToString())</li>")
[void]$selfScheduledReportsList.Append("</ul>")
[void]$selfScheduledReportsList.Append("</li>")
}
else
{
[void]$scheduledReportsList.Append("<li><b>$reportName</b>")
[void]$scheduledReportsList.Append("<ul style=""list-style: none;"">")
[void]$scheduledReportsList.Append("<li><i><font color='#2E74B5'>Custom Title:</font></i> $customTitle</li>")
[void]$scheduledReportsList.Append("<li><i><font color='#2E74B5'>Format:</font></i> $format</li>")
[void]$scheduledReportsList.Append("<li><i><font color='#2E74B5'>Delivery:</font></i> $delivery</li>")
[void]$scheduledReportsList.Append("<li><font color='#2E74B5'><i>Recipients</i></font>: $($activityScopeItemsList.ToString())</li>")
[void]$scheduledReportsList.Append("</ul>")
[void]$scheduledReportsList.Append("</li>")
}
}
}
if ($configurationContainer -ne "CustomCommands" -and $configurationContainer -ne "ReportSchedule")
{
$activityScopeItemsList = New-Object System.Text.StringBuilder
GetActivityScopeItems $configurationObject $activityScopeItemsList
}
# Build record
switch ($configurationContainer)
{
"CustomCommands"
{
$record = "<li><h3>$configurationObjectName</h3>
<ul style=""list-style: none;"">
<li><font color='#2E74B5'><i>Description</i></font>: $description</li>
<li><font color='#2E74B5'><i>Disabled</i></font>: $disabled</li>
<li><font color='#2E74B5'><i>Action and Conditions</i></font>: $($conditionedActionsList.ToString())</li></ul></li>"
}
"BusinessRules"
{
$record = "<li><h3>$configurationObjectName</h3>
<ul style=""list-style: none;"">
<li><font color='#2E74B5'><i>Description</i></font>: $description</li>
<li><font color='#2E74B5'><i>Operation Type</i></font>: $operationTypeString</li>
<li><font color='#2E74B5'><i>Execution Moment</i></font>: $executionMoment</li>
<li><font color='#2E74B5'><i>Disabled</i></font>: $disabled</li>
<li><font color='#2E74B5'><i>Action and Conditions</i></font>: $($conditionedActionsList.ToString())</li>
<li><font color='#2E74B5'><i>Activity Scope</i></font>: $($activityScopeItemsList.ToString())</li></ul></li>"
}
"ScheduledTasks"
{
$recurrencePatternString = GetRecurrencePattern $configurationObject
$ownerServiceDnsHostName = $configurationObject.OwnerServiceDnsHostName
$isOwnerServicePermanent = $configurationObject.IsOwnerServicePermanent
$record = "<li><h3>$configurationObjectName</h3>
<ul style=""list-style: none;"">
<li><font color='#2E74B5'><i>Description</i></font>: $description</li>
<li><font color='#2E74B5'><i>Disabled</i></font>: $disabled</li>
<li><font color='#2E74B5'><i>Recurrence pattern</i></font>: $recurrencePatternString</li>
<li><font color='#2E74B5'><i>Run on</i></font>: $ownerServiceDnsHostName</li>
<li><font color='#2E74B5'><i>Always run on this server</i></font>: $isOwnerServicePermanent</li>
<li><font color='#2E74B5'><i>Action and Conditions</i></font>: $($conditionedActionsList.ToString())</li>
<li><font color='#2E74B5'><i>Activity Scope</i></font>: $($activityScopeItemsList.ToString())</li></ul></li>"
}
"ReportSchedule"
{
$recurrencePatternString = GetRecurrencePattern $configurationObject
$ownerServiceDnsHostName = $configurationObject.OwnerServiceDnsHostName
$isOwnerServicePermanent = $configurationObject.IsOwnerServicePermanent
$record = "<ul style=""list-style: none;"">
<li><font color='#2E74B5'><i>Description</i></font>: $description</li>
<li><font color='#2E74B5'><i>Disabled</i></font>: $disabled</li>
<li><font color='#2E74B5'><i>Run on</i></font>: $ownerServiceDnsHostName</li>
<li><font color='#2E74B5'><i>Always run on this server</i></font>: $isOwnerServicePermanent</li>
<li><font color='#2E74B5'><i>Recurrence pattern</i></font>: $recurrencePatternString</li>"
if ($scheduledReportsList.Length -ne 0)
{
$record += "<li><font color='#2E74B5'><i>Scheduled Reports</i></font>: <ul style=""list-style: none;""> $($scheduledReportsList.ToString())</ul></li>"
}
if ($selfScheduledReportsList.Length -ne 0)
{
$record += "<li><font color='#2E74B5'><i>Self-Scheduled Reports</i></font>: <ul style=""list-style: none;""> $($selfScheduledReportsList.ToString())</ul></li>"
}
if ($scheduledReportsList.Length -eq 0 -and $selfScheduledReportsList.Length -eq 0)
{
$record += "<li><font color='#2E74B5'><i>Scheduled Reports</i></font>: N/A</li>"
}
$record += "</ul>"
}
}
if ($records.ContainsKey($groupBy))
{
$records[$groupBy] += $record
}
else
{
$records.Add($groupBy, $record)
}
}
}
finally
{
# Release resources
$searchResultIterator.Dispose()
}
}
$report = New-Object "System.Text.StringBuilder"
foreach ($displayName in $configurationObjectInfos.Keys)
{
$configurationObjects = @{}
$info = $configurationObjectInfos[$displayName]
BuildReport $info[0] $info[1] $configurationObjects $enabledObjectsOnly
[void]$report.Append("<h2><font color='#2E74B5'>$displayName</font></h2><ul style=""list-style: none;"">")
foreach ($groupBy in $configurationObjects.Keys)
{
[void]$report.Append("<li>")
if ($info[0] -ne "ReportSchedule")
{
[void]$report.Append("<h2>Object type: $groupBy</h2>")
[void]$report.Append("<ul style=""list-style: none;"">")
[void]$report.Append($configurationObjects[$groupBy])
[void]$report.Append("</ul>")
}
else
{
[void]$report.Append("<h2>Report Scheduled Task: $groupBy</h2>")
[void]$report.Append($configurationObjects[$groupBy])
}
[void]$report.Append("</li>")
}
[void]$report.Append("</ul>")
}
# Build report
$html = $reportHeader + $report.ToString() + $reportFooter
if ($saveToFile)
{
$html | Out-File $filePath
}
if ($sendMail)
{
# Send mail
$Context.SendMail($to, $subject, $NULL, $html)
}
What exactly do you mean? Do you want to include the host name of the Adaxes service the script is executed on? Where exactly do you need the data to be added?
Thank you for the clarification. We updated the script accordingly. Now the output will contain the service scheduled tasks and report scheduled tasks are configured to run on. Please, clear browser cache and recopy the script.
Do we understand correctly that you need to filter out disabled business rules, custom commands, scheduled tasks and scheduled reports or only disabled scheduled tasks should be filtered out?
We updated the report accordingly. Please, clear browser cache and recopy the script.
Unfortunately, there is no such possibility.