Script Repository


Temporary group membership

February 24, 2021
1681

To allow adding users to AD groups for a limited period of time, you need to use a custom command with parameters and a scheduled task.

  1. Create a custom command that executes Script 1 below. The script adds the user for which the command is executed to the group(s) specified in the corresponding parameter. Also, it adds a record specifying when to remove the user from the group. The command must be configured for User 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 be configured for 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 target user to AD groups specified in the corresponding parameter.

Parameters

  • $startDateParam – Specifies the name of the parameter that holds the date when the user must be added to the group(s) with the param- prefix. The parameter must be of Date/Time picker type.
  • $endDateParam – Specifies the name of the parameter that holds the date when the user must be removed from the group(s) with param- prefix.
    The parameter must be of Date/Time picker type.
  • $groupsParam – Specifies the name of the parameter that holds the group(s) to which the user will be temporarily added with param- prefix.
    The parameter must be of AD object picker type.
  • $groupsParamSeparator – Specifies a separator (e.g. semicolon) for groups in the parameter.
  • $memberListProperty – Specifies the LDAP name of the multi-value property of the groups where information about adding/removing members will be stored.
Edit Remove
PowerShell
$startDateParam = "param-AddToGroupDate" # TODO: modify me
$endDateParam = "param-RemoveFromGroupDate" # TODO: modify me
$groupsParam = "param-Groups" # TODO: modify me
$groupsParamSeparator = ";" # TODO: modify me
$memberListProperty = "adm-CustomAttributeTextMultiValue1" # TODO: modify me

# Get parameter values
$groupsToAdd = $Context.GetParameterValue($groupsParam)
$startDate = $Context.Arguments.GetParameterValueAsIs($startDateParam)
$endDate = $Context.Arguments.GetParameterValueAsIs($endDateParam)

# Check dates
$addToGroup = $False
$currentDate = [DateTime]::UtcNow
if ($currentDate -gt $endDate)
{
    $Context.LogMessage("The specified date for removing the users from groups has already expired.", "Warning")
    return
}
elseif ($startDate -gt $endDate)
{
    $Context.LogMessage("The specified date for adding the user to groups is invalid.", "Warning")
    return
}
elseif ($currentDate -gt $startDate)
{
    $startDate = $currentDate
    $addToGroup = $True
}

# Build user record
$userGuid = [Guid]"%objectGUID%"
$userPath = "Adaxes://<GUID=$userGuid>"
$userRecord = "$userPath " + $startDate.ToFileTimeUtc() + "-" + $endDate.ToFileTimeUtc()

# Update the groups
foreach ($dn in $groupsToAdd.Split($groupsParamSeparator))
{
    $group = $Context.BindToObjectByDN($dn)
    
    # Get group records
    try
    {
        $records = $group.GetEx($memberListProperty)
    }
    catch
    {
        $records = @()
    }

    # Check group records
    $addNewRecord = $True
    for ($i = 0; $i -lt $records.Length; $i++)
    {
        $record = $records[$i]
        $path = ($record | Select-String -Pattern "Adaxes\:\/\/\<GUID=.+\>").Matches[0].Value
        if ($path -ne $userPath)
        {
            continue
        }
        $record = $record.Replace($path, "").Trim()
        
        # The access to this group was already requested for this user, update dates
        $dates = $record.Split("-") | %%{[Datetime]::FromFileTimeUtc($_)}
        if ((($startDate -le $dates[0]) -and ($endDate -ge $dates[0])) -or
            (($startDate -ge $dates[0]) -and ($endDate -le $dates[1])) -or
            (($startDate -le $dates[1]) -and ($endDate -ge $dates[1])) -or
            (($startDate -le $dates[0]) -and ($endDate -ge $dates[1])))
        {
            # Update record
            $records[$i] = $userRecord
            $addNewRecord = $False
            break
        }
    }
    
    # Add a record for the user to the group
    if ($addNewRecord)
    {
        $records += $userRecord
    }

    # Update user records for the group
    $group.PutEx("ADS_PROPERTY_UPDATE", $memberListProperty, $records)
    $group.SetInfo()
    
    # Directly add to groups
    if ($addToGroup)
    {
        $group.Add($userPath)
    }
}

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 multi-value property where information about adding/removing members is stored. It must be the same as $memberListProperty in Script 1.
Edit Remove
PowerShell
$memberListProperty = "adm-CustomAttributeTextMultiValue1" # TODO: modify me

function UpdateMembership($path, $operation)
{
    $isMember = $Context.TargetObject.IsMember($path)
    switch ($operation)
    {
        "Remove"
        {
            if ($isMember)
            {
                $Context.TargetObject.Remove($path)
                $objectName = $Context.GetDisplayNameFromAdsPath($path)
                $Context.LogMessage("Removed '$objectName' from group %name%", "Information")

            }
        }
        "Add"
        {
            if (-not($isMember))
            {
                $Context.TargetObject.Add($path)
                $objectName = $Context.GetDisplayNameFromAdsPath($path)
                $Context.LogMessage("Added '$objectName' to group %name%", "Information")

            }
        }
    }
}

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

$currentDate = [DateTime]::UtcNow
$updateRecords = $False
for ($i = 0; $i -lt $records.Length; $i++)
{
    $record = $records[$i]
    $path = ($record | Select-String -Pattern "Adaxes\:\/\/\<GUID=.+\>").Matches[0].Value

    $record = $record.Replace($path, "").Trim()
    $dates = $record.Split("-") | %%{[Datetime]::FromFileTimeUtc($_)}
    $Context.LogMessage($dates[1], "Information")
    if ($dates[1] -le $currentDate)
    {
        UpdateMembership $path "Remove"
        $records[$i] = $NULL
        $updateRecords = $True
    }
    elseif ($currentDate -ge $dates[0])
    {
        UpdateMembership $path "Add"
    }
}

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


