﻿Import - Module activedirectory

$startime = Get-Date -Format HH:mm

$output = "thing.csv"

#days in hours because idk how powershell time work.

$20days = ( Get-Date ) .addhours ( - 480 ) .ToString ( )

$21_0days = ( Get-Date ) .addhours ( - 504 ) .ToString ( )

$21_9days = ( Get-Date ) .addhours ( - 527 ) .ToString ( )

$34_0days = ( get-date ) .addhours ( - 816 ) .tostring ( )

$34_9days = ( get-date ) .addhours ( - 839 ) .tostring ( )

$35_0days = ( get-date ) .addhours ( - 840 ) .tostring ( )

$90days = ( get-date ) .addhours ( - 2160 ) .tostring ( )

$forever = ( get-date ) .addhours ( - 131400 ) .tostring ( )

#get dc names based on name mask

$dc = get - addomaincontroller - filter { name -like "DC*" } | select name

#data set of all users from all DCs

$dataset = foreach ( $d in $dc ) {

Write-host "checking" $d .name

#get user list per DC so we can sort logon times later

$users = get - aduser - server $d .name - filter { name -like "*" } - Properties emailaddress , lastlogondate , whencreated | select name , samaccountname , emailaddress , lastlogondate , sid , DistinguishedName , enabled , whencreated

foreach ( $u in $users ) {

#build custom object for each user based on log on time, if its blank use the date created instead.

if ( $u .lastlogondate -eq $null -or $u .lastlogondate -eq "" ) {

[ pscustomobject ] @ {

Name = $u .name

SAM = $u .samaccountname

Email = $u .emailaddress

LLOD = $u .whencreated

SID = $u .sid

DN = $u .DistinguishedName

Enabled = $u .enabled

DC = $d .name

logononce = "NO"

}

} else {

[ pscustomobject ] @ {

Name = $u .name

SAM = $u .samaccountname

Email = $u .emailaddress

LLOD = $u .lastlogondate

SID = $u .sid

DN = $u .DistinguishedName

Enabled = $u .enabled

DC = $d .name

logononce = "YES"

}

}

}

}

#group by the user name, sort the group by the date and select the last date in that group.

#this hopfully gets one user per user set of x DCs and gets the newest time. But does it? hell if i know....

$all = $dataset | ForEach-Object { $_ .LLOD = [ datetime ] $_ .LLOD; $_ } | Group-Object name | ForEach-Object { $_ . group | Sort-Object LLOD | Select-Object -Last 1 }

#pre-filter service accounts because i dont think the exemption list comparison works.

$allad = $all | where { $_ .name -notlike "*.svc" }

#build seperate arrays based on time ranges. becuase i cant think of a better way and im scared.

$21dayaccounts = $allad | where { ( $_ .llod -le $21_0days -and $_ .llod -ge $21_9days ) }

$34dayaccounts = $allad | where { ( $_ .llod -le $34_0days -and $_ .llod -ge $34_9days ) }

$35dayaccounts = $allad | where { ( $_ .enabled -eq $true -and ( $_ .llod -le $35_0days -and $_ .llod -ge $90days ) ) }

$90dayaccounts = $allad | where { ( $_ .enabled -eq $false -and ( $_ .llod -le $90days -and $_ .llod -ge $forever ) ) }

#foreach user found in the group, grab the attribs you want and build a custom object to compare against the main AD grab. Do i need to do this?

$exempt_list1 = foreach ( $x in ( get - adgroupmember - Identity "Disable_Exempt" ) ) {

$service = get - aduser $x .samaccountname -erroraction SilentlyContinue - properties emailaddress , lastlogondate , whencreated | select name , samaccountname , emailaddress , lastlogondate , sid , DistinguishedName , enabled , whencreated

foreach ( $s in $service ) {

if ( $s .lastlogondate -eq $null -or $s .lastlogondate -eq "" ) {

[ pscustomobject ] @ {

Name = $s .name

SAM = $s .samaccountname

Email = $s .emailaddress

LLOD = $s .whencreated

SID = $s .sid

DN = $s .DistinguishedName

Enabled = $s .enabled

DC = "SERVICE"

logononce = "NO"

}

} else {

[ pscustomobject ] @ {

Name = $u .name

SAM = $u .samaccountname

Email = $u .emailaddress

LLOD = $u .lastlogondate

SID = $u .sid

DN = $u .DistinguishedName

Enabled = $u .enabled

DC = "SERVICE"

logononce = "YES"

}

}

}

}

