Use Get-MailboxStatistics in Get-QADuser

by flcn_ at 2013-04-20 04:16:56

Hello Guys,

In our company we need to cleanup our ActiveDirectory and Im trying to put a script together in which I filter all inactive accounts and move them to a temporary OU.

I figured that the LastLogonTimeStamp is not enough to make it waterproof since the replication time between the DCs is not realtime. (We have 4 DCs)
Therefor Id like to check on both "LastLogonTimeStamp" via get-QADuser (In AD) and "LastLognTime" by using get-mailboxstatistics (In Exchange).

My best guess is something like]
$accounts = Get-QadUser -LdapFilter "((objectCategory=person)(sn=))" -SearchRoot $ou -SizeLimit $sizeLimit | Where-Object { $.LastLogontimestamp -ne $null -and $.LastLogontimestamp -le $date -and (Get-2003MailboxStatistics -server servername -Identity $_.SAMaccountName).LastLogonTime -le $date}
But I think its not working properly, im not sure about the -and (get-2003mailbox… etc part). Can someone help me or provide me an alternative? Thanks in advance

Our main goals is to filter all accounts in two specific OUs that have not logged in to AD or Accessed their maibloxes since 01-05-2012 (1st of May 2012).

Below is the full script:

Set-PSDebug -Strict

# Add-PSSnapin Quest.ActiveRoles.ADManagement
. D:\powershell_scripts\Danny\Get-MailboxStatistics.ps1

$year = "2012"
$month = "5"
$day = "1"
$sizeLimit = "0"
$OUs = "OU=office,OU=Useraccounts,DC=domain,DC=lan","OU=sales,OU=Useraccounts,DC=domain,DC=lan"
$OUToDelete = "OU=ToDelete,OU=Useraccounts,DC=domain,DC=lan"
$date = New-Object System.DateTime -ArgumentList @($year,$month,$day,0,0,0)
$ExpirationDate = New-Object System.DateTime -ArgumentList @(2000,01,01,0,0,0)
$epoch = New-Object System.DateTime -ArgumentList @(1601,01,01,0,0,0)

foreach($ou in $OUs){
$accounts = Get-QadUser -LdapFilter "((objectCategory=person)(sn=
))" -SearchRoot $ou -SizeLimit $sizeLimit | Where-Object { $.LastLogontimestamp -ne $null -and $.LastLogontimestamp -le $date -and (Get-2003MailboxStatistics -server servername -Identity $.SAMaccountName).LastLogonTime -le $date}
foreach ($user in $accounts) {
if ($user -eq $null){
Write-Host ("Geen account(s) gevonden in $ou die aan creteria voldoen!")
break
}
elseif (($user -ne $null) -and (!($user.AccountIsDisabled))) {
Write-Host ("Gebruiker: " + $user.Name)
Write-Host ("Laatste Logon: " + $user.LastLogonTimestamp)
$description = "Marked for deletion due inactivity +1year on " + (Get-Date).Day + "-" + (Get-Date).Month + "-" + (Get-Date).Year
Set-QADUser -Identity $user -Description $description -AccountExpires $ExpirationDate
Move-QADObject $user -NewParentContainer $OUToDelete
}
elseif (($user -ne $null) -and ($user.AccountIsDisabled)) {
Write-Host ("Gebruiker: " + $user.Name)
Write-Host ("Laatste Logon: " + $user.LastLogonTimestamp)
$description = "Marked for deletion due inactivity +1year on " + (Get-Date).Day + "-" + (Get-Date).Month + "-" + (Get-Date).Year
Enable-QADUser -Identity $user
Set-QADUser -Identity $user -Description $description -AccountExpires $ExpirationDate
Move-QADObject $user -NewParentContainer $OUToDelete
}
}
}

Get-QADUser -SearchRoot $OUToDelete -includeallproperties | Select displayname, samaccountname, employeeID, lastlogontimestamp | Export-csv c:\UsersToDelete.csv -NoTypeInformation
by DonJ at 2013-04-20 08:38:52
As a first suggestion, it might be better to check the date the user last changed their password. If you enforce a password age, anyone significantly past that age is obviously not logging on. That attribute is replicated more reliably. You could also, fairly easily since you only have four, query lastLogonTimestamp from each DC and just take the newest value. Also, lastLogonTimestamp will be accurate to within 14 days. You could just set your cutoff date to account for that. See http://blogs.technet.com/b/askds/archiv … works.aspx.

Break out the Get-MailboxStatistics bit, and run it by itself. What is LastLogonTime containing? Also, make sure LastLoginTimestamp is returning a DateTime, and not some goofy-formatted value (see http://blog.mattvogt.net/2011/10/06/pow … single-ho/ - the attribute isn’t a DateTime by default; you have to convert it to one if you’re going to compare it).

The key here is to look at what those properties contain. Right now, you’re probably comparing apples to oranges in your Where criteria.
by ps_gregg at 2013-04-20 08:55:24
The Get-QADUser cmdlet and the Get-MailboxStatistics cmdlet produce different objects, so I think you will need to run these as two separate commands and combine the outputs. You can try something like this:

$accounts = @()

$accounts += Get-QadUser -LdapFilter "((objectCategory=person)(sn=*))" -SearchRoot $ou -SizeLimit $sizeLimit | Where-Object { $
.LastLogontimestamp -ne $null -and $.LastLogontimestamp -le $date }

# Get-MailboxStatistics cmdlet takes either -Server or -Identity, not both
$accounts += Get-MailboxStatistics -server $server | Where-Object { $
.LastLogonTime -le $date } | Get-Mailbox | ForEach-Object {Get-QADUser $_.samaccountname}

Also, what Don said about LastLogontimestamp goofy-formatted dates is true for the Get-ADUser cmdlet, but I think the Get-QADUser cmdlet returns a proper datetime value. At least it always has in my experience…