Re: How to make this apply to all users?



Thank you so much Richard - This does the trick perfectly!

Now if I could only sort the username output alphabetically so I don't
have to keep pulling it into Excel....
You've been a great help . Thanks!
Craig

Richard Mueller wrote:
I also replied in newsgroup microsoft.public.adsi.general. I'll reply here
with a "brute force" solution. This will be much slower because it requires
binding to all user objects. Still, it demonstrates how to use a recursive
subroutine to enumerate the contents of all containers/OU's in the domain.

Instead of binding to a user object, the oUsr reference, you can all a
recursive subroutine to enumerate all users in all containers/OU's in the
domain. The meat of your program is the steps to retrieve the pwdLastSet
value, convert to a date, and output. This could all be placed in a
subroutine, which would be called once for each user. I called this Sub
GetPwdInfo. The code follows, but a few points.

1. This example does not account for the bug in the IADsLargeInteger
interface for Integer8 (64-bit) numbers, but that can safely be ignored
because the resulting error is only 7 minutes, 10 seconds.
2. The code outputs several lines per user. It would make more sense to
revise to output one line per user, perhaps with fields separated by commas
so you can import into a spread***. No need to output the text.
3. I've left most of your code alone.
4. Watch for possible line wrapping.
============================
const ONE_HUNDRED_NANOSECONDS = .0000001
const SECONDS_PER_DAY = 86400

function ConvertLargeIntegerToDays( oLI )
dim dblLI ' Large Integer converted to a double
dim dblNanoSec ' Nanoseconds for the password policy
dim dblDays ' Days for the password policy
'
' Convert the inteface into a double, there are some interesting things
' that happen with the sign bit. It is not important, just
' need the abosolute value of the conversion.
'
dblLI = ABS(oli.HighPart * 2^32 + oLI.LowPart)
dblNanosec = dblLI * ONE_HUNDRED_NANOSECONDS
dblDays = dblNanosec / 86400
'
' Return only the days....strip the decimal portion
'
ConvertLargeIntegerToDays = int(dblDays)
end function
'
' Retrieve the domain policy for max password age.
' If the value is not returned from the AD ( Property Not
' found in cache error) then the domain does not have
' a policy set, and passwords will never expire.
'
dim oRootDSE: Set oRootDSE = GetObject("LDAP://RootDSE";)
dim oDom : set oDom = Getobject("LDAP://"; &
oRootDSE.Get("defaultNamingContext"))
dim oMaxPwdAge : set oMaxPwdAge = oDom.Get("maxPwdAge")
MaxPwdAgeInDays = ConvertLargeIntegerToDays( oMaxPwdAge )

' Enumerate all users in the domain.
Call GetUsers(oDom)

Sub GetUsers(oContainer)
' Recursive subroutine to retrieve all users in domain.

' Filter on objects of class user.
oContainer.Filter = Array("user")

' Enumerate users and call Sub to get Passsword info.
For Each oUsr In oContainer
Call GetPwdInfo(oUsr)
Next

' Now filter on child containers and OU's.
oContainer.Filter = Array("container", "organizationalUnit")

' Enumerate child containers and OU's and recursively call this Sub.
For Each oChild In oContainer
Call GetUsers(oChild)
Next
End Sub

Sub GetPwdInfo (oUsr)
'
' and convert the pwdLastSet value into days since January 1 1601...
'
dim oPwdDate : set oPwdDate = oUsr.Get("pwdLastSet")
dim dDate
DaysPwdLastSet = ConvertLargeIntegerToDays ( oPwdDate )
'
' Since the FILETIME and the IADsLargeInteger values map to the same base
' date, we can set a variant to the base date and work with the days
' value from the PwdLastSet attribute...
'
dim BaseDate : BaseDate = CDate("January 1, 1601") ' from a FILETIME
structure definition
'
' Calculate the Password last set date...
'
PwdSetDate = BaseDate + DaysPwdLastSet
'
' Calculate the password expiration date...
'
ExpDate = PwdSetDate + MaxPwdAgeInDays
'
'Display some information about this users password expiration.
'
WScript.Echo "User: " & oUsr.Get("SamAccountName")
WScript.Echo "Day Password was last set: " & PwdSetDate
WScript.Echo "Password Expiration Date: " & ExpDate
DaysToExpPwd = int(ExpDate - now())
WScript.Echo "Days until the password expires: " & DaysToExpPwd

End Sub

--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net

"BLACKCRACK" <craigstern@xxxxxxxxx> wrote in message
news:1151089524.535422.5290@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
came across a code snip which is of particular interest to me because
it permits me to do 'almost' what I need to accomplish, yet I am very
new at coding and I have made several attempts to modify this script to

no avail... I was hoping someone out there with a a better grasp on
this might be able to assist me?

The script below takes the user defined in the LDAP query and provides
details about the user's password in accordance with the defined domain

policy. What I am particularily interested in doing is changing the
script to provide details about ALL domain users rather than just one
and I am just stumped to to do this?


-----
Here is the script
Thanks for everyones help!
Craig
-----


const ONE_HUNDRED_NANOSECONDS = .0000001
const SECONDS_PER_DAY = 86400


function ConvertLargeIntegerToDays( oLI )
dim dblLI ' Large Integer converted to a double
dim dblNanoSec ' Nanoseconds for the password policy
dim dblDays ' Days for the password policy
'
' Convert the inteface into a double, there are some interesting
things
' that happen with the sign bit. It is not important, just
' need the abosolute value of the conversion.
'
dblLI = ABS(oli.HighPart * 2^32 + oLI.LowPart)
dblNanosec = dblLI * ONE_HUNDRED_NANOSECONDS
dblDays = dblNanosec / 86400
'
' Return only the days....strip the decimal portion
'
ConvertLargeIntegerToDays = int(dblDays)
end function
'
' Retrieve the domain policy for max password age.
' If the value is not returned from the AD ( Property Not
' found in cache error) then the domain does not have
' a policy set, and passwords will never expire.
'
dim oRootDSE: Set oRootDSE = GetObject("LDAP://RootDSE";)
dim oDom : set oDom = Getobject("LDAP://"; &
oRootDSE.Get("defaultNamingContext"))
dim oMaxPwdAge : set oMaxPwdAge = oDom.Get("maxPwdAge")
MaxPwdAgeInDays = ConvertLargeIntegerToDays( oMaxPwdAge )
'
' Get a user object
' and convert the pwdLastSet value into days since January 1 1601...
'
Dim oUsr : set oUsr = GetObject("LDAP://cn=John
Doe,OU=Users,dc=larson,dc=com")
dim oPwdDate : set oPwdDate = oUsr.Get("pwdLastSet")
dim dDate
DaysPwdLastSet = ConvertLargeIntegerToDays ( oPwdDate )
'
' Since the FILETIME and the IADsLargeInteger values map to the same
base
' date, we can set a variant to the base date and work with the days
' value from the PwdLastSet attribute...
'
dim BaseDate : BaseDate = CDate("January 1, 1601") ' from a FILETIME
structure definition
'
' Calculate the Password last set date...
'
PwdSetDate = BaseDate + DaysPwdLastSet
'
' Calculate the password expiration date...
'
ExpDate = PwdSetDate + MaxPwdAgeInDays
'
'Display some information about this users password expiration.
'
WScript.Echo "User: " & oUsr.Get("SamAccountName")
WScript.Echo "Day Password was last set: " & PwdSetDate
WScript.Echo "Password Expiration Date: " & ExpDate
DaysToExpPwd = int(ExpDate - now())
WScript.Echo "Days until the password expires: " & DaysToExpPwd


.