$exempt_list2 = foreach ( $y in ( ( get - adgroupmember - Identity "Exempt_Delete" ) ) .samaccountname ) {

$sas = get - aduser $y -erroraction SilentlyContinue - properties emailaddress , lastlogondate , whencreated | select name , samaccountname , emailaddress , lastlogondate , sid , DistinguishedName , enabled , whencreated

foreach ( $a in $sas ) {

if ( $a .lastlogondate -eq $null -or $a .lastlogondate -eq "" ) {

[ pscustomobject ] @ {

Name = $a .name

SAM = $a .samaccountname

Email = $a .emailaddress

LLOD = $a .whencreated

SID = $a .sid

DN = $a .DistinguishedName

Enabled = $a .enabled

DC = "SAS"

logononce = "NO"

}

} else {

[ pscustomobject ] @ {

Name = $a .name

SAM = $a .samaccountname

Email = $a .emailaddress

LLOD = $a .lastlogondate

SID = $a .sid

DN = $a .DistinguishedName

Enabled = $a .enabled

DC = "SAS"

logononce = "YES"

}

}

}

}

#1 is exempt from disables 1 + 2 is exempt from deletes

$exempt_list3 = $exempt_list1 + $exempt_list2

#compares should add only those found in the left set in the the new array, but sometimes exempt accounts slip through. why?

$nonexempt35 = compare-object $35dayaccounts $exempt_list1 -property sam -PassThru | where { $_ .sideindicator -eq '<=' } | select name , sam , email , llod , sid , DN , enabled , DC , logononce

$nonexempt90 = compare-object $90dayaccounts $exempt_list3 -property sam -PassThru | where { $_ .sideindicator -eq '<=' } | select name , sam , email , llod , sid , DN , enabled , DC , logononce

#all function build a custom object and appends the data to an array. holy shit guy you like custom objects or something?

#email users 2 weeks before disable

function 2weekwarning {

foreach ( $s in $21dayaccounts ) {

[ pscustomobject ] @ {

Name = $s .sam

LLOD = $s .llod

DN = $s .Dn

logononce = $s .logononce

DC = $s .dc

State = "2 week warning"

}

<#

Send-MailMessage -To "$s.email" `

-From "a guy" `

-Subject "Your Account Will Expire In 14 Days" `

-Body "Your Account Will Expire In 14 Days, Please log in or it will be disabled." `

-SmtpServer thing

#>

}

}

#email user 1 day before disable

function 1day {

foreach ( $p in $34dayaccounts ) {

[ pscustomobject ] @ {

Name = $p .sam

LLOD = $p .llod

DN = $p .Dn

logononce = $p .logononce

DC = $p .dc

State = "1 day warning"

}

<#

Send-MailMessage -To "$p.email" `

-From "a guy" `

-Subject "Your Account Will Expire In 1 Day" `

-Body "Your Account Will Expire In 1 Day, Please log in or it will be disabled." `

-SmtpServer thing

#>

}

}

#disable all users not in exemptlist after 35 days and send an email

function disable {

[ string ] $rootOU = 'OU=ADStaleAccounts'

foreach ( $r in $nonexempt35 ) {

[ pscustomobject ] @ {

Name = $r .sam

LLOD = $r .llod

DN = $r .Dn

logononce = $r .logononce

DC = $r .dc

State = "Disabled"

}

}

<#

#move to stale, disable, add info to the notes

Get-ADUser $r.sid | Move-ADObject -TargetPath $rootOU

Disable-ADAccount -Identity $r.sid

Set-ADUser $r.sid -replace @{info="Disabled $(Get-Date) per Inactive Account Policy. user must be validated before reactivation."}

Send-MailMessage -To "$r.email" `

-From "a guy" `

-Subject "YOUR ACCOUNT HAS EXPIRED"

-Body "Your account has been disabled and is in danger of being DELETED, Please put in a ticket with the Help Desk to have it enabled." `

-SmtpServer thing

#>

}

#delete user not in exempt list that is 90+

function delete {

foreach ( $z in $nonexempt90 ) {

[ pscustomobject ] @ {

Name = $z .sam

LLOD = $z .llod

DN = $z .Dn

logononce = $z .logononce

DC = $z .dc

State = "Deleted"

}

}

<#

Send-MailMessage -To "$z.email" `

-From "a guy" `

-Subject "YOUR ACCOUNT HAS BEEN DELETED"

-Body "Your Account has been deleted. Please put in a ticket to have it created again." `

-SmtpServer thing

#>

#remove user from AD -confirm:$false so this can be ran as a scheduled task and wont prompt for every delete.

#Remove-ADUser -identity $z.sid -confirm:$false

}

$final = @ ( )

$final += 2weekwarning

$final += 1day

$final += disable

$final += delete

$final | select name , LLOD , DN , state , dc , logononce | Export-Csv -NoTypeInformation $output

$endtime = Get-Date -Format HH:mm

$recipients = #emails

Send - MailMessage - To $recipients `

- From "a guy" `

- Subject "Script Ended: Disabled/Deleted User Report" `

-Body "Run complete.

Start: $startime

End: $endtime" `

- SmtpServer thing `