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 {id=collapse1}
    • 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 step 1 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

      Reports of this type are generated by performing a directory search. Only objects that match the specified criteria are included in the report. On top of that, you can use conditions to cover cases where a directory query is insufficient. For example, you can include or exclude users with a specific Microsoft 365 license from your report.

    • Script

      Using this option, you can create reports on the basis of a PowerShell script. It allows you to specify more sophisticated criteria for including objects, and even create reports without any common criteria at all. Apart from that, objects can be included in the report based on information that cannot be obtained from the directory. For example, information from an HR database can be used for this purpose. In addition to directory objects, such reports can include Adaxes log records, approval requests, and custom objects (file shares, permissions, database records, etc).

    • Existing report with specific parameters

      With this report type, you can create new reports on the basis of existing ones, but redefine certain report settings. You can override the scope, chart, columns, parameter values, report categories and related reports.

    Click Next.

  4. Scope

    On this wizard step, you need to specify the options for selecting a report scope. A scope defines the directory objects to include into the report.

    For reports based on a directory search, a scope specifies where in the directory to perform the search. Reports based on PowerShell scripts can be created without a scope. In this case, you can click Next to skip the step.

    A scope can include objects located in a particular organizational unit, subordinates of a certain manager, members of a group, etc. A report can have more than one scope. In this case, they will appear as a drop-down list when generating the report, so users can select the necessary one.

     View screenshot

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

     Step by step { #collapse2}
    • 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.

    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%" or $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 { #collapse3}
    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

      Using this option, you can generate column values based on properties of the objects included into the report. To include property values in the template, use value references (e.g. %department% or %title%). They will be replaced with corresponding property values of the object a column value is generated for.

      Script

      Select this option to generate column values with the help of a PowerShell script.

      To assign a column value, use a variable called $Context. It is a predefined PowerShell variable of type ReportCustomColumnScriptContext. Use the Value property of the variable to set the column value.

      $Context.Value = "My value"
      

      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).

       View screenshot { #collapse10}

      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 { #collapse4}

    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 possible using 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 { #collapse5}

    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 values to them in the report-generating script itself. To set a value for a column, first you need to get the column ID. For this purpose, on the Columns step of the wizard, right-click the column and select Copy > Column ID. The ID will be copied to the clipboard.

     View screenshot { #collapse6}

    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 on the basis of 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).

     View 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.

     View 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.

     View screenshot { #collapse15}

    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.

     View screenshot { #collapse12}

    To add a related report, click Add.

    When done, click Finish.