Powershell – Automatically Removing Users from a Group after Login

$group     = "CN=MySecurityGroup,OU=People,DC=Domain,DC=local"
$dc          = (Get-ADDomainController).name  
$result = Get-ADReplicationAttributeMetadata $group -Server $dc -ShowAllLinkedValues | `          
    Where-Object {
        $_.AttributeName -eq 'member'
    } | Select-Object FirstOriginatingCreateTime, LastOriginatingChangeTime, AttributeValue   
$result | Foreach-Object {
    if ((get-date).AddHours(-12) -gt $_.LastOriginatingChangeTime) {
        $user = Get-ADUser $_.AttributeValue
        Remove-ADGroupMember -Identity Certificate_Onboarding -Members $user -confirm:$false -verbose
    }
}

LastOriginatingChangeTime = Last date when user was added to group
Dropoff Time = Remove user if this value exceeds LastOriginatingChangeTime

Removes user from group if that time exceeds defined value (such as 24 hours or 1 week). Run as task schedule every day.

The next script can be ran hourly and will check if a user has logged on recently. This covers scenarios where you may not want the user to stay in a group after they’ve logged in for the first time.

Function Get-LastLogon (){
    [cmdletbinding()]
    Param(
        [alias("UserName","User","SamAccountName","Name","DistinguishedName","UserPrincipalName","DN","UPN")]
        [parameter(ValueFromPipeline,Position=0,Mandatory)]
        [string[]]$Identity
    )
    begin{
        $DCList = Get-ADDomainController -Filter * | Select-Object -ExpandProperty name
    }
    process{
        foreach($currentuser in $Identity)
        {
            $filter = switch -Regex ($currentuser){
                '=' {'DistinguishedName';break}
                '@' {'UserPrincipalName';break}
                ' ' {'Name';break}
                default {'SamAccountName'}
            }
            Write-Verbose "Checking lastlogon for user: $currentuser"
            foreach($DC in $DCList)
            {
                Write-Verbose "Current domain controller: $DC"
                $account = Get-ADUser -Filter "$filter -eq '$currentuser'" -Properties lastlogon,lastlogontimestamp -Server $DC
                if(!$account)
                {
                    Write-Verbose "No user found with search term '$filter -eq '$currentuser''"
                    continue
                }
                Write-Verbose "LastLogon         : $([datetime]::FromFileTime($account.lastlogon))"
                Write-Verbose "LastLogonTimeStamp: $([datetime]::FromFileTime($account.lastlogontimestamp))"
                $logontime = $account.lastlogon,$account.lastlogontimestamp |
                    Sort-Object -Descending | Select-Object -First 1
            
                if($logontime -gt $newest)
                {
                    $newest = $logontime
                }
            }
            if($account)
            {
                switch ([datetime]::FromFileTime($newest)){
                    {$_.year -eq '1600'}{
                        "Never"
                    }
                    default{$_}
                }
            }
            Remove-Variable newest,lastlogon,account,logontime,lastlogontimestamp -ErrorAction SilentlyContinue
        }
    }
    end{
        Remove-Variable dclist -ErrorAction SilentlyContinue
    }
}
# If Dropoffdate is newer than last time user was added to the group = $dropoffdate -gt $_.LastOriginatingChangeTime
# If Dropoffdate is older than last logon = $dropoffdate -lt $userlastlogon
$scriptpath = "$PSScriptRoot\Onboarding_Script_Logs.txt"
$group = "CN=MySecurityGroup,OU=People,DC=Domain,DC=local"
$groupmembers = Get-ADGroupMember -Identity Certificate_Onboarding 
$dc = (Get-ADDomainController).name 
$dropoffdate = (get-date).AddDays(-2)
$dropoffhourly = (get-date).AddHours(-1)
if ($groupmembers) {
    $result = Get-ADReplicationAttributeMetadata $group -Server $dc -ShowAllLinkedValues | `          
        Where-Object {
            $_.AttributeName -eq 'member' -and `
            $_.AttributeValue -in $groupmembers.distinguishedName
        } | Select-Object LastOriginatingChangeTime, AttributeValue   
    
    $result | Foreach-Object {
        $currenttime = $(Get-date -Format "HH:mm:ss")
        $user = Get-ADUser $_.AttributeValue
        $userlastlogon = Get-LastLogon -Identity $user.SamAccountName
        if ( ($dropoffdate -gt $_.LastOriginatingChangeTime) -or ($dropoffhourly -lt $userlastlogon) ) {   
            Remove-ADGroupMember -Identity Certificate_Onboarding -Members $user -confirm:$false
        }
    }
}

Leave a comment