Create report

Adaxes allows you to create reports for various purposes, such as monitoring your directory activity and state, performing bulk operations, audit, and so on. Reports can present objects grouped together based on various criteria, such as their location, property values, or group membership. In addition to directory data, reports can be based upon and include information from other sources like Exchange, Adaxes logs, approval requests, external databases, HR systems, etc.

In this tutorial, you will learn how to create reports in Adaxes.

  1. Launch Adaxes administration console.

     How
    • On the computer where Adaxes administration console is installed, open Windows Start menu.

    • Click Adaxes Administration Console.

  2. Expand Adaxes service \ Reports \ All Reports. Right-click the container where you want to create a report, point to New, and click Report.

  3. Report name and type

    On the General step of the wizard, enter a name and an optional description for the new report. Also, specify how the new report will be generated.

    A report can be generated based on:

    • Directory search

      These reports are generated through a directory search, including only objects that meet the specified criteria. Additional conditions can address cases where a directory query alone is insufficient. For example, include or exclude users based on their assigned Microsoft 365 licenses.

    • Script

      This option lets you create reports using PowerShell scripts, allowing for complex or highly flexible criteria. Reports can include objects based on external data, such as HR databases, and may also feature Adaxes log records, approval requests, and custom objects like file shares, permissions, or database records.

    • Existing report with specific parameters

      With this report type, you can build new reports using existing ones as a foundation while customizing specific settings. You can modify the scope, charts, columns, parameter values, report categories, and related reports to better suit your needs.

    Click Next.

  4. Scope

    On this wizard step, you need to specify the options for selecting a report scope. A scope defines which objects will be included into the report.

    • Reports based on a directory search – a scope specifies where in the directory to perform the search.

    • Script-based reports – adding a scope is optional. Click Next to skip the step if your script will not use scopes.

    To add a new scope, click New and follow the instructions in the New Scope Item wizard.

     Step by step
    • Select the type of scope you want to add, and click Next.

    • In the Title field, specify a title under which the scope will be displayed when selected.

    • In the Drop-down item text field, specify a caption under which the scope will be displayed in the list of available scopes.

    • Click Next.

    • Specify options for selecting the base object of the new scope.

    • Click Finish.

    A report can have more than one scope. Multiple scopes will appear as a drop-down list when generating the report.

     Screenshot

    Click Next.

  5. Parameters

    On this step, you can add parameters to the new report. Parameters can be used to supply additional information that can be necessary for report generation.

    Where parameters can be used

    • Criteria

      If the report is generated from a directory search, you can use parameters in search criteria.

      For example: Department is %param-Department%.

    • Conditions

      Parameters can also be used in conditions meant to include or exclude objects from a report.

      Examples:

      • If is a member of %param-Group%
      • If the 'My Checkbox' parameter equals 'Yes'
    • Scripts

      It is possible to use parameter values in scripts. For instance, you can set a script variable to a parameter value like so:

      $var = "%param-MyParam%"
      
      # Alternatively, you can use the GetParameterValue method of the $Context variable:
      $var = $Context.GetParameterValue("param-MyParam")
      
    • Charts

      Parameters can be used to build charts. For example, you can use the following value generation template for an item in a bar or pie chart:

      Count of specific values in Department. Value to count: %param-Department%.

    To add a parameter, click New and follow the instructions in the New Parameter wizard.

    When done, click Next.

  6. Columns

    On this step, you can specify default columns for the report, as well as restrict the columns that can be added. Also, you can set the default sorting and grouping options.

    Report-specific columns

    You can create columns that are specific to the new report only. Values in such columns are generated either using a template, or with the help of a PowerShell script.

     How to create a report-specific column
    1. In the Report-specific columns section, click Add.

    2. Enter a display name for the new column.

    3. In the Data Type section, select the type of data the new column will contain.

      Click Next.

    4. Specify how to generate values for the column.

      Template

      This option lets you generate column values based on the properties of objects included in the report. To add property values to the template, use value references (e.g. %department% or %title%), which will be replaced with the corresponding property values of each object.

      Script

      This option lets you generate column values with the help of a PowerShell script.

      To assign a column value, use the Value property of the $Context variable.

      $Context.Value = "My value"
      

      It is a predefined PowerShell variable of type ReportCustomColumnScriptContext. It allows you to obtain detailed information about each item in the report.

      Getting information about the report item

      To get information about the directory object a column value is generated for, use the $Context.GetDirectoryObject method. The object returned by the method supports the IADs interface.

      Example – Setting column value to the UPN suffix of a user.

      # Get the user.
      $user = $Context.GetDirectoryObject()
      
      # Get the property value.
      $upn = $user.Get("userPrincipalName")
      
      # Set the column value.
      $upnSuffix = $upn.Substring($upn.LastIndexOf("@") + 1)
      $Context.Value = $upnSuffix
      

      In addition to that, you can access information on the report item using the $Context.ReportItem property. It supports the IAdmListItem interface. If the object represented by the item is a log record or a custom object, the property also supports the IAdmListItemLogRecord or IAdmListItemCustom interface respectively.

      $Context.Value = $Context.ReportItem.LogRecord.StartTime
      

      Getting information about the user the report is generated for

      To get information about the user the report is generated for, use the $Context.Initiator property.

      if (-not($Context.Initiator.Username.Contains("admin")))
      {
          $Context.Value = "Not allowed to view"
      }
      

      You can also use value references (e.g. %department% or %title%) to get property values of the user account.

      $recipientInfo = "%fullname%, %title% at %department%"
      

      Improving performance

      The script is executed for batches of objects rather than one at a time. For better performance, you can share information among iterations of the script within a batch. In the following example, a value requested from a web service is shared.

      if ($null -eq $myValue) # Check whether value has already been requested.
      {
          # Get a value from web service.
          $service = New-WebServiceProxy `
              -uri "http://www.company.com/Service.asmx?WSDL"
          $myValue = $service.RequestSomething("My Argument")
      }
      
      # Get the user.
      $user = $Context.GetDirectoryObject()
      
      # Get the username.
      $username = $user.Get("userPrincipalName")
      
      # Set the column value.
      $Context.Value = "Personal Share: \$myValue\Shares\$username"
      

      If the report is generated with the help of a script, you can optimize the performance by setting column values inside the script that generates the report. This approach allows you to generate column values more efficiently.

      If you want to use the approach, select the Template option and assign an initial value to the column. For example, if it is a text column, the initial value can be (empty).

       Screenshot

      For information on how to set column values in the script used for report generation, see Setting values of report-specific columns.

    5. Click Finish.

    Click Next.

  7. On this wizard page you need to specify either search criteria, or a PowerShell script for report generation, depending on the selected report type.

    Search Options

    If the report is generated based on a directory search, specify the criteria and/or optional conditions for including objects into the report.

     Details

    Criteria

    • Click Edit.

    • Click Add criteria and select the criteria for including objects into the report.

    You can use value references to use different criteria depending on who generates the report. For example, Department is %department% criteria means the report will include objects whose department matches the department of the user generating the report.

    Similarly, you can use value references to include parameters in criteria. For example, if you specify Company is %param-ParamCompany%, the report will include objects whose company matches the value of the ParamCompany parameter.

    Conditions

    Conditions allow you to specify additional requirements for including or excluding objects from the report. To add a condition, click Add condition.

    Using conditions is expensive performance-wise, as each object is evaluated against conditions separately. Try to avoid using conditions where possible and specify as many requirements as you can via criteria.

    By default, objects that meet conditions are excluded from the report. You can change the behavior to instead include only such objects. To do so, click Exclude.

    You can use value references in conditions. With their help, you can create a condition that depends on who generates the report. For example, using an If located under %adm-ParentDN% condition, you can exclude or include objects located in the same organizational unit as the user generating the report.

    Similarly, you can use value references to include parameters in conditions. For example, using an If is a member of %param-ParamGroup% condition, you can include or exclude members of a group specified by parameter ParamGroup.

    Script

    On the Script page, you need to create a script for report generation.

     Details

    To add items to the report, use the $Context.Items.Add method. The following examples demonstrate how to add items of different types:

     Directory objects
    $johnDoe = $Context.BindToObjectByDN("CN=John Doe,CN=Users,DC=company,DC=com")
    $Context.Items.Add($johnDoe)
    
     Search results

    There are two ways how you can include search results in the report. The first option is to pass specific search results to the Add method.

    try
    {
        $searchIterator = $Context.DirectorySearcher.ExecuteSearch()
        while ($Context.MoveNext($searchIterator))
        {
            $searchResult = $searchIterator.Current
            $Context.Items.Add($searchResult)
        }
    }
    finally
    {
        if ($searchIterator) { $searchIterator.Dispose() }
    }
    

    Alternatively, you can pass all search results at once. To do this, pass the $Context.DirectorySearcher property.

    $Context.Items.Add($Context.DirectorySearcher)
    
     Log records
    $serviceLogPath = $Context.GetWellKnownContainerPath("ServiceLog")
    $serviceLog = $Context.BindToObject($serviceLogPath)
    $log = $serviceLog.GeneralLog.Log
    
    $records = $log.GetPage(0)
    $record = $records.GetObject(0)
    $Context.Items.Add($record)
    
     Approval requests
    # Get pending approval requests
    $containerPath = $Context.GetWellKnownContainerPath("ApprovalRequests")
    $container = $Context.BindToObject($containerPath)
    $requests = $container.GetApprovalRequests("ADM_APPROVALSTATE_PENDING")
    
    foreach ($requestID in $requests)
    {
        # Bind to request
        $guid = New-Object "System.Guid" (,$requestID)
        $guid = $guid.ToString("B")
        $request = $Context.BindToObject("Adaxes://<GUID=$guid>")
    
        # Add request to report
        $Context.Items.Add($request)
    }
    
     Custom objects

    To add a custom object, pass the index of an icon to use with the object, object name, display type, and also a hash table with column values:

    $columnValues = @{ }
    $columnValues.Add("company", "Acme")
    $columnValues.Add("department", "Sales")
    $Context.Items.Add(1, "My Item", "My Type", $columnValues)
    

    For information on how to get indexes of available icons, see View list of icons and icon indexes.

    Getting parameter values

    To get values of report parameters, use the $Context.GetParameterValue method. The method argument specifies the parameter name.

    $date = $Context.GetParameterValue("param-ParamDate")
    # The $date variable is set to "05/03/2022 12:24:00 PM"
    

    If you need to use the report parameter value in an LDAP filter, set the optional second argument of the $Context.GetParameterValue method to $true. The value will be converted into a suitable format.

    $date = $Context.GetParameterValue("param-ParamDate", $true)
    # The $date variable is set to "20220503122400.0Z"
    

    It is also possible to get the parameter value without converting it to a string, using the GetParameterValueAsIs method.

    $date = $Context.ReportArguments.GetParameterValueAsIs("param-ParamDate")
    # The $date variable is set to a System.DateTime object
    

    Finally, you can get parameter values with the help of value references.

    $department = "%param-ParamDepartment%"
    

    Getting information about the user the report is generated for

    In your script, you can use information about the user the report is generated for. For this purpose, use the $Context.Initiator property.

    $initiatorDepartment = $Context.Initiator.UserAdsObject.Get("department")
    

    To get property values of the initiator's user account, you can also use value references (e.g. %department% or %title%).

    $parentDn = "%adm-ParentDN%"
    

    Modifying search parameters

    You can modify various parameters of the search. To do so, use methods and properties provided by the $Context.DirectorySearcher property.

    Example 1 – Modifying the search criteria

    # Modify search criteria
    
    # WARNING: Replacing the criteria entirely will break the report.
    # You need to merge the existing criteria with your criteria via the AddCriteria method.
    
    $department = $Context.GetParameterValue("param-ParamDepartment", $true) 
    $criteriaToAdd = New-AdmCriteria "user" {department -eq $department}
    $Context.DirectorySearcher.AddCriteria($criteriaToAdd)
    
    # Add all search results to report
    $Context.Items.Add($Context.DirectorySearcher)
    

    Example 2 – Adding properties to load during the search

    # Load the Department and Company properties during search
    
    # WARNING: Replacing all properties to load is not recommended.
    # Instead, you need to add the necessary properties.
    
    $Context.DirectorySearcher.SearchParameters.PropertiesToLoad.AddRange(
        @("department", "company"))
    
    # Add all search results to report
    $Context.Items.Add($Context.DirectorySearcher)
    

    Changing item color and font style

    You can highlight items in the report with color and font style. To do so, create an item style with the help of the $Context.Items.CreateItemStyle method and pass it to the $Context.Items.Add method as the last parameter.

    # Add first item
    
    $textColor1 = "red"
    $backgroundColor1 = $null # default
    $fontStyle1 = "ADM_LISTITEMFONTSTYLE_BOLD" # bold
    $style1 = $Context.Items.CreateItemStyle($textColor1, $backgroundColor1, $fontStyle1)
    $reportItem1 = $Context.BindToObjectByDN("CN=John Doe,OU=People,DC=company,DC=com")
    $Context.Items.Add($reportItem1, $style1)
    
    # Add second item
    
    $textColor2 = "#FFFFFF" # white
    $backgroundColor2 = "16776960" # yellow
    $fontStyle2 = "ADM_LISTITEMFONTSTYLE_BOLD",
        "ADM_LISTITEMFONTSTYLE_ITALIC" # bold + italic
    $style2 = $Context.Items.CreateItemStyle($textColor2, $backgroundColor2, $fontStyle2)
    $reportItem2 = $Context.BindToObjectByDN("%manager%")
    $Context.Items.Add($reportItem2, $style2)
    

    Setting values of report-specific columns

    If the report contains report-specific columns, you can assign their values directly in the report script.

    To set a value for a column, first you need to get the column ID. On the Columns step of the wizard, right-click the column and select Copy > Column ID. The ID will be copied to the clipboard.

     Screenshot

    Then, for each object, you need to create a hash table that maps a column ID to the column value. When adding the object to the report, pass the hash table to the $Context.Items.Add method.

    $columnID = "{8421e8e1-65b2-4190-9f24-93a264c6c9ba}" # TODO replace with the ID of
                                                         # the column you need
    
    # Create hash table and specify column value
    $columnValues = @{ }
    $columnValues.Add($columnID, "My Value")
    
    # Add item to report
    $item = $Context.BindToObjectByDN("CN=John Doe,CN=Users,DC=company,DC=com")
    $Context.Items.Add($item, $columnValues)
    

    Click Next.

  8. Chart

    On this step, you can add a chart to the new report. A chart can be used to represent the report data visually. To add a chart, select the Enable chart option.

    You can add charts of the following types:

    Bar and pie charts

    When adding bar and pie charts to the report, you need to specify how to calculate the size of each bar or slice. The size is calculated based on the column values. For example, you can add an item that displays the number of times a certain value occurs in a specific column, e.g. Count of (Department=Sales).

     Screenshot
    Using value references

    You can use value references in charts. They let you create chart items that depend on who generates the report. For example, the following item will display the number of users in the same company as the user generating the report: Count of (Company=%company%).

    Similarly, you can use value references to create items based on parameters. For example, the following item will display the number of users in the department specified by parameter ParamDepartment: Count of (Department=%param-ParamDepartment%).

    Using report-specific columns

    Chart items can be based on report-specific columns. Such columns can be generated with the help of a script, which gives you more possibilities when generating chart items.

     Screenshot

    Top Records chart

    This type of chart allows displaying a certain number of items sorted by a specific column. For example, a chart can display top ten organizational units with the biggest number of objects in them.

    Using a report-specific column

    You can create the chart on the basis of a report-specific column. Such columns can be generated with the help of a script, which gives you more possibilities when generating a chart.

     Screenshot

    Total Count chart

    This chart displays the total number of items in the report. It does not have any parameters.

    When done, click Next.

  9. Miscellaneous

    Categories

    On the final step, you need to specify categories for the new report. Categories are used to distribute permissions to view reports. Only users who have the permissions for a category will be able to view reports within that category.

    To specify a report category, select it in the categories list. To create a new category, click Manage categories.

    For information on how to grant permissions to view reports belonging to a specific category, see Grant rights to view reports.

    If there are any reports related to the new one, you can add them to the Related reports section. This will make such reports easily accessible to users. For example, when working with a report in the web interface, a list of related reports will appear at the bottom of the left pane.

     Screenshot

    To add a related report, click Add.

    When done, click Finish.