Comments ( 20 )
avatar
tentaal
May 29, 2019
Hello, look great but not working.
it seems that property adm-CustomAttributeTextMultiValue1 is not populated as it remains empty after script execution.
avatar
tentaal
May 29, 2019
Oups, forget my last message, actually it works :

--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 be configured for Group object type.
avatar
cccoder
Sep 06, 2019
Thank you for these scripts.
The second one is not working, I get this error :

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
Cannot index into a null array. Stack trace: at <ScriptBlock>, <No file>: line 48
avatar
Support
Sep 06, 2019

Hello,

As per our check both scripts work just fine. Did you make any modifications to the scripts? How exactly was the second script executed? Was it ran by a Scheduled Task configured for the Group object type?

avatar
cccoder
Sep 09, 2019
Hello,

No change in the script. Uusing a scheduled task on a group object type.
avatar
Support
Sep 09, 2019

Hello, 

What about the first script? Did you make any changes in it? If so, could you, please, provide all the possible details?

avatar
cccoder
Sep 10, 2019
Hello,

First, I want to thank you for your answers.

The only things I changed in both scripts is : $memberListProperty = "adm-CustomAttributeTextMultiValue10" --> 10 insted of 1

The first script is working fine. It adds the user into the specified group in %param-group%.

Both %param-....Date% are Date/Time Picker format.

This is an example, of the CustomAttributeTextMultiValue10 after running the script :
Adaxes://<GUID=yyyyyyyy----xxxxxxx> 09.10.2019 11 31 09.12.2019 11 31
avatar
Support
Sep 10, 2019

Hello,

Thank you for the provided details. The issue occurred because of incorrect date conversion. We updated both scripts which should fix the issue. Also, if you have groups with records in the custom multivalued attribtue which were created by old scripts, clear the attribute before using the updated scripts.

avatar
cccoder
Sep 11, 2019
Hello, Thanks you , it work now but only if I choose the today date. If I choose a later day then the script add the adm-CustomAttributeTextMultiValue10 in the group but it does not add the user.
avatar
Support
Sep 11, 2019

Hello,

 

This is exactly how the script in the Custom Command should work. If the date in the start date parameter is in future, the corresponding user will be added to the group by the Scheduled Task on the specified date.

avatar
cccoder
Sep 11, 2019
Oups, yes of course, this is obvious! Sorry :-)

Thank you for the work!

Regards!
avatar
Kenneth
Sep 17, 2019
Hi,

Is it possibe to enter a period of time also? like:

"18-09-2019" until 12:00
avatar
Support
Sep 18, 2019

Hello,

Yes, it is possible. You will need to enable the Allow change time option for date parameters of the Custom Command.

 

avatar
Kenneth
Sep 30, 2019
When I use time, the attribute value is filled, but the account is not added to the group.

Value:
Adaxes://<GUID=1e86a10d-f1fa-4b03-8b01-3af27ec72b87> 132143034000000000-132143894240000000

Without the time parameter, it's working, except from removing the membership again... (both attrib. value and account)
avatar
Support
Sep 30, 2019

Hello,

> When I use time, the attribute value is filled, but the account is not added to the group.

The first script (executed in a Custom Command) adds the target user to the specified group only if the date/time specified in the corresponding parameter is equal to the current one or is in the past. If the date/time is in future, the user will be added to the group by the Scheduled Task.

> Without the time parameter, it's working, except from removing the membership again... (both attrib. value and account)

As per our check the scripts work just fine. Make sure that the date/time to remove users from groups is later than the date/time to add.

avatar
Kenneth
Sep 30, 2019
In the webform, time is showen in AM/PM (02:59PM)
In Adaxes Console, the preview of the parameters are correct 14:59

Does it has something to say? because if I remove the "Allow time change" the user is added to the gorup.

The removal schedule task doesn't work either way...
(I'm using param-startDateParam %datetime% and param-endDateParam %datetime,1d%) so even with a day between add/remove it doesn't work :(
avatar
Support
Sep 30, 2019

Hello,

If you specify only the current date in the startDateParam parameter, the user will be directly added to the specified groups. However, if the time part is present and it is in the future (e.g. if you specify 2:30 PM while the Custom Command is executed at 2:25 PM) the user will be added to the group by the Scheduled task. This behavior is by design.


To add/remove members from groups, the Scheduled Task needs to run after the specified dates. For example, if the date/time specified in the endDateParam parameter is September/30/2019 4:40 PM, the corresponding user will be removed from the corresponding group on the next run of the task following the exact time. If no time part is specified, members will be added/removed on the first run of the task on the specified day.

avatar
Kenneth
Oct 02, 2019
Hi,

Thank you, it's working now. I was using an AD attribute, not an Adaxes custom attribute.... if I replaced my AD attribute in the scripts with "CustomAttributeTextMultiValue1" everything is working! :)
avatar
Camilo
Dec 02, 2020
I don´t understand the parameter type here and what needs to be passed on or written into!?

$memberListProperty – Specifies the LDAP name of the multi-value property of the groups where information about adding/removing members will be stored.

$memberListProperty = "adm-CustomAttributeTextMultiValue1"
avatar
Support
Dec 03, 2020
Hello Camilo,

The $memberListProperty variable is not for a parameter. It is just a property where information about the time when users will be added/removed from groups will be stored. In the variable, you need to enter the LDAP name of the property, e.g. adm-CustomAttributeTextMultiValue1.
Leave a comment

Related Scripts