Expired Accounts life cycle

Hi Team.

Just looking for some suggestions on the best way forward.

I have a new user form that is just creating a temp AD user. Very basic account and that account by default has a 21 days account expiry set at creation time.

Now what we are wanting to do is

1) Account created with 21 days until account expires.

2) At 14 and 19 days send an email to the person who created the account with a Keep or Delete approval type email

3) If no response at 21 days then disable the account

4) If person who created the account clicks Keep then the account expiry is extended 21 days

5) If person clicks Delete then the account is automatically deleted

Based on the above do you think this would typically be a single work flow? Would it be easier to put the accounts in a group and have the check performed on the group members?

Just trying to work out the best approach to this.

Parents
  • I would use more than one workflow. A scheduled workflow to run daily and check virtual attributes that  contains data such as dates, or days. Then I'd create another workflow based on virtual attribute changes, then initiate the approval from there. 

  • Thanks, 

    Yes i had come to the same conclusion and approach and started to work down that path so thank you validating my thinking. 

    I am trying to reuse the script  provided which works great in a new user workflow. I am trying to use this in a scheduled task workflow.

    The plan is the workflow will run on a schedule. it searches a AD group that contains all the accounts i want to check the accountexpires on. If it find an account and the script returns true then set the VA on the workflow to TRUE

    When the workflow runs it displaying the error 

    Activity 'If-Else Branches' encountered an error.
     Details <<<
    At line: 16 char:5. Exception calling "Get" with "1" argument(s): "Object reference not set to an instance of an object."

    function Convert-Int8ToDateTime($Request)
    {
        $MaxDays = 21
    
        $EvalDate = (Get-Date).AddDays($MaxDays)
       
        $Int8 = $Request.get("accountExpires")
        $Return = "FALSE"
       
    
        if($Int8)
        {    
            if([DateTime]::FromFileTimeUTC($Int8) -ge $EvalDate)
            {
                $Return = $TRUE
                #throw "TRUE"
            }
        }
        
        return $Return
    }

  • Hi  

    You have two options

    1) Search for your users within the script you call, and them loop through each and perform the action you required, or

    2) If you are using the Search activity (FoundObject) step, and are putting an If/Else in, then you'd need to modify your code so that it executes against the foundobject, not $Request. Have a look at the SDK (Specifically "Retrieving data from a workflow context" and look at the FoundObject Method, IE: 

  • Thanks Stu. 

    I am going to go down the Powershell route

    I am just trying to knock something up that will pull the correct accounts. 

    I have two accounts in the security group. I have one account that expires in 14 days and one that expires in 21 days. I am trying to get it to only return the accounts at day 14 but its pulling in 14 and 21. 

    The thing is the date the account will expire is actually day 15 and not 14.

    Example 14 days ago from today is the 15th of July but the account will expire on 16th at 00:00

    Username AccountExpires
    -------- --------------
    USER1       22/07/2024 00:00:00
    USER2       16/07/2024 00:00:00

    I have played around with most of not all of the filters. 

    Any suggestions? 

    # Specify the group
    $securityGroup = "GROUPNAME"
    
    # Calculate the date less than 14 days from now
    $expiryThreshold14 = (Get-Date).AddDays(-14)
    # Get members of the security group
    $groupMembers = Get-QADGroupMember -Identity $securityGroup
    
    # Loop through each member and check account expiration
    foreach ($user in $groupMembers) {
        # Get user details
        $userDetails = Get-QADUser -Identity $user.SamAccountName -IncludeAllProperties
        
        # Check if the account expiration date is set and compare it
        if ($userDetails.AccountExpires -ne [System.DateTime]::MaxValue) {
            if ($userDetails.AccountExpires -gt $expiryThreshold14 ) {
                
                # Output the user's details
                [PSCustomObject]@{
                    Username           = $userDetails.SamAccountName
                    AccountExpires     = $userDetails.AccountExpires
                }
            }
        }
    }
    

  • I have implemented the WIKI item below so that i at least dont need to do the conversion. 

     Populating a custom Virtual Attribute with a readable accountExpires timestamp using an Active Roles Policy Script .

    However i still have the same issue. 

    Updated PowerShell code below. 

    # Connect Quest Active Roles
    Connect-QADService -Service "AR-SERVER-NAME" -Proxy
    
    $Groupname = "AD-GROUPNAME"
    
    # Calculate the date less than 14 days from now
    $expiryThreshold14 = (Get-Date).AddDays(-14)
    # Get members of the security group
    $groupMembers = Get-QADGroupMember -Identity $Groupname
    
    # Loop through each member and check account expiration
    foreach ($user in $groupMembers) {
        # Get user details
        $userDetails = Get-QADUser -Identity $user.SamAccountName -IncludedProperties edsvaAccountExpiresReadable
        
        # Check if the account expiration date is set and compare it
            if ($userDetails.edsvaAccountExpiresReadable -ge $expiryThreshold14 ) {
    
                # Output the user's details
                [PSCustomObject]@{
                    Username           = $userDetails.SamAccountName
                    AccountExpires     = $userDetails.edsvaAccountExpiresReadable
                }
            }
        }
    

  • Hi. 

    I am also looking at this from a Workflow side as well but really running in to the exact same issue. 

    I have created a workflow that searches for any user accounts in a security group. I am then saving the date and time value from the edsvaAccountExpiresReadable attribute

    I then have a IF-Else branch where i am trying to say if user accounts edsvaAccountExpiresReadable from the saved object get todays date and time - minus 21 days. 

    This should return at least one account where the edsvaAccountExpiresReadable date is 07/09/2024 00:00:00

    I am just trying to configure something that will find users at 14 and 21 days but right now cant even get it to return just 21 days. 

    I thought this would be easier as i am now not having to do the conversion of dates. 

    If the process works it should hit the Stop/Block 1 but its hitting Stop/Block 2 so i know its not finding accounts. 

    if i change it from equals to less than equals then it is finding accounts and hitting the Stop/Block 1 but i need to be specific at only 21 days or only 14 days. 

  • Ok this seems to be doing the trick in the Powershell code.

    Seems if i want to be specific i need to knock one day off what i am looking for. Example if i want account that expire in 14 days i look for 13 days and if i want 21 days i look for 20 days 

    # Connect Quest Active Roles
    Connect-QADService -Service "AR-SERVER-NAME" -Proxy
    
    # Calculate the date less than 14 days from now
    $expiryThreshold13 = (Get-Date).AddDays(-13)
    $expiryThreshold14 = (Get-Date).AddDays(-14)
    $expiryThreshold15 = (Get-Date).AddDays(-15)
    $expiryThreshold20 = (Get-Date).AddDays(-20)
    $expiryThreshold21 = (Get-Date).AddDays(-21)
    $expiryThreshold22 = (Get-Date).AddDays(-22)
    
    write-host "Today -13 Days =" $expiryThreshold13
    write-host "Today -14 Days =" $expiryThreshold14
    write-host "Today -15 Days =" $expiryThreshold15
    write-host "Today -20 Days =" $expiryThreshold20
    write-host "Today -21 Days =" $expiryThreshold21
    write-host "Today -22 Days =" $expiryThreshold22
    
    $Groupname = "AD-GROUP"
    
    # Calculate the date 13 days ago in UTC
    $dateThreshold = (Get-Date).AddDays(-13).Date
    
    # Retrieve the users in the specified security group
    $group = Get-QADGroup $groupName
    $users = Get-QADGroupMember $groupname -IncludedProperties edsvaAccountExpiresReadable  | Where-Object { $_.Type -eq 'User' }
    
    # Filter users whose accounts expired 13 days ago
    $expiredUsers = $users | Where-Object {
        if ($_.edsvaAccountExpiresReadable  -ne 0 -and $_.edsvaAccountExpiresReadable -ne $null) {
            $accountExpiresDate = ($_.edsvaAccountExpiresReadable)
            return $accountExpiresDate -eq $dateThreshold
        }
        return $false
    }
    
    # Display the expired users
    $expiredUsers | Select-Object Name, SamAccountName, AccountExpires

  • re howeveHi Craig

    Have a look at the below parameters of Get-QADUser, these would allow you to find all user accounts within a particular directory object (OU structure or MU), and filter the objects to Expire after, Expire before, expire between, expire outside of, or never expire. 

    • AccountExpiresBefore
    • AccountExpiresAfter
    • AccountNeverExpires

    This is an alternative approach, to only retrieve objects you want to process.

    In a similar value, Get-Help <commandlet name> will give you other bits of information about parameters available for a command.

    In the case of Get-QADGroupMember, there is a "Type" parameter, where you can specify "-Type user"

    or if you also want to include indirect members of the group also include "-Indirect"

    You're normally better to filter the results from a command before receiving them, rather than getting all the records and filtering them with a Where-Object. There are however reasons why you might want to get all the data, and filter in your script.

  • Thanks Stu. I will take a look at that and see if i can improve it 

Reply Children
No Data