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:
- 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.
- 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).
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.
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()
}
"Method invocation failed because [softerra.adaxes.adsi.admuser] does not contain a method named Add".
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.
How can I change this script so heldesk can specify a user in parameter instead of using the initator?
Thanks.
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.
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.
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:
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
#$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?