comparing dates with Powershell

Bob Pants 261 Reputation points
2020-12-07T22:17:14.227+00:00

I need to delete AD users based on expiry date greater than 30 days

I can pull the users that are expired and their expiry date easy enough:

$Today = (Get-Date).ToString("dd-MM-yyyy")
$DeleteDate = (Get-Date $date).AddDays(-30).ToString("yyyyMMdd")

Get-ADUser -Filter 'enabled -eq $false' -Properties AccountExpirationDate | Select sAMAccountName, AccountExpirationDate

But I want to delete only those where the AccountExpirationDate is > 30 days.

Could someone pls help me with an expression to do this?

note my PS skill is rudimentary so simpler is better

Thanks

Windows for business Windows Server User experience PowerShell
{count} votes

5 answers

Sort by: Most helpful
  1. Anonymous
    2020-12-08T07:56:32.973+00:00

    Hi,

    The above script gives the error because $AccountExpirationDate is an array of type ADUser. To expand the AccountExpirationDate property you can add the parameter -ExpandProperty. Or you could try the following script

     $date = Get-Date  
     $deletedate = $date.AddDays(-30)  
     Get-ADUser -Filter 'enabled -eq $false' -Properties AccountExpirationDate -SearchBase "OU=test2,DC=contoso,DC=com" |   
     Where-Object{ $_.AccountExpirationDate -and ($_.AccountExpirationDate -lt $deletedate)} | Select-Object sAMAccountName, AccountExpirationDate  
    

    Best Regards,
    Ian Xue

    ============================================

    If the Answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

  2. Andreas Baumgarten 123.4K Reputation points MVP Volunteer Moderator
    2020-12-07T22:51:38.427+00:00

    Maybe this helps (not tested):

    # Get Account Expiration Date
    $AccountExpirationDate = Get-ADUser -Filter 'enabled -eq $false' -Properties AccountExpirationDate | Select AccountExpirationDate
    
    # This is just for testing
    #$AccountExpirationDate = (Get-Date).AddDays(-45)
    
    # Create a Delete Date
    $DeleteDate = (Get-Date).AddDays(-30)
    # Compare Account Expiration Date with Delete Date
    if ($AccountExpirationDate -lt $DeleteDate)
        {Write-Output "Expiration Date is older than 30 Days"
        # Add  your code here
        }
    else {Write-Output "Expiration Date is not older than 30 Days"
        # Add your code here
        }
    

    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten

    0 comments No comments

  3. Bob Pants 261 Reputation points
    2020-12-08T01:00:43.187+00:00

    Thanks the above gives an error:

    Cannot compare "@{sAMAccountName=xx; AccountExpirationDate=28/11/2020 12:00:00 AM}" to "20201108" because the objects are not the same type or the object "@{sAMAccountName=xxx;

    I tried converting the date to string like this
    $DeleteDate = (Get-Date).AddDays(-30).ToString("yyyyMMdd")

    but same error

    0 comments No comments

  4. Bob Pants 261 Reputation points
    2020-12-09T06:42:22.543+00:00

    Sorry, I'm back..

    I need to fit this into an existing script that has a 'If ($Null -ne $DisabledUsers)' loop and I'm having trouble getting the delete part to work. Is there a way to do this as a one liner like this simply by adding a pipe with Remove-ADuser command?

    Remove-ADuser seems to work when piped onto a Search-ADAccount cmd but not Get-ADuser

    For instance:

    this works, and deletes the found users (but uses the wrong criteria I want)

    Search-ADAccount -SearchBase $SearchBase -AccountInactive -UsersOnly -TimeSpan 30.00:00:00 | Where-Object {$_.enabled -eq $false} | Remove-ADUser
    

    This does not work and gives an error when Remove-ADuser is added at the end

    Get-ADUser -Filter 'enabled -eq $false' -Properties AccountExpirationDate -SearchBase $SearchBase | 
          Where-Object{ $_.AccountExpirationDate -and ($_.AccountExpirationDate -lt $deletedate)} | Select-Object sAMAccountName, AccountExpirationDate | Remove-ADuser
    

    This is the bit of script I need to change, effectively I need to make it delete users based on expiry date rather than last login date

    $DisabledUsers = Search-ADAccount -SearchBase $SearchBase -AccountInactive -UsersOnly -TimeSpan 30.00:00:00 | Where-Object {$_.enabled -eq $false} | Select SAMAccountName
    
            If ($Null -ne $DisabledUsers) {   
    
               Search-ADAccount -SearchBase  $SearchBase -AccountInactive -UsersOnly -TimeSpan 30.00:00:00 | Where-Object {$_.enabled -eq $false} | Remove-ADUser -Confirm:$False
    

    Search and Get seem to return the SAMaccountname in a different format

    Sorry If this is dumb questions, I am not a scripter


  5. Rich Matheisen 47,901 Reputation points
    2020-12-11T16:17:46.197+00:00

    I tried to post this a a comment but it won't let me! So here's an answer that's really just a comment!

    IanXue-MSFT has given you a way to fix your problem -- by piping the expected object type to the Remove-ADUser. However, you should also understand that you can use Select-Object -- but you have to provide a property in the resulting object named "Identity". You can check the help for the Remove-ADUser to see that you can pipe that property name and provide a sAMAccount as its value. To do that you'd use a calculated property:

    Select-Object @{name='Identity';expression={$_.sAMAccountName}}
    

    As IanXue-MSFT pointed out, you don't need the Select-Object in this case. Also, note that the Remove-ADUser will, by default, prompt you for permission before it removes the account. See the Notes section of cmdlet's help:

    "By default, this cmdlet prompts for confirmation as it is defined with High impact and the default value of the $ConfirmPreference variable is High. To bypass prompting for confirmation before removal, you can specify -Confirm:$False when using this cmdlet."

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.