Author Posts

January 27, 2016 at 7:09 am

This statement does not give me any results in my variable. Any ideas what I am doing wrong?

$Exp = Get-ADUser -LDAPfilter {sAMAccountName -eq $Name} -Properties * | Select -ExpandProperty PasswordExpired

January 27, 2016 at 7:12 am

Try ditching the pipe to Select-Object, and see what you get. (Check to see the result when you run $Exp.PasswordExpired ,after making that change ).

January 27, 2016 at 7:17 am

Changed to Select-Object and still no results in my $Exp variable after the statement completes. I am not receiving any errors either. Thanks!

$Exp = Get-ADUser -LDAPfilter {sAMAccountName -eq $Name} -Properties * | Select-Object -ExpandProperty PasswordExpired

January 27, 2016 at 7:20 am

That's not what I meant. 🙂 I just meant to get rid of the call to Select-Object entirely, to make sure you're getting something back from Get-ADUser. (If there are no objects that match your filter, for example, then you'd get nothing.)

$Exp = Get-ADUser -LDAPfilter {sAMAccountName -eq $Name} -Properties *

$Exp.PasswordExpired

January 27, 2016 at 7:26 am

The problem is that the LDAP filter you're using isn't an LDAP filter

To use an LDAP filter
Get-ADUser -LDAPFilter "(Name=Richard)"

To use a filter
Get-ADUser -Filter {Name -eq 'Richard'}

You're using the Filter (PowerShell) syntax with LDAPfilter instead of the LDAP search syntax

January 27, 2016 at 7:31 am

Removed the script that didn't work. Reposting what worked at the end of the conversation.

January 27, 2016 at 7:51 am

I changed the code to:

$Exp = Get-ADUser -Filter {sAMAccountName -eq $Name} -Properties *
$Exp.PasswordExpired

-OR-

$Exp = Get-ADUser -LDAPfilter "(sAMAccountName=$Name)" -Properties *
$Exp.PasswordExpired

I still do not get any results in my variable but it shows $Exp as being the Distinguished Name? Something is screwy! The $Name is populated just fine.

January 27, 2016 at 9:27 am

well, i'm not sure why your using the filter, you can do a straight get-aduser $name -properties passwordexpired

then $exp.passwordexpired does contain the value

January 27, 2016 at 11:13 am

If all you want is accounts with expired passwords look at using search-ADAccount

to search whole domain
Search-ADAccount -PasswordExpired

to search an OU
Search-ADAccount -PasswordExpired -SearchBase 'OU=Testing,DC=Manticore,DC=org'

January 27, 2016 at 1:23 pm

OK, here is what worked finally:

$attributes = 'Name','PasswordExpired'
$Test = Get-ADUser -Filter "sAMAccountName -eq '$SaName'" -SearchBase "$OU"`
-SearchScope Subtree -Properties $attributes | Select $attributes

Thanks everyone for your help!

January 29, 2016 at 11:57 am

Here is my finished script. This is my first script so I am sure there are lots of improvements to be made!:

##########################################################################
#——————————————————————————————#
# Prompt for OU Selection for Report
#——————————————————————————————#

$caption = "Please select OU to query"
$message = "Select OU to query"

$choices = [System.Management.Automation.Host.ChoiceDescription[]] `
@("&Moscow", "&SST", "&SST-Mgmt")

[int]$defaultChoice = 0

$choiceRTN = $host.ui.PromptForChoice($caption,$message, $choices,$defaultChoice)

switch($choiceRTN)
{
0 {
$OU = "OU=ou name,DC=ad,DC=somewhere,DC=org"
$LD = "LDAP://OU=ou name,DC=ad,DC=somewhere,DC=org"
$ShortOU = "A-OU"
break
}
1 {
$OU = "OU=ou name,DC=ad,DC=somewhere,DC=org"
$LD = "LDAP://OU=ou name,DC=ad,DC=somewhere,DC=org"
$ShortOU = "B-OU"
break
}
2 {
$OU = "OU=ou name,DC=ad,DC=somewhere,DC=org"
$LD = "LDAP://ou name,DC=ad,DC=somewhere,DC=org"
$ShortOU = "C-OU"
break
}
}

#——————————————————————————————#
# Specify number of days. Any users whose passwords expire within
# this many days after today will be processed.
#——————————————————————————————#
$intDays = 90

#——————————————————————————————#
# Retrieve Domain maximum password age policy, in days.
#——————————————————————————————#

$D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Domain = [ADSI]"LDAP://$D"
$MPA = $Domain.maxPwdAge.Value

#——————————————————————————————#
# Convert to Int64 ticks (100-nanosecond intervals).
#——————————————————————————————#
$lngMaxPwdAge = $Domain.ConvertLargeIntegerToInt64($MPA)

#——————————————————————————————#
# Convert to days.
#——————————————————————————————#
$MaxPwdAge = -$lngMaxPwdAge/(600000000 * 1440)

#——————————————————————————————#
# Determine the password last changed date such that the password
# would just now be expired. We will not process any users whose
# password has already expired.
#——————————————————————————————#

$Now = Get-Date
$Date1 = $Now.AddDays(-$MaxPwdAge)

#——————————————————————————————#
# Determine the password last changed date such the password
# will expire $intDays in the future.
#——————————————————————————————#

$Date2 = $Now.AddDays($intDays – $MaxPwdAge)

#——————————————————————————————#
# Convert from PowerShell ticks to Active Directory ticks.
#——————————————————————————————#

$64Bit1 = $Date1.Ticks – 504911232000000000
$64Bit2 = $Date2.Ticks – 504911232000000000

$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 100
$Searcher.SearchScope = "subtree"

#——————————————————————————————#
# Filter on user objects where:
# ~the password expires between the dates specified
# ~the account is not disabled
# ~password never expires is not set
# ~password not required is not set
# ~password cannot change is not set.
#——————————————————————————————#

$Searcher.Filter = "(&(objectCategory=person)(objectClass=user)" `
+ "(pwdLastSet>=" + $($64Bit1) + ")" `
+ "(pwdLastSet $Null
$Searcher.PropertiesToLoad.Add("distinguishedName") > $Null
$Searcher.PropertiesToLoad.Add("pwdLastSet") > $Null

#——————————————————————————————#
# Only search the specified OU.
#——————————————————————————————#

$Searcher.SearchRoot = "$LD"

$Results = $Searcher.FindAll()

#——————————————————————————————#
# Build Report
#——————————————————————————————#
ForEach ($Result In $Results)
{
Try
{
#——————————————————————————————#
# Clear variables at top of loop
#——————————————————————————————#

$Test =$Check = $Status = $Name = $Null

#——————————————————————————————#
# Retrieve attribute values for this user
#——————————————————————————————#

$SaName = $Result.Properties.Item("sAMAccountName")
$DN = $Result.Properties.Item("distinguishedName")
$PLS = $Result.Properties.Item("pwdLastSet")

#——————————————————————————————#
# Retrieve PasswordExpired Calculated Value
#——————————————————————————————#

$attributes = 'Name','PasswordExpired'
$Test = Get-ADUser -Filter "sAMAccountName -eq '$SaName'" -SearchBase "$OU"`
-SearchScope Subtree -Properties $attributes | Select $attributes
$Check = $Test.PasswordExpired.ToString()
$Name = $Test.Name.ToString()

If ($PLS.Count -eq 0)
{
$Date = [DateTime]0
}

Else
{

#——————————————————————————————#
# Interpret 64-bit integer as a date.
#——————————————————————————————#

$Date = [DateTime]$PLS.Item(0)

}
#——————————————————————————————#
# If User Password is Expired show "Expired" for this user's status else "OK"
#——————————————————————————————#
Switch ($Check)
{
"false" {$Status = "OK" ; break}
"true" {$Status = "Expired!" ; break}
}

#——————————————————————————————#
# Convert from .NET ticks to Active Directory Integer8 ticks.
# Also, convert from UTC to local time.
#——————————————————————————————#

$PwdLastSet = $Date.AddYears(1600).ToLocalTime()

#——————————————————————————————#
# Determine when password expires.
#——————————————————————————————#

$PwdExpires = $PwdLastSet.AddDays($MaxPwdAge)

#——————————————————————————————#
# Output Report in CSV Format
#——————————————————————————————#

New-Object -TypeName PSCustomObject -Property @{

PasswordExpDate = $PwdExpires
PwdStatus = "$Status"
Name = "$Name"
sAMAccountName = "$SaName"
DN = "$DN"

} | Export-Csv -Path C:\TestFiles\"$ShortOU"_UserPasswordStatus_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation -Append
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$ErrorActionPreference = "Inquire"
}
Finally
{

}

}
If ($Results -ne $Null)
{
#——————————————————————————————#
# Notify user that Report has completed processing
#——————————————————————————————#
$Pop = new-object -comobject wscript.shell
$Box = $Pop.popup("The report finished successfully!",30,"Status",1)
}
Else
{
#——————————————————————————————#
# Notify user that Report was not created
#——————————————————————————————#
$Pop = new-object -comobject wscript.shell
$Box = $Pop.popup("**No Accounts were identified. No report was generated.**",30,"Status",1)
}