0 votes

I'm using this report as a baseline and I have it mostly working, but I need assistance setting the ldap filter or search base to include only specified OUs instead of the whole domain because I'm running it against DomainDNS and cannot use Activity Scope.

$to = "email@example.com" # TODO: modify me

function GetObjectDisplayName($objectDN)
{
    $objectPath = New-Object -TypeName "Softerra.Adaxes.Adsi.AdsPath"`
        -ArgumentList @($null, $objectDN)   
    return [Softerra.Adaxes.Utils.ObjectNameHelper]::GetObjectName(
        $objectPath, "IncludeParentPath")
}

# Get the default Web Interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
$appendWebInterFaceLink = $True
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
{
    $appendWebInterFaceLink = $False
    $Context.LogMessage("Default web interface address not set for Adaxes service. For details, see http://www.adaxes.com/help/?HowDoI.ManageService.RegisterWebInterface.html", "Warning")
}

$htmlBuilder = New-Object "System.Text.StringBuilder"
$htmlBuilder.append("<html><head>")
$htmlBuilder.append("<meta http-equiv=""Content-Type""`
    content=""text/html charset=UTF-8""></head>")
$htmlBuilder.append("<body>")
$htmlBuilder.append("<p>Disabled Managers</p>")
$htmlBuilder.append("<table width=""100%%"" border=""1"">")
$htmlBuilder.append("<tr>")
$htmlBuilder.append("<th>Full Name</th><th>Username</th>
<th>Parent</th><th>Direct Reports</th>")
if ($appendWebInterFaceLink)
{
    $htmlBuilder.append("<th>Link</th>")
}

$htmlBuilder.append("</tr>")

# Find disabled managers
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.SearchFilter = "(&(objectCategory=user)(samAccountName=*)(!thumbnailPhoto=*))"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.VirtualRoot = $True

try
{
    $searchResult = $searcher.ExecuteSearch()
    $photoEmpty = $searchResult.FetchAll()

    # Add information on each user
    if ($photoEmpty.Count -gt 0)
    {
        foreach ($employee in $photoEmpty)
        {
            $employee = $Context.BindToObject($employee.AdsPath)
            $employeeDN = New-Object "Softerra.Adaxes.Ldap.DN" $employee.Get("distinguishedName")
            $parentDisplayName = GetObjectDisplayName($employeeDN.Parent.ToString())
            $htmlBuilder.append("<tr>")
            $htmlBuilder.appendFormat("<td>{0}</td>", $employee.Get("name"))
            $htmlBuilder.appendFormat("<td>{0}</td>", $employee.Get("sAMAccountName"))
            $htmlBuilder.appendFormat("<td>{0}</td>", $parentDisplayName)

            # Append direct reports
            $htmlBuilder.append("<td>")
#            foreach ($directReportDN in $employee.GetEx("directReports"))
#            {
#                $directReport = $Context.BindToObjectByDN($directReportDN)
#                $htmlBuilder.appendFormat("{0} ({1})<br />", $directReport.Get("name"), $directReport.Get("sAMAccountName"))
#            }
#            $htmlBuilder.append("</td>")

            if ($appendWebInterFaceLink)
            {
                $htmlBuilder.appendFormat("<td><a href='$webInterfaceAddress`ViewObject.aspx?guid={0}'>View</a></td>", [Guid]$employee.Get("objectGUID"))
            }
            $htmlBuilder.append("</tr>")
        }
    }

    $htmlBuilder.append("</table>")
    $htmlBuilder.appendFormat("Total: {0} employees", $photoEmpty.Count.ToString())
    $htmlBuilder.append("</body></html>")

    $Context.SendMail($to, "[AD Report] Employees Without Pictures", $NULL, $htmlBuilder.ToString())
}
finally
{
    $searchResult.Dispose()
}
by (540 points)

1 Answer

0 votes
by (216k points)
selected by
Best answer

Update 2018

Starting with Adaxes 2018.1 you can use a built-in report, Users without photo. By default, the report is located in container Reports\All Reports\Users.

Original

Hello,

Here's a version of the script that will do the job. In the script:

  • $to - specifies the recipient of the report;
  • $subject - specifies the subject for the email notification;
  • $ouDNs - specifies Distinguished Names (DNs) of the Organizational Units that you want to run the report for.
$to = "recipient@domain.com" # TODO: modify me
$subject = "[AD Report] Employees Without Pictures" # TODO: modify me
$ouDNs = @("OU=MyOU1,DC=domain,DC=com", "OU=MyOU2,DC=domain,DC=com") # TODO: modify me

function BuildReport($ouDN)
{
    # Find users without photos
    $searcher = $Context.BindToObjectByDN($ouDN)
    $searcher.PageSize = 500
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.SearchFilter = "(&(objectCategory=person)(objectClass=user)(!(thumbnailPhoto=*)))"
    $searcher.SetPropertiesToLoad(@("distinguishedName", "name", "sAMAccountName", "objectGuid"))

    try
    {
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()

        # Add information on each user
        $searchResultsCount = $searchResults.Count
        if ($searchResultsCount -gt 0)
        {
            foreach ($searchResult in $searchResults)
            {
                [void]$htmlBuilder.Append("<tr>")
                [void]$htmlBuilder.AppendFormat("<td>{0}</td>", $searchResult.Properties["name"].Value)
                [void]$htmlBuilder.AppendFormat("<td>{0}</td>", $searchResult.Properties["sAMAccountName"].Value)
                $userDN = New-Object "Softerra.Adaxes.Ldap.DN" $searchResult.Properties["distinguishedName"].Value
                $parentDisplayName = GetObjectDisplayName($userDN.Parent.ToString())
                [void]$htmlBuilder.AppendFormat("<td>{0}</td>", $parentDisplayName)

                if ($appendWebInterFaceLink)
                {
                    [void]$htmlBuilder.AppendFormat("<td><a href='$webInterfaceAddress`ViewObject.aspx?guid={0}'>View</a></td>", [Guid]$searchResult.Properties["objectGuid"].Value)
                }
                [void]$htmlBuilder.Append("</tr>")
            }
        }

        return $searchResultsCount
    }
    finally
    {
        $searchResultIterator.Dispose()
    }
}

function GetObjectDisplayName($objectDN)
{
    $objectPath = New-Object -TypeName "Softerra.Adaxes.Adsi.AdsPath"`
        -ArgumentList @($null, $objectDN)   
    return [Softerra.Adaxes.Utils.ObjectNameHelper]::GetObjectName(
        $objectPath, "IncludeParentPath")
}

# Get the default Web Interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
$appendWebInterFaceLink = $True
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
{
    $appendWebInterFaceLink = $False
    $Context.LogMessage("Default web interface address not set for Adaxes service. For details, see http://www.adaxes.com/help/?HowDoI.ManageService.RegisterWebInterface.html", "Warning")
}

# Start building the report
$htmlBuilder = New-Object "System.Text.StringBuilder"
$htmlBuilder.Append("<html><head>")
$htmlBuilder.Append("<meta http-equiv=""Content-Type""`
    content=""text/html charset=UTF-8""></head>")
$htmlBuilder.Append("<body>")
$htmlBuilder.Append("<p>Disabled Managers</p>")
$htmlBuilder.Append("<table width=""100%%"" border=""1"">")
$htmlBuilder.Append("<tr>")
$htmlBuilder.Append("<th>Full Name</th><th>Username</th><th>Parent</th>")
if ($appendWebInterFaceLink)
{
    $htmlBuilder.Append("<th>Link</th>")
}
$htmlBuilder.Append("</tr>")
$totalCount = 0

# Process each OU
foreach ($dn in $ouDNs)
{
    $totalCount += BuildReport $dn
}

# Finish building the report
$htmlBuilder.Append("</table>")
$htmlBuilder.AppendFormat("<br/>Total: {0} employees", $totalCount)
$htmlBuilder.Append("</body></html>")

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

How would you exclude an OU from this search?
So, exclude an OU that is a child of one of the OUs specified within $ouDNs

0

Hello,

We've published an updated version of the script in our Script Repository: Users without photo. In the new version, use $excludeOuDNs to specify the OUs you want to skip.

Related questions

0 votes
1 answer

I'm trying to schedule a report to look in a few specific OUs. Currently "Look in" location only allows for single instance or multiple drop downs. How do I schedule multiple OU locations without creating multiple reports?

asked Jul 2, 2020 by Al (20 points)
0 votes
1 answer

This is the query I am using (basically if "Photo" is empty): (&amp;(sAMAccountType=805306368)(!(photo=*))) which returns everyone in AD, not just users without photos. ... sAMAccountType=805306368)(!(manager=*))) What am I doing wrong? Can my query be fixed?

asked Jun 11, 2012 by MarkManley (90 points)
0 votes
1 answer

We are looking for if Adaxes has a report we can run that will tell us if there are multiple users using the same or similar passwords? Is there any tool that we can ... as another users? I appreciate any information you may be able to provide. Thank You,

asked Feb 27 by Jeff.Briand (60 points)
0 votes
1 answer

Hi, we currenlty have a business rule to send an email everytime the Title, Manager, Department, accountExpires, EmployeeType or FirstName attributes are ... Unit: %BusinessUnit% End Date: %accountExpires% Effective Date of Change: %adm-CustomAttributeDate2%

asked Feb 14 by KevC (60 points)
0 votes
1 answer

Hi I'm trying to add your report from here but whenever I run it, I get 2 errors for each user which seem to correspond to the following 2 lines in the ... "user" $Context.DirectorySearcher.AddCriteria($criteria) But I still get the same error's. Thanks Matt

asked Oct 16, 2023 by chappers77 (2.0k points)
3,346 questions
3,047 answers
7,782 comments
544,986 users