0 votes

I have read the section on Managing Approvals, but I'm not having any luck implementing something I'm trying to do.

Being the only service administrator, I want approval requests to go only to me. However, should I be unavailable for a day and am not able to process them, I'd like to temporarily allow for one or two other admins to see and process pending requests. Is that possible?

by (470 points)
0

Hello,

We suggest the following solution:

  1. In the Business Rule(s) that sends operations for approval, you can specify yourself as a possible approver and also specify all other users who can approve requests while you are absent also as possible approvers.

  2. You can use a certain property of your own account to serve as a flag that you are not available and someone else can process Approval Requests. For this purpose, you can use one of Adaxes virtual properties. Such properties are not stored in AD, but you can use them as any other properties of directory objects. For example, you can use CustomAttributeBoolean1 that can store boolean (True/False) values.

  3. You can create a Business Rule triggered Before Updating an Approval Request. Since processing (approving, denying, canceling) an Approval Request means updating it, the Business Rule will be triggered once anyone tries to process an Approval Request.

  4. The Business Rule will behave as follows:

    • If you try to Approve or Deny an Approval Request, it will allow you to do this in any case.
    • If someone else tries to Deny or Approve a Request, it will check the flag whether you are out of office. If the flag is set to True, it will allow to process the Request, if not, it will cancel any attempt to process it.

If you are OK with such a solution, we will provide you with the necessary details and the script required to accomplish the task.

0

That seems like a fine solution. The property is good, too, since approvals are related to Adaxes only, and not AD.

I'd be interested in seeing how you'd implement the solution. Thanks!

1 Answer

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

Hello,

To implement what you want, you need to create a Business Rule that will be triggered Before Updating an Approval Request and will allow processing an Approval Request only in the following cases:

  • The Request is not being Canceled (we should allow users cancel their own Approval Requests if they made a mistake, for example).
  • The Request is processed by someone else when you are available at the office.

