Temporary group membership

HI,  I would like to add a group by midnight through a script, I know the GUI has the setting to set date and time but how would I do it using a script.

Command:

Add-QADgroupmember -identity "groupname" -member $ADuser   (tonight at midnight)

any help would be much appreciated  Slight smile

  • I had a script open, I had to remove bits (so you'll need to test in your lab environment), but to add to Johnny's link

    $Type = "Add"
    $Group = "<GroupDN>"
    $Member = "<MemberDN>"
    $Reason = "<Reason>"
    $SetTime = get-date -Date (Get-date).Date -Hour 00 -Minute 00 -Second 00
    $GroupDN =  Get-QADObject -Identity $Group
    $MemberDN = Get-QADObject -Identity $Member
       
    $ControlHash=@{}
    $ControlHash.Add("OperationReason","$Reason")
    $ControlHash.Add('ScheduledOperation-SetTime',$($SetTime))
    
    if($Type -eq "Add")
    {
    	$Add = Add-QADGroupMember -Identity $GroupDN.DN -Member $MemberDN.DN -Control $ControlHash -Proxy
    }
    ElseIf($Type -eq "Remove")
    {
    	$Remove = Remove-QADGroupMember -Identity $GroupDN.DN -Member $MemberDN.DN -Control $ControlHash -Proxy
    }
    Elsehttps://www.oneidentity.com/community/active-roles/f/forum/32839/temporary-group-membership/80088#
    {
    	Write-Host "Unhandled type ($($Type))"
    }

  • so would you say this is correct, to start at 10PM

    $SetTime = get-date -Date (Get-date).Date -Hour 22 -Minute 00 -Second 00
    $ControlHash=@{}
    $ControlHash.Add('ScheduledOperation-SetTime',$($SetTime))
    Add-qadgroupmember -identity "TheGroup" -members $user -Control $ControlHash -Proxy

  • Yes

    Bear in mind however, the time that gets set is based upon your local time... so in the UK for example, currently we are in British Summer Time (GMT+1 or UTC+1), therefore if I were to add at 10, it would shown in the console as 11....

    IE I ran this:

    And it resulted in this:

    As always time zones can result in your results appears differently, so take account of this when writing/running your script. There are methods to set the time as GMT/UTC, or to the offset you require.

  • Here's something I wrote if it helps:

    #QSet-TimeBasedGroupMembership.ps1
    #written by Jon Raines on 2026-05-19

    param(
    [string]$Group, # Group
    [string]$Member, # User or Group
    [string]$Type, # Add or Remove
    [string]$Reason, # Notes as to why this change is being made (e.g. "User is leaving the company on 2024-12-31"
    [datetime]$FutureDate # Datetime for this change (e.g. "2024-12-01 08:00:00" defaults to now if not specified)
    )

    Connect-QADService -service <your ActiveRoles Admin server> -proxy

    try {
    $GroupDN = Get-QADObject -Identity $Group
    }
    catch
    {
    Write-Host "Error: Group '$Group' not found. $($_.Exception.Message)"
    exit "Group_not_found"
    }

    try {
    $MemberDN = Get-QADObject -Identity $Member
    }
    catch
    {
    Write-Host "Error: Member '$Member' not found. $($_.Exception.Message)"
    exit "Member_not_found"
    }

    if(-not $FutureDate)
    {
    $FutureDate = get-date
    $DoItNow = $true
    }
    #check if the future date is in the past, if so exit with error
    else {
    $DoItNow = $false
    if($FutureDate -lt (Get-Date))
    {
    write-error "Expiration date '$FutureDate' is in the past."
    exit "Invalid_Expiration_Date"
    }
    }

    #Verify that the type is either Add or Remove, if not exit with error
    if($Type.ToLower() -ne "add" -and $Type.ToLower() -ne "remove")
    {
    write-error "Type '$Type' is invalid. Must be either 'Add' or 'Remove'."
    exit "Invalid_Type"
    }

    #Verify that a reason was provided, if not exit with error
    if(-not $Reason)
    {
    write-error "Reason for change must be provided."
    exit "Reason_Required"
    }

    #check if the member is already in the group
    $MemberList = Get-QADGroupMember -Identity $GroupDN.DN -ErrorAction SilentlyContinue
    if ($MemberList -match $MemberDN.SamAccountName) { $IsMember = $true } else { $IsMember = $false }

    $controlHash = @{}
    $controlHash.add("ScheduledLink-GetPending",1)
    $controlHash.add("ScheduledLink-GetStartEndTime",1)

    #Neet to see if there are any existing scheduled operations for this group and member, if so exit with error
    $ExistingOperations = Get-QADGroupMember -Identity $GroupDN.DN -Control $controlHash -ErrorAction SilentlyContinue | Select-Object distinguishedName, SamAccountName, "edsva-ScheduledLink-StartTime", "edsva-ScheduledLink-EndTime"
    #loop though the existing operations and check if there is a pending operation for this member
    $HasPendingAddOperation = $false
    $HasPendingRemoveOperation = $false
    foreach($Operation in $ExistingOperations)
    {
    if($Operation.SamAccountName -eq $MemberDN.SamAccountName) {
    $ExistingStartTime = $Operation.'edsva-ScheduledLink-StartTime'
    $ExistingEndTime = $Operation.'edsva-ScheduledLink-EndTime'
    if ($ExistingStartTime -gt (Get-Date) -or $ExistingEndTime -gt (Get-Date)) {
    if ($ExistingStartTime -gt (Get-Date)) {
    $HasPendingAddOperation = $true
    write-host "Warning: a pending add operation is scheduled to start at $ExistingStartTime for member '$Member' in group '$Group'."
    }
    if ($ExistingEndTime -gt (Get-Date)) {
    $HasPendingRemoveOperation = $true
    write-host "Warning: a pending remove operation is scheduled to end at $ExistingEndTime for member '$Member' in group '$Group'."
    }
    }
    }
    }

    #setup the control hash for the scheduled operation
    $ControlHash=@{}
    $ControlHash.Add("OperationReason","$Reason")
    $ControlHash.Add('ScheduledOperation-SetTime',$($FutureDate.ToUniversalTime()))

    if($Type.ToLower() -eq "add")
    {
    if ($IsMember) {
    if ($HasPendingRemoveOperation) {
    write-host "Warning: '$Member' is already in group '$Group'. Cannot add."
    exit "Already_a_member"
    } else {
    write-host "Warning: '$Member' is already in group '$Group'. Cannot add."
    exit "Already_a_member"
    }
    } else {
    if ($HasPendingAddOperation) {
    if ($DoItNow) {
    write-host "Warning: '$Member' is not currently in group '$Group', but there is a pending add operation scheduled to start at $ExistingStartTime."
    write-host "User will be added to the group now."
    } else {
    write-host "Updating the pending add operation to $FutureDate as the new scheduled start time."
    }
    } else {
    write-host "'$Member' is not currently in group '$Group'. Scheduling add operation for $FutureDate."
    }
    }
    try {
    if ($DoItNow) {
    $Add = Add-QADGroupMember -Identity $GroupDN.DN -Member $MemberDN.DN
    write-host "Success: '$Member' added to '$Group' effective immediately."
    exit "Success"
    } else {
    $Add = Add-QADGroupMember -Identity $GroupDN.DN -Member $MemberDN.DN -Control $ControlHash
    write-host "Success: '$Member' scheduled at $FutureDate to be added to '$Group'."
    exit "Success"
    }
    } catch {
    write-error "Error adding member to group: $($_.Exception.Message)"
    exit "Add_Error"
    }
    }
    ElseIf($Type.ToLower() -eq "remove")
    {
    if (-not $IsMember) {
    #if there is a pending add operation, we can still schedule the remove, but warn the user that the member is not currently in the group
    if ($HasPendingAddOperation) {
    if ((-not $DoItNow) -and $FutureDate -le $ExistingStartTime) {
    write-host "Warning: '$Member' is not currently in group '$Group', but there is a pending add operation scheduled to start at $ExistingStartTime."
    write-host "However, it makes no sense to schedule a remove operation for $FutureDate, which is at or before the add operation."
    exit "Schedule_Error"
    } elseif ($DoItNow) {
    write-host "Warning: '$Member' is not currently in group '$Group', but there is a pending add operation scheduled to start at $ExistingStartTime."
    write-host "Removing the pending add operation so that user will not be added to the group, as you have requested to remove them now."
    } else {
    write-host "Notice: '$Member' is not currently in group '$Group', but there is a pending add operation scheduled to start at $ExistingStartTime."
    write-host "Scheduling remove operation for $FutureDate"
    }
    } else {
    write-host "Warning: '$Member' is not in group '$Group'. Cannot remove."
    exit "Not_a_member"
    }
    } else {
    if ($HasPendingRemoveOperation) {
    write-host "Updating the pending remove operation to $FutureDate as the new scheduled start time."
    } else {
    write-host "'$Member' is currently in group '$Group'. Scheduling remove operation for $FutureDate."
    }
    }
    try {
    if ($DoItNow) {
    $Remove = Remove-QADGroupMember -Identity $GroupDN.DN -Member $MemberDN.DN
    write-host "Success: '$Member' removed from '$Group' effective immediately."
    exit "Success"
    } else {
    $Remove = Remove-QADGroupMember -Identity $GroupDN.DN -Member $MemberDN.DN -Control $ControlHash
    write-host "Success: '$Member' scheduled at $FutureDate to be removed from '$Group'."
    exit "Success"
    }
    } catch {
    write-error "Error removing member from group: $($_.Exception.Message)"
    exit "Remove_Error"
    }
    }
    else
    {
    write-error "Unhandled type ($Type)"
    exit "Unhandled_ErrorType"
    }

    return "Done?"

  • Yeah, that time zone part was confusing.   

    $ControlHash.Add('ScheduledOperation-SetTime',$($SetTime.ToUniversalTime()))

  • As far as I know, Add-QADGroupMember doesn't have a built-in option to schedule membership changes. You'd typically need to create a scheduled task that runs the command at midnight, or use the GUI's temporary membership feature if available in your environment.

  • David,

    The scripts provided by John and Stu above are accurate examples of using the "ScheduledOperation-SetTime" control in order to schedule a temporal group membership event. That is the built-in option.