Script Repository


Self-service temporary group membership

February 24, 2021
1545

To enable users to add themselves to AD groups for a limited period of time, you need to use Adaxes custom commands and scheduled tasks. You need to do the following:

  1. Create a custom command that executes Script 1 below. The script adds the user who executes the command to the group on which it is executed. Also, it adds a record specifying when to remove the user from the group. The command must be configured for the Group object type.
  2. Create a scheduled task that runs Script 2 on a periodical basis. It will remove users from groups when their temporary group membership expires. The task must also be configured for the Group object type.
    Note: The time when to remove a user will be stored in an Adaxes custom attribute. The attribute must be multi-valued to allow several temporary members at once. For example, you can use CustomAttributeTextMultiValue1.

Script 1: Add temporary membership

This script can be used in a custom command that adds the initiator to an AD group.

Parameters

  • $memberListProperty - Specifies the LDAP name of the attribute that stores a list of temporary group members and the times when to remove them.
  • $durationInHours - Specifies the duration of temporary membership (in hours).
Edit Remove
PowerShell
$memberListProperty = "adm-CustomAttributeTextMultiValue1" # TODO: modify me
$durationInHours = 24 # TODO: modify me

# Build initiator path
$guid = [Guid]$Context.Initiator.UserAdsObject.Get("ObjectGuid")
$initiatorPath = "Adaxes://<GUID=$guid>"

# Build initiator record
$endDate = [System.Datetime]::UtcNow.AddHours($durationInHours)
$initiatorRecord = "$initiatorPath " + $endDate.ToFileTimeUtc()

# Get group records
try
{
    $records = $Context.TargetObject.GetEx($memberListProperty)
}
catch
{
    $records = @()
}

# Check whether initiator has already requested access to the group
$addNewRecord = $True
for ($i = 0; $i -lt $records.Length; $i++)
{
    $path = ($records[$i] | Select-String -Pattern "Adaxes\:\/\/\<GUID=.+\>").Matches[0].Value
    if ($path -ne $initiatorPath)
    {
        continue
    }
    
    # The initiator has already requested access to this group, update date
    $records[$i] = $initiatorRecord
    $addNewRecord = $False
    break
}

if ($addNewRecord)
{
    # Add information when to remove the initiator from the group
    $records += $initiatorRecord
    
    # Add initiator to the group
    $Context.TargetObject.Add($Context.Initiator.UserAdsObject.AdsPath)
}

# Update the list of members to remove
$Context.TargetObject.PutEx("ADS_PROPERTY_UPDATE", $memberListProperty, $records)
$Context.TargetObject.SetInfo()

Script 2: Remove expired temporary memberships

This script can be used in a scheduled task that removes users from AD groups when their temporary membership expires.

Parameter

  • $memberListProperty - Specifies the LDAP name of the attribute that stores a list of temporary group members and the times when to remove them. It must be the same as $memberListProperty in Script 1.
Edit Remove
PowerShell
$memberListProperty = "adm-CustomAttributeTextMultiValue1" # TODO: modify me

# Get members to remove
try
{
    $records = $Context.TargetObject.GetEx($memberListProperty)
}
catch
{
    return # No members
}

$currentDate = [DateTime]::UtcNow
$updateRecords = $False

for ($i = 0; $i -lt $records.Length; $i++)
{
    # Get user ADS path and date when to remove the user from group
    $record = $records[$i]
    $path = ($record | Select-String -Pattern "Adaxes\:\/\/\<GUID=.+\>").Matches[0].Value
    $record = $record.Replace($path, "").Trim()
    $date = [Datetime]::FromFileTimeUtc($record)

    if ($date -le $currentDate -and ($Context.TargetObject.IsMember($path)))
    {
        # Remove the user
        $Context.TargetObject.Remove($path)
        $records[$i] = $NULL
        $updateRecords = $True
    }
}

if ($updateRecords)
{
    # Update list of users to remove
    [System.String[]]$records = $records | ?{$_}
    $Context.TargetObject.PutEx("ADS_PROPERTY_UPDATE", $memberListProperty, $records)
    $Context.TargetObject.SetInfo()
}


Comments ( 8 )
avatar
Jason
Feb 11, 2019
I am attempting to run the Custom Command script, and I am receiving the following error:

"Method invocation failed because [softerra.adaxes.adsi.admuser] does not contain a method named Add".
avatar
Support
Feb 11, 2019

Hello Jason,

Looks like you configured your Custom Command for User Object type. You need to use the script in a Custom Command configured for Group Object type.

avatar
tentaal
Apr 25, 2019
Hello,
How can I change this script so heldesk can specify a user in parameter instead of using the initator?

Thanks.
avatar
Support
Apr 29, 2019

Hello,

 

If you are using Adaxes version 2018.2, this can be done using Custom Command parameters. For details, have a look at the following script from our repository: https://www.adaxes.com/script-repository/temporary-group-membrship-s533.htm.

avatar
cccoder
Sep 06, 2019
Hello,


I try to customise the script to use custom Parameters. I want to pick up the user instead of using the initiator but I get some problem with this code :

# Build initiator path
$guid = [Guid]$Context.%param-usertoadd%.UserAdsObject.Get("ObjectGuid") --> not working like this.
$initiatorPath = "Adaxes://<GUID=$guid>"

What's wrong with the syntax?

Thank you.
avatar
Support
Sep 06, 2019

Hello,

If the usertoadd parameter is of AD object picker type, you need to use the following code to bind to the user specified in the parameter:

Edit Remove
PowerShell
$user = $Context.BindToObject("Adaxes://%param-usertoadd%")

 

avatar
cccoder
Sep 06, 2019
Thank you :-)

I did this :

$user = $Context.BindToObject("Adaxes://%param-usertoadd%")
$guid = [Guid]$user.Get("objectGUID")
$initiatorPath = "Adaxes://<GUID=$guid>"

The script returns no error but the group membership is not updated. The value adm-CustomAttributeTextMultiValue1 is setted in the group with a value like this :

Adaxes://<GUID=91e9bdae-f4fe-4021-9bc2-9bc3505e2aaa> 132123316309802111
avatar
cccoder
Sep 06, 2019
I finally manage to get the first script working by changing this:
#$Context.TargetObject.Add($Context.Initiator.UserAdsObject.AdsPath)

$Context.TargetObject.Add($initiatorPath)

The second script give me an error about date format :

Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime." Stack trace: at <ScriptBlock>, <No file>: line 46 at <ScriptBlock>, <No file>: line 46

$dates = ($records[$i] | Select-String -Pattern "\d{2}\/\d{2}\/\d{4}\s\d{2}\s\d{2}\s.{2}" -AllMatches).Matches | %%{[DateTime]::ParseExact($_.Value, "MM/dd/yyyy hh mm tt", $NULL)}

$dates = ($records[$i] | Select-String -Pattern "\d{2}\/\d{2}\/\d{4}\s\d{2}\s\d{2}\s.{2}" -AllMatches).Matches | %%{[DateTime]::ParseExact($_.Value, "MM/dd/yyyy hh mm tt", $NULL)}

Maybe because I user European format dd/mm/yyyy?
avatar
Support
Sep 06, 2019
As we understand, you want to temporarily add users to groups and the solution should work not only for the initiator. Have a look at the following script from our repository: https://www.adaxes.com/script-repository/temporary-group-membrship-s533.htm.
Leave a comment

Related Scripts