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

Users are asking if they can change their name to suit preferred names as opposed to birth names? Is this possible?

asked Oct 14 by Charlie.Evans (70 points)
0 votes
1 answer

I need to create a report of all enabled users in selected group or multiple groups. I am aware of the report named "Members of selected groups", but I don't know how to filter only enabled users. Is there a way to achieve this?

asked May 28 by gsoc.ssm (90 points)
0 votes
1 answer

I created a Report asking the report to get the Assinged Microsoft Supbsription license assinged to the Users, When the Reports runs it geta few users but time out ... way to increase the time Out oprtion fro Reports that are getting information from Azure?

asked May 16 by George.Holden (60 points)
3,589 questions
3,278 answers
8,303 comments
548,130 users