powershell to get Active directory account expire in 10 days

cawasaki
cawasaki used Ask the Experts™
on
Hi,

I need to query the entire domain find any user with accountExpires in 10 days (compare with actual date), then send an email to the users and his manager.

1-if the users have not an email address, log this user name and account expire date in a csv or txt file.

2-if users not have a manager, just send email to the user.

i have quest powershell tools installed, sow the script can user quest commandlet.


thanks for help
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Checked this out. I think this is what you are looking for.
Can modify as per your need.

http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/a9d086cc-c706-4666-80d6-25795ba21873

Author

Commented:
yes, its what i need but i need to add manager in the email and log the result of script.
i am sure its is possible to get the script in 5-10

Commented:
# PSAcctExpires.ps1

Trap {"Error: $_"; Break;}

# Specify number of days. Users whose accounts expire between now and
# this many days in the future will be processed.
$Days = 10

# Email settings.
$Script:From = "myemailaddress@mydomain.com"
$Script:Cc = "<ENTER YOUR MANAGERs EMAIL ADDRESS>"
$Script:Subject = "Account Expiration Notice"
$Server = "smtp.mydomain.com"
$Port = 25
$Client = New-Object System.Net.Mail.SmtpClient $Server, $Port
# You may need to provide credentials.
$Client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

Function SendEmail($To, $Body)
{
    $Message = New-Object System.Net.Mail.MailMessage `
        $Script:From, $To, $Script:Cc, $Script:Subject, $Body
    $Client.Send($Message)
}

modify the above part of script in article as shown by bold and change <ENTER YOUR MANAGERs EMAIL ADDRESS> to your manager's email address.
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
hi,

its not good because manager is an AD attribute and the script must get it automaticly
Software Systems Specialist 3
Commented:
Here's a script that I just put together. It uses the Quest Active Roles PoSh cmdlets downloadable via the link below. It also uses the POSH 2.0 cmd "Send-MailMessage" to send the SMTP email. I have not tested it as I don't want to send this mail to my clients.

#Number of days from now that you want to start notifying clients.
$datediff = -10

$reportPath = "c:\AccounsExpiring.csv"
$DatePast = (get-date).AddDays($dateDiff)

#Email properties:
$FromAddress = "Admin@example.com" 
$SMTPServer = "SMTPRelay.Example.COM"

#Script relies on Quest Active Roles Powershell cmdlets. (download: http://bit.ly/1EAVF0)

$Expiring = Get-QADUser -AccountExpiresAfter $datePast -AccountExpiresBefore (Get-Date) -sizelimit 0
foreach ($Acct in $expiring) {
	if ($acct.mail -ne $null) {
		$expiration = $acct.accountexpires.tostring()
		$recipients = @($acct.mail)
		if ($acct.Manager -ne $null) {
			$recipients += (Get-QADUser $acct.Manager).mail
		}
		$msgBody = "Your Account ("+$Acct.Name+") expires on "+$expiration
		Send-MailMessage -Subject "Account Expiring"+$expiration -To $recipients -From $FromAddress -SmtpServer $SMTPServer -Body $msgBody
	} else {
		#Assumes file path is valid and file exits.
		$acct.Name +","+$expiration | Out-File -FilePath $reportPath -Append 
	}
}

Open in new window

Author

Commented:
hi ericwoodford

thanks for this script, i will test it and report the result.

thanks

Author

Commented:
hi,

this command:

Get-QADUser -AccountExpiresAfter $datePast -AccountExpiresBefore (Get-Date) -sizelimit 0

get me expired account 10 days before todays.

can you correct this plz?

Author

Commented:
and mail message work but not log file was created.

Author

Commented:
hi,

have change this $datediff = -10 to $datediff = 10 to get the good expireddate account.

and change

Get-QADUser -AccountExpiresAfter $datePast -AccountExpiresBefore (Get-Date) -sizelimit 0

to

Get-QADUser -AccountExpiresAfter $datePast -AccountExpiresBefore (Get-Date) -sizelimit 0

Now i have 2 problem to resolve:

1-if user not have email address, the email is not sent to his manager==> can you help me in this point plz?

2-never log anithing in csv file (csv file not created)==> can you help me in this point plz?

3-if user not have email adress and manager value is empty, just log this account in csv file.

thanks

Author

Commented:
any help here plz?
Eric WoodfordSoftware Systems Specialist 3

Commented:
1. We need to add a little code.

I've modified the entire For{} loop (lines 14-27 above)

foreach ($Acct in $expiring) {
        #If Manager field populated on acct, determine if manager has valid email.
        if ($acct.manager -ne $null) {
            $mgr = get-qaduser $acct.manager -erroraction silentlycontinue
            $mgrEmailValid = ($mgr.mail -ne $null)
        } else { 
             #No valid manager defined.
             $mgrEmailValid = $false
       }
	
	if ($acct.mail -ne $null) {
		#If Account has valid email address.
		$expiration = $acct.accountexpires.tostring()
		$recipients = @($acct.mail)
		if ($mgrEmailValid) {
			#Add Manager to recipients.
			$recipients += (Get-QADUser $acct.Manager).mail
		}
		$msgBody = "Your Account ("+$Acct.Name+") expires on "+$expiration
		Send-MailMessage -Subject "Account Expiring"+$expiration -To $recipients -From $FromAddress -SmtpServer $SMTPServer -Body $msgBody
	} elseif ($acct.mail -eq $null -and $mgrEmailValid) {
		#If Acct doesn't have valid email, but manager does.
		$expiration = $acct.accountexpires.tostring()		
		$recipients = (Get-QADUser $acct.Manager).mail		
		$msgBody = "The Account ("+$Acct.Name+") expires on "+$expiration
		Send-MailMessage -Subject "Account Expiring"+$expiration -To $recipients -From $FromAddress -SmtpServer $SMTPServer -Body $msgBody	
	else {
		#Assumes file path is valid and file exits.
		$acct.Name +","+$expiration | Out-File -FilePath $reportPath -Append 
	}
}

Open in new window


2. I am guessing the CSV may not already exist? Since it 'appends' to an existing, it is failing. Put this after the $ReportPath = " " statement.

$ReportPath = "c:\AccountsExpiring.csv"
if (-not (Test-Path $reportPath)) {
	"Account, ExpirationDate"  | Out-File -FilePath $reportPath
}

Open in new window

Commented:
Hello I found this script for Richard Mueller from your links :

But can explain the script for exactly what doing ? and how i can run it?

and where i should put the password for the client email which will send the email for the user and how the email will be ?? and does it will same a CSV file or no ?

Regards,

# PSAcctExpires.ps1

Trap {"Error: $_"; Break;}

# Specify number of days. Users whose accounts expire between now and
# this many days in the future will be processed.
$Days = 7

# Email settings.
$Script:From = "myemailaddress@mydomain.com"
$Script:Subject = "Account Expiration Notice"
$Server = "smtp.mydomain.com"
$Port = 25
$Client = New-Object System.Net.Mail.SmtpClient $Server, $Port
# You may need to provide credentials.
$Client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

Function SendEmail($To, $Body)
{
    $Message = New-Object System.Net.Mail.MailMessage `
        $Script:From, $To, $Script:Subject, $Body
    $Client.Send($Message)
}

