Skip to content

Managing approval requests

This article describes how to manage approval requests using PowerShell scripts and C# code. The code samples included in this article can be used in stand-alone scripts and applications as well as in PowerShell scripts executed by Business Rules, Custom Commands, and Scheduled Tasks.

approval requests are stored as directory objects in the Adaxes Configuration Server (AD LDS). To get a list of approval requests, first you need to bind to the container where approval requests are stored. After you’ve bound to the container, you can use the IAdmApprovalRequestContainer interface to enumerate approval requests.

To get approval requests, call the GetApprovalRequests method of the IAdmApprovalRequestContainer interface and pass the desired request state as the parameter of the method. For a list of possible request states, see the ADM_APPROVALSTATE_ENUM enumeration.

The GetApprovalRequests method returns an array of GUIDs (each represented as an array of 16 bytes) that can be used to bind to Approval Request objects. Approval Request objects expose the IAdmApprovalRequest interface.

The following code sample outputs information about pending approval requests.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$admNS = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the Approval Requests container
$containerPath = $admService.Backend.GetConfigurationContainerPath(
"ApprovalRequests")
$container = $admService.OpenObject($containerPath.ToString(),
$NULL, $NULL, 0)

# Get all pending approval requests
$requests = $container.GetApprovalRequests("ADM_APPROVALSTATE_PENDING")

# Iterate through the requests
foreach ($requestID in $requests)
{
# Bind to the approval request
$guid = New-Object "System.Guid" (,$requestID)
$guid = $guid.ToString("B")
$requestPath = "Adaxes://<GUID=$guid>"
$request = $admService.OpenObject($requestPath, $NULL, $NULL, 0)

# $request implements the IAdmApprovalRequest interface

Write-Host "Requestor:" $request.Requestor.Get("name")
Write-Host "Request Date:" $request.CreationDate.ToShortDateString()
Write-Host "Operation:" $request.DescriptionOfOperationToApprove
}
using System;
using Interop.Adsi.ApprovalRequests;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
static void Main(string[] args)
{
    // Connect to the Adaxes service
    AdmNamespace adsNS = new AdmNamespace();
    IAdmService admService = adsNS.GetServiceDirectly("localhost");

    // Bind to the Approval Requests container
    String containerPath = admService.Backend.GetConfigurationContainerPath(
        "ApprovalRequests");
    IAdmApprovalRequestContainer container =
        (IAdmApprovalRequestContainer)admService.OpenObject(
            containerPath, null, null, 0);

    // Get all pending approval requests
    Object[] requests = (Object[])container.GetApprovalRequests(
        ADM_APPROVALSTATE_ENUM.ADM_APPROVALSTATE_PENDING);

    // Iterate through the requests
    foreach (Byte[] requestID in requests)
    {
        // Bind to the approval request
        String guid = new Guid(requestID).ToString("B");
        String requestPath = String.Format("Adaxes://<GUID={0}>", guid);
        IAdmApprovalRequest request = (IAdmApprovalRequest)admService.OpenObject(
            requestPath, null, null, 0);

        Console.WriteLine("Requestor: " + request.Requestor.Get("name"));
        Console.WriteLine("Request Date: " + request.CreationDate.ToShortDateString());
        Console.WriteLine("Operation: " + request.DescriptionOfOperationToApprove);
        Console.WriteLine(String.Empty);
    }
}
}

Getting approval requests initiated/processed by a user

To get all approval requests initiated by a specific user, first you need to bind to the user. After you’ve bound to the user, you can use the GetRequestsForApproval method of the IAdmUser interface. To get approval requests initiated by a user during a given period of time, you can use the GetRequestsForApproval2 method of the IAdmUser2 interface.

Both methods return an array of GUIDs (each represented as an array of 16 bytes) that can be used to bind to Approval Request objects. Approval Request objects expose the IAdmApprovalRequest interface.

The following code sample outputs information about pending approval requests initiated by a specific user during the last 10 days.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$userDN = "CN=John Smith,CN=Users,DC=domain,DC=com"
$numDays = 10

# Connect to the Adaxes service
$admNS = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the user
$user = $admService.OpenObject("Adaxes://$userDN", $NULL, $NULL, 0)

# Get pending approval requests initiated by the user during the requested time period
$startDateTime = (Get-Date).AddDays(-$numDays)
$endDateTime = Get-Date
$approvalRequestGuids = $user.GetRequestsForApproval2("ADM_APPROVALSTATE_PENDING", $startDateTime, $endDateTime)

foreach ($requestGuidBytes in $approvalRequestGuids)
{
    # Bind to the Approval Request
    $requestGuid = [Guid]$requestGuidBytes
    $requestPath = "Adaxes://<Guid=$requestGuid>"
    $request = $admService.OpenObject($requestPath, $NULL, $NULL, 0)

    # Output information about the Approval Request
    Write-Host "Operation:" $request.DescriptionOfOperationToApprove
    Write-Host "Requested on " $request.CreationDate.ToShortDateString()
    Write-Host
}
using System;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.ApprovalRequests;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        const String userDN = "CN=John Smith,CN=Users,DC=domain,DC=com";
        const Int32 numDays = 10;

        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        // Bind to the user
        IAdmUser2 user = (IAdmUser2)admService.OpenObject("Adaxes://" + userDN, null, null, 0);

        // Get pending approval requests initiated by the user during the requested time period
        DateTime startDateTime = DateTime.Now.AddDays(-numDays);
        DateTime endDateTime = DateTime.Now;
        Object[] approvalRequestGuids = (Object[])user.GetRequestsForApproval2(
            ADM_APPROVALSTATE_ENUM.ADM_APPROVALSTATE_PENDING, startDateTime, endDateTime);

        foreach (Byte[] requestGuidBytes in approvalRequestGuids)
        {
            // Bind to the Approval Request
            String requestGuid = new Guid(requestGuidBytes).ToString("B");
            String requestPath = String.Format("Adaxes://<GUID={0}>", requestGuid);
            IAdmApprovalRequest request = (IAdmApprovalRequest)admService.OpenObject(
                requestPath, null, null, 0);

            // Output information about the Approval Request
            Console.WriteLine("Operation: " + request.DescriptionOfOperationToApprove);
            Console.WriteLine("Requested on " + request.CreationDate.ToShortDateString());
            Console.WriteLine(String.Empty);
        }
    }
}

To get approval requests processed by a user or waiting for the user’s approval, you can use the GetApprovals method of the IAdmUser interface. To get approval requests that were initiated during a given period of time and processed by a specific user, you can use the GetApprovals2 method of the IAdmUser2 interface.

The following code sample outputs information about approval requests initiated during the last 10 days and denied by a specific user.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$userDN = "CN=John Smith,CN=Users,DC=domain,DC=com"
$numDays = 10

# Connect to the Adaxes service
$admNS = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the user
$user = $admService.OpenObject("Adaxes://$userDN", $NULL, $NULL, 0)

# Get approval requests initiated during the requested time period and denied by the user
$startDateTime = (Get-Date).AddDays(-$numDays)
$endDateTime = Get-Date
$approvalRequestGuids = $user.GetApprovals2("ADM_APPROVALSTATE_DENIED", $startDateTime, $endDateTime)

foreach ($requestGuidBytes in $approvalRequestGuids)
{
    # Bind to the Approval Request
    $requestGuid = [Guid]$requestGuidBytes
    $requestPath = "Adaxes://<Guid=$requestGuid>"
    $request = $admService.OpenObject($requestPath, $NULL, $NULL, 0)

    # Output information about the Approval Request
    Write-Host "Target object: " $request.TargetObject.Name
    Write-Host "Operation: " $request.DescriptionOfOperationToApprove
    Write-Host "Reason for denial: " $request.DenialOrCancelingReason
    Write-Host
}
using System;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.ApprovalRequests;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        const String userDN = "CN=John Smith,CN=Users,DC=domain,DC=com";
        const Int32 numDays = 10;

        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        // Bind to the user
        IAdmUser2 user = (IAdmUser2)admService.OpenObject("Adaxes://" + userDN, null, null, 0);

        // Get approval requests initiated during the requested time period and denied by the user
        DateTime startDateTime = DateTime.Now.AddDays(-numDays);
        DateTime endDateTime = DateTime.Now;
        Object[] approvalRequestGuids = (Object[])user.GetApprovals2(
            ADM_APPROVALSTATE_ENUM.ADM_APPROVALSTATE_DENIED, startDateTime, endDateTime);

        foreach (Byte[] requestGuidBytes in approvalRequestGuids)
        {
            // Bind to the Approval Request
            String requestGuid = new Guid(requestGuidBytes).ToString("B");
            String requestPath = String.Format("Adaxes://<GUID={0}>", requestGuid);
            IAdmApprovalRequest request = (IAdmApprovalRequest)admService.OpenObject(
                requestPath, null, null, 0);

            // Output information about the Approval Request
            Console.WriteLine("Target object: {0}", request.TargetObject.Name);
            Console.WriteLine("Operation: {0}",
                request.DescriptionOfOperationToApprove);
            Console.WriteLine("Reason for denial: {0}", request.DenialOrCancelingReason);
            Console.WriteLine();
        }
    }
}

Approving, denying and cancelling requests

To approve, deny or cancel an Approval Request, first you need to bind to the directory object representing the request. Then you can use the Approve, Deny and Cancel methods of the IAdmApprovalRequest interface to approve, deny or cancel the request. The Deny and Cancel methods get a single parameter that is a string that explains the reason for the request denial or cancelling.

Tip

A request can be approved or denied either by a request approver or by an Adaxes service administrator. A request can be cancelled by the request initiator only.

The following code sample denies requests that were not resolved within 30 days.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$admNS = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the Approval Requests container
$containerPath = $admService.Backend.GetConfigurationContainerPath(
    "ApprovalRequests")
$container = $admService.OpenObject($containerPath.ToString(),
    $NULL, $NULL, 0)

# Get all pending approval requests
$requests = $container.GetApprovalRequests("ADM_APPROVALSTATE_PENDING")

# Iterate through the requests
foreach ($requestID in $requests)
{
    # Bind to the approval request
    $guid = New-Object "System.Guid" (,$requestID)
    $guid = $guid.ToString("B")
    $requestPath = "Adaxes://<GUID=$guid>"
    $request = $admService.OpenObject($requestPath, $NULL, $NULL, 0)

    # Check whether the request must be denied
    $deadlineDate = $request.CreationDate.AddDays(30)
    if ([System.DateTime]::Now -lt $deadlineDate)
    {
        continue
    }
    $request.Deny("The request is denied because it was not resolved within 30 days")
}
using System;
using Interop.Adsi.ApprovalRequests;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        // Bind to the Approval Requests container
        String containerPath = admService.Backend.GetConfigurationContainerPath(
            "ApprovalRequests");
        IAdmApprovalRequestContainer container =
            (IAdmApprovalRequestContainer)admService.OpenObject(
                containerPath, null, null, 0);

        // Get all pending approval requests
        Object[] requests = (Object[])container.GetApprovalRequests(
            ADM_APPROVALSTATE_ENUM.ADM_APPROVALSTATE_PENDING);

        // Iterate through the requests
        foreach (Byte[] requestID in requests)
        {
            // Bind to the approval request
            String guid = new Guid(requestID).ToString("B");
            String requestPath = String.Format("Adaxes://<GUID={0}>", guid);
            IAdmApprovalRequest request = (IAdmApprovalRequest)admService.OpenObject(
                requestPath, null, null, 0);

            // Check whether the request must be denied
            DateTime deadlineDate = request.CreationDate.AddDays(30);
            if (DateTime.Now < deadlineDate)
            {
                continue;
            }
            request.Deny(
                "The request is denied because it has not been resolved within 30 days");
        }
    }
}

Managing approvers

To get the approvers of a request, you need to bind to the directory object representing the request and call the GetApproversInfo method of the IAdmApprovalRequest interface. Request approvers are represented by the IAdmRequestApproversInfo and IAdmRequestApproversInfo2 interfaces, using which you can get and modify the list of approvers.

To get a list of all users that are approvers of a request, call the GetApproversEx method of the IAdmRequestApproversInfo2 interface. Approvers are represented by the IAdmApprovers interface.

The following code sample outputs the names and emails of all users whose approval is required for operations that are currently pending.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$admNS = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the Approval Requests container
$containerPath = $admService.Backend.GetConfigurationContainerPath(
    "ApprovalRequests")
$container = $admService.OpenObject($containerPath.ToString(),
    $NULL, $NULL, 0)

# Get all pending approval requests
$requests = $container.GetApprovalRequests("ADM_APPROVALSTATE_PENDING")

$emails = @{}

# Iterate through the requests
foreach ($requestID in $requests)
{
    # Bind to the approval request
    $guid = New-Object "System.Guid" (,$requestID)
    $guid = $guid.ToString("B")
    $requestPath = "Adaxes://<GUID=$guid>"
    $request = $admService.OpenObject($requestPath, $NULL, $NULL, 0)

    # Get users that are approvers of the request
    $approversInfo = $request.GetApproversInfo()
    $approvers = $approversInfo.GetApproversEx($request.Requestor,
        $request.TargetObject)
    foreach ($approver in $approvers)
    {
        try
        {
            $email = $approver.Get("mail")
        }
        catch [System.Runtime.InteropServices.COMException]
        {
            $name = $approver.Get("name")
            Write-Warning "No email specified for $name"
            continue
        }

        if (-not($emails.ContainsKey($email)))
        {
            $emails.Add($email, $approver.Get("name")) # Email -> Name
        }
    }
}

# Output information about approvers
foreach ($item in $emails.GetEnumerator())
{
    Write-Host $item.Value "[" $item.Key "]"
}
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Interop.Adsi;
using Interop.Adsi.ApprovalRequests;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        // Bind to the Approval Requests container
        String containerPath = admService.Backend.GetConfigurationContainerPath(
            "ApprovalRequests");
        IAdmApprovalRequestContainer container =
            (IAdmApprovalRequestContainer)admService.OpenObject(
                containerPath, null, null, 0);

        // Get all pending approval requests
        Object[] requests = (Object[])container.GetApprovalRequests(
            ADM_APPROVALSTATE_ENUM.ADM_APPROVALSTATE_PENDING);

        Dictionary<String, String> emails = new Dictionary<String, String>(
            StringComparer.OrdinalIgnoreCase);

        // Iterate through the requests
        foreach (Byte[] requestID in requests)
        {
            // Bind to the approval request
            String guid = new Guid(requestID).ToString("B");
            String requestPath = String.Format("Adaxes://<GUID={0}>", guid);
            IAdmApprovalRequest request = (IAdmApprovalRequest)admService.OpenObject(
                requestPath, null, null, 0);

            // Get users that are approvers of the request
            IAdmRequestApproversInfo2 approversInfo =
                (IAdmRequestApproversInfo2)request.GetApproversInfo();
            IAdmApprovers approvers = approversInfo.GetApproversEx(
                request.Requestor, request.TargetObject);
            foreach (IADs approver in approvers)
            {
                String email;
                try
                {
                    email = (String)approver.Get("mail");
                }
                catch (COMException)
                {
                    String name = (String)approver.Get("name");
                    Console.WriteLine("WARNING: No email specified for " + name);
                    continue;
                }

                if (!emails.ContainsKey(email))
                {
                    String name = (String)approver.Get("name");
                    emails.Add(email, name);
                }
            }
        }
        // Output information about approvers
        foreach (KeyValuePair<String, String> item in emails)
        {
            String line = String.Format("{0} [{1}]", item.Value, item.Key);
            Console.WriteLine(line);
        }
        Console.ReadLine();
    }
}

To add a user to the list of approvers, call the Add method of the ApproverTrustees property of the IAdmRequestApproversInfo interface. The ApproverTrustees property exposes the IAdmApproverTrustees interface.

To add a group to the list of approvers, call the Add method of the ApproverGroups property of the IAdmRequestApproversInfo interface. The ApproverGroups property exposes the IAdmApproverGroups interface.

Use the ManagerOfTrusteeIsApprover, ManagerOfTargetObjectIsApprover, OwnerOfRequestorOUIsApprover, and OwnerOfTargetObjectOUIsApprover properties of the IAdmRequestApproversInfo and IAdmRequestApproversInfo2 interfaces to specify additional approver options.

To update the list of approvers of a request, call the SetApproversInfo method of the Approval Request object and then call the SetInfo method to save the changes.

The following code sample modifies the list of approvers of all pending requests that were not handled within 30 days. The script adds a specific user and group to the list of request approvers and allows the manager of the user who initiated the operation to approve or deny it.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$admNS = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$admService = $admNS.GetServiceDirectly("localhost")

$newApproverUserDN = "CN=John Smith,CN=Users,DC=company,DC=com"
$newApproverUser = $admService.OpenObject(
    "Adaxes://$newApproverUserDN", $NULL, $NULL, 0)

$newApproverGroupDN = "CN=Approvers,OU=Groups,DC=company,DC=com"
$newApproverGroup = $admService.OpenObject(
    "Adaxes://$newApproverGroupDN", $NULL, $NULL, 0)


# Bind to the Approval Requests container
$containerPath = $admService.Backend.GetConfigurationContainerPath(
    "ApprovalRequests")
$container = $admService.OpenObject($containerPath.ToString(),
    $NULL, $NULL, 0)

# Get all pending approval requests
$requests = $container.GetApprovalRequests("ADM_APPROVALSTATE_PENDING")

# Iterate through the requests
foreach ($requestID in $requests)
{
    # Bind to the approval request
    $guid = New-Object "System.Guid" (,$requestID)
    $guid = $guid.ToString("B")
    $requestPath = "Adaxes://<GUID=$guid>"
    $request = $admService.OpenObject($requestPath, $NULL, $NULL, 0)

    # Check whether the approvers of the request must be modified
    $deadlineDate = $request.CreationDate.AddDays(30)
    if ([System.DateTime]::Now -lt $deadlineDate)
    {
        continue
    }

    $approvers = $request.GetApproversInfo()

    # Add a user to the list of approvers
    if (-not($approvers.ApproverTrustees.IsApprover($newApproverUser)))
    {
        $approvers.ApproverTrustees.Add($newApproverUser)
    }

    # Add a group to the list of approvers
    if (-not($approvers.ApproverGroups.IsApprover($newApproverGroup)))
    {
        $approvers.ApproverGroups.Add($newApproverGroup)
    }

    # Allow the manager of the initiator to approve or deny the request
    $approvers.ManagerOfTrusteeIsApprover = $True

    # Save the changes
    $request.SetApproversInfo($approvers)
    $request.SetInfo()
}
using System;
using Interop.Adsi;
using Interop.Adsi.ApprovalRequests;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        const String newApproverUserDN =
            "CN=John Smith,CN=Users,DC=company,DC=com";
        IAdmTop newApproverUser = (IAdmTop)admService.OpenObject(
            "Adaxes://" + newApproverUserDN, null, null, 0);

        const String newApproverGroupDN =
            "CN=Approvers,OU=Groups,DC=company,DC=com";
        IAdmGroup newApproverGroup = (IAdmGroup)admService.OpenObject(
            "Adaxes://" + newApproverGroupDN, null, null, 0);

        // Bind to the Approval Requests container
        String containerPath = admService.Backend.GetConfigurationContainerPath(
            "ApprovalRequests");
        IAdmApprovalRequestContainer container =
            (IAdmApprovalRequestContainer)admService.OpenObject(
                containerPath, null, null, 0);

        // Get all pending approval requests
        Object[] requests = (Object[])container.GetApprovalRequests(
            ADM_APPROVALSTATE_ENUM.ADM_APPROVALSTATE_PENDING);

        // Iterate through the requests
        foreach (Byte[] requestID in requests)
        {
            // Bind to the approval request
            String guid = new Guid(requestID).ToString("B");
            String requestPath = String.Format("Adaxes://<GUID={0}>", guid);
            IAdmApprovalRequest request = (IAdmApprovalRequest)admService.OpenObject(
                requestPath, null, null, 0);

            // Check whether the approvers of the request must be modified
            DateTime deadlineDate = request.CreationDate.AddDays(30);
            if (DateTime.Now < deadlineDate)
            {
                continue;
            }

            IAdmRequestApproversInfo approvers = request.GetApproversInfo();

            // Add a user to the list of approvers
            if (!approvers.ApproverTrustees.IsApprover(newApproverUser))
            {
                approvers.ApproverTrustees.Add(newApproverUser);
            }

            // Add a group to the list of approvers
            if (!approvers.ApproverGroups.IsApprover((IAdmTop)newApproverGroup))
            {
                approvers.ApproverGroups.Add(newApproverGroup);
            }

            // Allow the manager of the initiator to approve or deny the request
            approvers.ManagerOfTrusteeIsApprover = true;

            // Save the changes
            request.SetApproversInfo(approvers);
            request.SetInfo();
        }
    }
}

See also