The Business Rule will perform all the checks with the help of a PowerShell script triggered by the If PowerShell script returns True condition, and the Request procession will be stopped with the help of the Cancel this operation action. Since a Business Rule that you need to create cannot be created from the GUI, you'll need to create it with a script. To do this:

  1. Copy the following script and paste it to a text editor (e.g. notepad.exe).

    
     $ruleName = "My Rule" # TODO: Modify me
     $defaultApprover = "John Doe,CN=Users,DC=example,DC=com" # TODO: Modify me
     $reasonMessage = "I'm at the office now and can approve Requests myself!" # TODO: Modify me
     $scriptDescription = "Check whether Request procession is allowed" # TODO: Modify me
     $flagProperty = "adm-CustomAttributeBoolean1" # TODO: Modify me
    
     $scriptBlock = @"
     `$defaultApproverDN = `"$defaultApprover`" `# TODO: Modify me
     `$flag = `"$flagProperty`" `# TODO: Modify me
    
     `# Check whether the Request is Approved, Denied or Cancelled
     `$requestBeingProcessed = `$Context.IsPropertyModified(`"adm-ApprovalState`")
     if (`!`$requestBeingProcessed)
     {
         `$Context.ConditionIsMet = `$False
         return
     }
    
     `# Allow Request Initiators to Cancel their own Requests
     `$requestStatus = `$Context.GetModifiedPropertyValue(`"adm-ApprovalState`")
     if (`$requestStatus -eq 3)
     {
         `$Context.ConditionIsMet = `$False
         return
     }
    
     `# Allow processing to the default approver
     if (`"`%adm-InitiatorDN`%`" -ieq `$defaultApproverDN)
     {
         `$Context.ConditionIsMet = `$False
         return
     }
    
     `# Check whether the default approver is in office
     `$defaultApproverObj = `$Context.BindToObjectByDN(`$defaultApproverDN)
    
     try
     {
         `$allowedToApprove = `$defaultApproverObj.Get(`$flag)
     }
     catch
     {
         `$Context.ConditionIsMet = `$True
         return
     }
    
     `$Context.ConditionIsMet = `!`$allowedToApprove
     "@
    
     # Connect to the Adaxes service
     $admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
     $admService = $admNS.GetServiceDirectly("localhost")
    
     # Bind to the 'Business Rules' container
     $businessRulesPath = $admService.Backend.GetConfigurationContainerPath(
         "BusinessRules")
     $businessRulesContainer = $admService.OpenObject($businessRulesPath,
         $NULL, $NULL, 0)
    
     # Create a new Business Rule
     $rule = $businessRulesContainer.Create("adm-BusinessRule", "CN=$ruleName")
    
     # Triggering Operation: Before updating an Approval Request
     $rule.ExecutionMoment = "ADM_BUSINESSRULEEXECMOMENT_BEFORE"
     $rule.ObjectType = "adm-ApprovalRequest"
     $rule.OperationType = "set properties"
     $rule.Disabled = $False
     $rule.SetInfo()
    
     # Include All Objects in the Activity Scope of the Business Rule
     $scopeItem = $rule.ActivityScopeItems.Create()
     $scopeItem.BaseObject = $NULL
     $scopeItem.Type = "ADM_SCOPEBASEOBJECTTYPE_ALL_DIRECTORY"
     $scopeItem.Inheritance = "ADS_SCOPE_SUBTREE"
     $scopeItem.Exclude = $False
     $scopeItem.SetInfo()
     $rule.ActivityScopeItems.Add($scopeItem)
     $rule.SetInfo()
    
     # Create a new set of actions and conditions
     $actionsAndConditions = $rule.ConditionedActions.Create()
     $actionsAndConditions.ConditionsLogicalOperation = "ADM_LOGICALOPERATION_AND"
     $actionsAndConditions.SetInfo()
    
     # Create the If PowerShell returns True condition that performs all the checks
     $condition = $actionsAndConditions.Conditions.CreateEx("adm-ScriptCondition")
     $scriptCondition = $condition.GetCondition()
     $scriptCondition.ScriptDescription = $scriptDescription
     $scriptCondition.Script = $scriptBlock
     $condition.SetCondition($scriptCondition)
     $condition.SetInfo()
     $actionsAndConditions.Conditions.Add($condition)
    
     # Add 'Cancel this operation' action
     $action = $actionsAndConditions.Actions.CreateEx("adm-CancelOperationAction")
     $action.ExecutionOptions = "ADM_ACTIONEXECUTIONOPTIONS_SYNC"
     $actionObj = $action.GetAction()
     $actionObj.ReasonMessage = $reasonMessage
     $action.SetAction($actionObj)
     $action.SetInfo()
     $actionsAndConditions.Actions.Add($action)
    
     # Add the set to the Business Rule
     $rule.ConditionedActions.Add($actionsAndConditions)
    
     # Save the Business Rule
     $rule.SetInfo()
    
  2. In the script:

    • $ruleName - the name of the Business Rule that will be created,
    • $defaultApprover - the Distinguished Name (DN) of the approver who will be allowed to approve Requests at any time (that is, the DN of your own user account),
    • $reasonMessage - text that will be shown to users when their attempt to process a Request will be canceled,
    • $scriptDescription - a short description of the PowerShell script as appears in the list of actions/conditions of the Business Rule,
    • $flagProperty - the LDAP name of the property of your user account that will serve as a flag that you are out of office.

    Modify the above variables to your requirements.

  3. Save the script to a file with a .ps1 extension, for example, Myscript.ps1.

  4. Copy the file with the script to the computer where your Adaxes service is installed.

  5. Log on to that computer with credentials of Adaxes default service administrator (the user that you specified during Adaxes installation).

  6. Launch Windows PowerShell. To do this:

    • Press Win+R.
    • Type powershell.exe.
    • Press Enter.
  7. Navigate to the directory where you copied the script. For example, if you copied it to C:\Scripts, type

     cd C:\Scripts
    
  8. Launch the script. For example, if you named the file with the script Myscript.ps1, type

     .\Myscript.ps1
    
  9. When the script completes, the required Business Rule will appear in Adaxes under the name that you specified in $ruleName. When the Rule is created, if necessary, you can modify it the same as any other Business Rule in Adaxes. You can add, remove, modify the actions and conditions etc.

After creating the Business Rule, you can use the property that you specified in $flagProperty as follows:

  • When the property is set to $False or not specified, you are at the office and can process Requests yourself. Other people who try to process Approval Requests will not be able to do that.
  • When the property is set to $True, you not available, and other people specified as possible Approvers of Approval Requests can process them.
0

I'm going to add this and test is out, but I have one other question related to the custom attribute.

Is it possible to use a flag or property currently used by Outlook/Exchange as the out-of-office flag? In other words, instead of using adm-CustomAttributeBoolean1, could I use the LDAP property (assuming it exists) for one currently out of the office?

This would eliminate the need for me to set a seperate flag.

0

Hello,

That's possible. That can't be done by simply checking a LDAP property, but it won't be very difficult with the help of Adaxes ADSI API. However, it will take some time to accomplish. We've assigned our script guys to the task and will update you as soon as they come up with a modified script.

0

Hello,

The following version of the script determines whether you are out of office basing on OOF configuration. Use it instead of the script that you currently have.

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

$ruleName = "My Rule" # TODO: Modify me
$defaultApprover = "John Doe,CN=Users,DC=example,DC=com" # TODO: Modify me
$reasonMessage = "I'm at the office now and can approve Requests myself!" # TODO: Modify me
$scriptDescription = "Check whether Request procession is allowed" # TODO: Modify me

$scriptBlock = @"
`$defaultApproverDN = `"$defaultApprover`" `# TODO: Modify me

`$Context.ConditionIsMet = `$False

`# Check whether the Request is Approved, Denied or Cancelled
`$requestBeingProcessed = `$Context.IsPropertyModified(`"adm-ApprovalState`")
if (`!`$requestBeingProcessed)
{
    return
}

`# Allow Request Initiators to Cancel their own Requests
`$requestStatus = `$Context.GetModifiedPropertyValue(`"adm-ApprovalState`")
if (`$requestStatus -eq 3)
{
    return
}

`# Allow processing to the default approver
if (`"`%adm-InitiatorDN`%`" -ieq `$defaultApproverDN)
{
    return
}

`# Check whether the default approver is in office
`$defaultApproverObj = `$Context.BindToObjectByDN(`$defaultApproverDN)

# Get Auto-Reply configuration
`$mailboxParams = `$defaultApproverObj.GetMailParameters()
`$automaticReplies = `$mailboxParams.AutoReplyConfiguration

# Get OOF status
`$automaticRepliesStatus = `$automaticReplies.AutoReplyState
switch (`$automaticRepliesStatus)
{
    "ADM_EXCHANGE_OOFSTATETYPE_DISABLED" 
    {
        # OOF disabled: the default approver is in office
        `$Context.ConditionIsMet = `$True
        return
    }
    "ADM_EXCHANGE_OOFSTATETYPE_ENABLED" 
    {
        # OOF enabled: the default approver is out of office
        return
    }
    "ADM_EXCHANGE_OOFSTATETYPE_SCHEDULED" 
    {
        # OOF scheduled: check whether OOF is enabled right now
        # Get current date
        `$currentDate = Get-Date

        # Check when OOF is scheduled to be enabled
        `$startDate = `$automaticReplies.StartTime
        `$endDate = `$automaticReplies.EndTime

        if ((`$startDate -lt `$currentDate) -and (`$endDate -gt `$currentDate))
        {
            return
        }
        `$Context.ConditionIsMet = `$True
    }
}

"@

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

# Bind to the 'Business Rules' container
$businessRulesPath = $admService.Backend.GetConfigurationContainerPath(
    "BusinessRules")
$businessRulesContainer = $admService.OpenObject($businessRulesPath,
    $NULL, $NULL, 0)

# Create a new Business Rule
$rule = $businessRulesContainer.Create("adm-BusinessRule", "CN=$ruleName")

# Triggering Operation: Before updating an Approval Request
$rule.ExecutionMoment = "ADM_BUSINESSRULEEXECMOMENT_BEFORE"
$rule.ObjectType = "adm-ApprovalRequest"
$rule.OperationType = "set properties"
$rule.Disabled = $False
$rule.SetInfo()

# Include All Objects in the Activity Scope of the Business Rule
$scopeItem = $rule.ActivityScopeItems.Create()
$scopeItem.BaseObject = $NULL
$scopeItem.Type = "ADM_SCOPEBASEOBJECTTYPE_ALL_DIRECTORY"
$scopeItem.Inheritance = "ADS_SCOPE_SUBTREE"
$scopeItem.Exclude = $False
$scopeItem.SetInfo()
$rule.ActivityScopeItems.Add($scopeItem)
$rule.SetInfo()

# Create a new set of actions and conditions
$actionsAndConditions = $rule.ConditionedActions.Create()
$actionsAndConditions.ConditionsLogicalOperation = "ADM_LOGICALOPERATION_AND"
$actionsAndConditions.SetInfo()

# Create the 'If PowerShell returns True' condition that performs all the checks
$condition = $actionsAndConditions.Conditions.CreateEx("adm-ScriptCondition")
$scriptCondition = $condition.GetCondition()
$scriptCondition.ScriptDescription = $scriptDescription
$scriptCondition.Script = $scriptBlock
$condition.SetCondition($scriptCondition)
$condition.SetInfo()
$actionsAndConditions.Conditions.Add($condition)

# Add 'Cancel this operation' action
$action = $actionsAndConditions.Actions.CreateEx("adm-CancelOperationAction")
$action.ExecutionOptions = "ADM_ACTIONEXECUTIONOPTIONS_SYNC"
$actionObj = $action.GetAction()
$actionObj.ReasonMessage = $reasonMessage
$action.SetAction($actionObj)
$action.SetInfo()
$actionsAndConditions.Actions.Add($action)

# Add the set to the Business Rule
$rule.ConditionedActions.Add($actionsAndConditions)

# Save the Business Rule
$rule.SetInfo()
0

Thank you so much for this script. It is perfect for what I need!

Related questions

+1 vote
1 answer

Aiming to go passwordless, this is a must-have

asked Aug 30, 2023 by JM (30 points)
0 votes
1 answer

Our network team is working on a system to allow temporary AD user accounts that will be allowed to obtain access to network services. (They are doing this by ... User account has an expiration date, it will automatically disable at conclusion of event.

asked Jun 14, 2022 by RayBilyk (240 points)
0 votes
1 answer

Hello, I am trying to find out if it would be possible to create a tool/ process on Adaxes that will allow me to create a new AD user and set a time limit on the ... or guides on how i might create a new users or set deletion / disable times? Thanks Rhys

asked Nov 9, 2021 by R_C (70 points)
0 votes
1 answer

I have a business rule to create a user in our AD, and then have it create a new O365 account and assign it a license. How can I have it create a temporary password that I specify during that business rule?

asked Jun 17, 2020 by keecit (60 points)
0 votes
1 answer

We have a rule setup that when a user requests membership into a group it will email approvers of the group for approval. I would like to create a report that sends out a list of ALL approvers for every group we have approvals setup for.

asked Dec 18, 2023 by jujones79 (20 points)
3,549 questions
3,240 answers
8,232 comments
547,814 users