# Determine dates.
$Date1 = Get-Date
$Date2 = $Date1.AddDays($Days)

# Convert from PowerShell ticks to Active Directory ticks.
$64Bit1 = $Date1.Ticks - 504911232000000000
$64Bit2 = $Date2.Ticks - 504911232000000000

$D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Domain = [ADSI]"LDAP://$D"
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 200
$Searcher.SearchScope = "subtree"

$Searcher.Filter = "(&(objectCategory=person)(objectClass=user)" `
    + "(accountExpires>=" + $($64Bit1) + ")" `
    + "(accountExpires<=" + $($64Bit2) + "))"
$Searcher.PropertiesToLoad.Add("distinguishedName") > $Null
$Searcher.PropertiesToLoad.Add("sAMAccountName") > $Null
$Searcher.PropertiesToLoad.Add("mail") > $Null
$Searcher.PropertiesToLoad.Add("proxyAddresses") > $Null
$Searcher.PropertiesToLoad.Add("accountExpires") > $Null
$Searcher.SearchRoot = "LDAP://" + $Domain.distinguishedName

$Results = $Searcher.FindAll()
ForEach ($Result In $Results)
{
    $DN = $Result.Properties.Item("distinguishedName")
    $Name = $Result.Properties.Item("sAMAccountName")
    $Mail = $Result.Properties.Item("mail")
    $Addresses = $Result.Properties.Item("proxyAddresses")
    $AE = $Result.Properties.Item("accountExpires")
    If (($AE.Item(0) -eq 0) -or ($AE.Item(0) -gt [DateTime]::MaxValue.Ticks))
    {
        $AcctExpires = "<Never>"
    }
    Else
    {
        $Date = [DateTime]$AE.Item(0)
        $AcctExpires = $Date.AddYears(1600).ToLocalTime()
    }
    # Determine email address.
    If ("$Mail" -eq "")
    {
        ForEach ($Address In $Addresses)
        {
            $Prefix = $Address.SubString(0, 5)
            If (($Prefix -ceq "SMTP:") -or ($Prefix -ceq "X400:"))
            {
                $Mail = $Address.SubString(5)
                Break
            }
        }
    }
    If ("$Mail" -ne "")
    {
        $Notice = "Account for user $Name on $AcctExpires"
        SendEmail $Mail $Notice
        "Email sent to $Name ($Mail), account expires $AcctExpires"
    }
    Else
    {
        "$Name has no email, but account expires $AcctExpires"
        "DN: $DN"
    }
}

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial