Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > VB Script

Vista - List email addresses

Reply
 
Old 08-01-2008   #1 (permalink)
richard


 
 

List email addresses

Could anyone show me how to do this? I can't seem to find any example
code via Google.
I want to list all users in a domain, and show their email address as
displayed in the 'Active Directory Users and Computers' User
properties dialog on the General tab.

The oDomainItem.Name seems to work ok, but not the EmailAddress.
I'm also wondering if I could get each users MailboxGUID property.
/************/

on error resume next

Set oDomain = GetObject("WinNT://hillsyde.local")
oDomain.Filter = Array("User")

For Each oDomainItem In oDomain
wscript.echo oDomainItem.Name & ";" & oDomainItem.EmailAddress
Next

/****************/

Regards,
Richard

My System SpecsSystem Spec
Old 08-01-2008   #2 (permalink)
Richard Mueller [MVP]


 
 

Re: List email addresses

Richard wrote:
Quote:

> Could anyone show me how to do this? I can't seem to find any example
> code via Google.
> I want to list all users in a domain, and show their email address as
> displayed in the 'Active Directory Users and Computers' User
> properties dialog on the General tab.
>
> The oDomainItem.Name seems to work ok, but not the EmailAddress.
> I'm also wondering if I could get each users MailboxGUID property.
> /************/
>
> on error resume next
>
> Set oDomain = GetObject("WinNT://hillsyde.local")
> oDomain.Filter = Array("User")
>
> For Each oDomainItem In oDomain
> wscript.echo oDomainItem.Name & ";" & oDomainItem.EmailAddress
> Next
>
> /****************/
First, the binding string with the WinNT provider is most likely:

Set oDomain = GetObject("WinNT://hillsyde")

But it doesn't matter because the WinNT provider does not expose the mail or
proxyAddresses attributes of user objects. You need to bind with the LDAP
provider, using the Distinguished Name of the domain. If the domain is
hillsyde.local, you can probably use:

Set oDomain = GetObject("LDAP://dc=hillsyde,dc=local")

Then, if the email address shows up on the "General" tab in ADUC (in the
field labeled "E-mail") you want the mail attribute of the users. If you use
Exchange then your email addresses are saved in the proxyAddresses
attribute, which is multi-valued.

Because of the hierarchy of AD you cannot bind to the domain and enumerate
all users, as you do using the WinNT provider. If all of your users are in
the cn=Users container, you can use similar code to enumerate all users in
that container. For example:
====
' Bind to the cn=Users container with the LDAP provider, using the
' Distinguished Name of the container.
Set objContainer = GetObject("LDAP://cn=users,dc=hillsyde,dc=local")

' Filter on user objects.
objContainer.Filter = Array("user")

' Enumerate all objects of class user.
For Each objUser In objContainer
' Document user NT name and email address
Wscript.Echo objUser.sAMAccountName & ";" & objUser.mail
Next
=========
You could use the "EmailAddress" property method instead of referring
directly to the "mail" attribute.

If your users are spread out in various OU's, you can use ADO in a VBScript
program to retrieve the values of the sAMAccountName and mail attributes of
all users. See this link for details:

http://www.rlmueller.net/ADOSearchTips.htm

You can use the first example code snippet in the link if you just
substitute "mail" for "cn". And, if have Exchange you must retrieve the
proxyAddresses attribute. This is multi-valued and ADO retrieves the value
as an array. Any user can have no values, one value, or more than one value
(email address). The link above shows how to handle this in a "For Each"
loop.

--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--


My System SpecsSystem Spec
Old 08-01-2008   #3 (permalink)
richard


 
 

Re: List email addresses

Thank you for such a detailed answer Richard. I'll have a read through
the page you mention and see if I can get things working.

Regards,
Richard
My System SpecsSystem Spec
Old 08-01-2008   #4 (permalink)
richard


 
 

Re: List email addresses

Richard,

Is is possible to get the lastLogon field using this method?
I've adapted the script from your site and can now get the mail, but not the lastLogon field which
I've seen used elsewhere. It always gives an error 'Object doesn't support this property or
method', even though I know that some of the users have certainly logged in.

The key bits of the script, as far as I know, are:

strAttributes = "sAMAccountName,cn,mail,lastLogon"
..
..
..

' Write the resulting recordset to file
Do Until adoRecordset.EOF
' Retrieve values and display.
strName = adoRecordset.Fields("sAMAccountName").Value
strCN = adoRecordset.Fields("cn").value
strMail= adoRecordset.Fields("mail").value

On error resume Next
strLastLogon= adoRecordset.Fields("lastLogon").value
if Err<>0 then
sLastLogonErrorMsg=replace(replace(Err.description,vbCr,""),vbLf,"")
else
sLastLogonErrorMsg="ok"
end if
Err.clear
On error goto 0

OutputLine = strName & ";" & strCN & ";" & strMail & ";" & strLastLogon & ";" &
sLastLogonErrorMsg
Wscript.Echo OutputLine
objOutputFile.WriteLine(OutputLine )
adoRecordset.MoveNext
Loop


As I mentioned, if I don't try to get the lastLogon, everything works.

Thanks for any help,
Richard
My System SpecsSystem Spec
Old 08-01-2008   #5 (permalink)
Richard Mueller [MVP]


 
 

Re: List email addresses

Richard wrote:
Quote:

> Is is possible to get the lastLogon field using this method?
> I've adapted the script from your site and can now get the mail, but not
> the lastLogon field which
> I've seen used elsewhere. It always gives an error 'Object doesn't
> support this property or
> method', even though I know that some of the users have certainly logged
> in.
>
> The key bits of the script, as far as I know, are:
>
> strAttributes = "sAMAccountName,cn,mail,lastLogon"
> .
> .
> .
>
> ' Write the resulting recordset to file
> Do Until adoRecordset.EOF
> ' Retrieve values and display.
> strName = adoRecordset.Fields("sAMAccountName").Value
> strCN = adoRecordset.Fields("cn").value
> strMail= adoRecordset.Fields("mail").value
>
> On error resume Next
> strLastLogon= adoRecordset.Fields("lastLogon").value
> if Err<>0 then
> sLastLogonErrorMsg=replace(replace(Err.description,vbCr,""),vbLf,"")
> else
> sLastLogonErrorMsg="ok"
> end if
> Err.clear
> On error goto 0
>
> OutputLine = strName & ";" & strCN & ";" & strMail & ";" & strLastLogon
> & ";" &
> sLastLogonErrorMsg
> Wscript.Echo OutputLine
> objOutputFile.WriteLine(OutputLine )
> adoRecordset.MoveNext
> Loop
>
>
> As I mentioned, if I don't try to get the lastLogon, everything works.
>
> Thanks for any help,
> Richard
The lastLogon attribute is Integer8, a large (64-bit) number representing a
date. It cannot be handled the way most string attributes are handled. In
fact, something called the IADsLargeInteger interface must be used, that
treats the value similar to an object and exposes HighPart and LowPart
methods that break the 64-bit value into two 32-bit values. This is
explained in detail at this link:

http://www.rlmueller.net/Integer8Attributes.htm

However, another complication is that lastLogon is not replicated. This
means that a different value is saved on every Domain Controller (DC). When
the user authenticates to a DC, the lastLogon attribute for that user is
updated on that DC, but the value is not replicated. To determine the true
lastLogon date/time you must query every DC in the domain. I have an example
VBScript program that retrieves the last logon dates for all users in the
domain by querying every DC linked here:

http://www.rlmueller.net/Last%20Logon.htm

As explained in the link, there is a new attribute called lastLogonTimeStamp
that is available if your domain is at Windows 2003 functional level. This
attribute is replicated, so you only need one query to get the value, but it
is only updated if the old value is at least 14 days (by default) in the
past. This is so you can find unused accounts. Replicating any value
everytime a user logged on would increase replication traffic unacceptably.

The code to retrieve lastLogonTimeStamp would be similar to (in part):
=============
' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngTZBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngTZBias = 0
For k = 0 To UBound(lngBiasKey)
lngTZBias = lngTZBias + (lngBiasKey(k) * 256^k)
Next
End If
' ...

strAttributes = "sAMAccountName,cn,mail,lastLogonTimeStamp"
' ...

Do Until adoRecordset.EOF
' Retrieve values and display.
strName = adoRecordset.Fields("sAMAccountName").Value
strCN = adoRecordset.Fields("cn").value
strMail= adoRecordset.Fields("mail").value

' Convert Integer8 value to date/time in current time zone.
On Error Resume Next
Set objDate = adoRecordset.Fields("lastLogonTimeStamp").Value
If (Err.Number <> 0) Then
On Error GoTo 0
dtmDate = #1/1/1601#
Else
On Error GoTo 0
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0 ) Then
dtmDate = #1/1/1601#
Else
dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow)/600000000 - lngBias)/1440
End If
End If

OutputLine = strName & ";" & strCN & ";" & strMail & ";" & dtmDate
Wscript.Echo OutputLine
objOutputFile.WriteLine(OutputLine )
adoRecordset.MoveNext
Loop
===========
I did not Dim the new variables. The same code can be used to retrieve
lastLogon (instead of lastLogonTimeStamp), but the value will only be valid
if you have one DC (or are lucky enough by chance to query the DC with the
largest value in the domain). Otherwise, especially if your domain is not at
W2k3 functional level, best would be to use the code to retrieve lastLogon
for all users in the domain (linked above) in a separate operation.

--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--


My System SpecsSystem Spec
Old 08-02-2008   #6 (permalink)
Al Dunbar


 
 

Re: List email addresses


"Richard Mueller [MVP]" <rlmueller-nospam@xxxxxx> wrote in
message news:u7LCiiD9IHA.3336@xxxxxx
Quote:

> Richard wrote:
>
Quote:

>> Is is possible to get the lastLogon field using this method?
>> I've adapted the script from your site and can now get the mail, but not
>> the lastLogon field which
>> I've seen used elsewhere. It always gives an error 'Object doesn't
>> support this property or
>> method', even though I know that some of the users have certainly logged
>> in.
>>
>> The key bits of the script, as far as I know, are:
>>
>> strAttributes = "sAMAccountName,cn,mail,lastLogon"
>> .
>> .
>> .
>>
>> ' Write the resulting recordset to file
>> Do Until adoRecordset.EOF
>> ' Retrieve values and display.
>> strName = adoRecordset.Fields("sAMAccountName").Value
>> strCN = adoRecordset.Fields("cn").value
>> strMail= adoRecordset.Fields("mail").value
>>
>> On error resume Next
>> strLastLogon= adoRecordset.Fields("lastLogon").value
>> if Err<>0 then
>> sLastLogonErrorMsg=replace(replace(Err.description,vbCr,""),vbLf,"")
>> else
>> sLastLogonErrorMsg="ok"
>> end if
>> Err.clear
>> On error goto 0
>>
>> OutputLine = strName & ";" & strCN & ";" & strMail & ";" &
>> strLastLogon & ";" &
>> sLastLogonErrorMsg
>> Wscript.Echo OutputLine
>> objOutputFile.WriteLine(OutputLine )
>> adoRecordset.MoveNext
>> Loop
>>
>>
>> As I mentioned, if I don't try to get the lastLogon, everything works.
>>
>> Thanks for any help,
>> Richard
>
> The lastLogon attribute is Integer8, a large (64-bit) number representing
> a date. It cannot be handled the way most string attributes are handled.
> In fact, something called the IADsLargeInteger interface must be used,
> that treats the value similar to an object and exposes HighPart and
> LowPart methods that break the 64-bit value into two 32-bit values. This
> is explained in detail at this link:
>
> http://www.rlmueller.net/Integer8Attributes.htm
>
> However, another complication is that lastLogon is not replicated. This
> means that a different value is saved on every Domain Controller (DC).
Strictly speaking, this is not exactly true (sorry, Richard). If the user
has never authenticated against two or more DC's, then these would all
register the same value for lastlogon. Of course, this would be done by
having no LastLogon attribute value stored for that account on these
particular DC's.

/Al
Quote:

> When the user authenticates to a DC, the lastLogon attribute for that
> user is updated on that DC, but the value is not replicated. To determine
> the true lastLogon date/time you must query every DC in the domain. I have
> an example VBScript program that retrieves the last logon dates for all
> users in the domain by querying every DC linked here:
>
> http://www.rlmueller.net/Last%20Logon.htm
>
> As explained in the link, there is a new attribute called
> lastLogonTimeStamp that is available if your domain is at Windows 2003
> functional level. This attribute is replicated, so you only need one query
> to get the value, but it is only updated if the old value is at least 14
> days (by default) in the past. This is so you can find unused accounts.
> Replicating any value everytime a user logged on would increase
> replication traffic unacceptably.
>
> The code to retrieve lastLogonTimeStamp would be similar to (in part):
> =============
> ' Obtain local Time Zone bias from machine registry.
> Set objShell = CreateObject("Wscript.Shell")
> lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
> & "TimeZoneInformation\ActiveTimeBias")
> If (UCase(TypeName(lngBiasKey)) = "LONG") Then
> lngTZBias = lngBiasKey
> ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
> lngTZBias = 0
> For k = 0 To UBound(lngBiasKey)
> lngTZBias = lngTZBias + (lngBiasKey(k) * 256^k)
> Next
> End If
> ' ...
>
> strAttributes = "sAMAccountName,cn,mail,lastLogonTimeStamp"
> ' ...
>
> Do Until adoRecordset.EOF
> ' Retrieve values and display.
> strName = adoRecordset.Fields("sAMAccountName").Value
> strCN = adoRecordset.Fields("cn").value
> strMail= adoRecordset.Fields("mail").value
>
> ' Convert Integer8 value to date/time in current time zone.
> On Error Resume Next
> Set objDate = adoRecordset.Fields("lastLogonTimeStamp").Value
> If (Err.Number <> 0) Then
> On Error GoTo 0
> dtmDate = #1/1/1601#
> Else
> On Error GoTo 0
> lngHigh = objDate.HighPart
> lngLow = objDate.LowPart
> If (lngLow < 0) Then
> lngHigh = lngHigh + 1
> End If
> If (lngHigh = 0) And (lngLow = 0 ) Then
> dtmDate = #1/1/1601#
> Else
> dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
> + lngLow)/600000000 - lngBias)/1440
> End If
> End If
>
> OutputLine = strName & ";" & strCN & ";" & strMail & ";" & dtmDate
> Wscript.Echo OutputLine
> objOutputFile.WriteLine(OutputLine )
> adoRecordset.MoveNext
> Loop
> ===========
> I did not Dim the new variables. The same code can be used to retrieve
> lastLogon (instead of lastLogonTimeStamp), but the value will only be
> valid if you have one DC (or are lucky enough by chance to query the DC
> with the largest value in the domain). Otherwise, especially if your
> domain is not at W2k3 functional level, best would be to use the code to
> retrieve lastLogon for all users in the domain (linked above) in a
> separate operation.
>
> --
> Richard Mueller
> MVP Directory Services
> Hilltop Lab - http://www.rlmueller.net
> --
>
>

My System SpecsSystem Spec
Old 08-02-2008   #7 (permalink)
richard


 
 

Re: List email addresses

On Fri, 1 Aug 2008 19:42:17 -0500, "Richard Mueller [MVP]" <rlmueller-nospam@xxxxxx>
wrote:

<---- snip ---->

Richard,

Thank you again for your help with these issues. I now have this part of my code doing what I need.

Regards,
Richard
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
use a list of email addresses from text file PowerShell
How do I make a list of addresses? Vista mail
List of Contacts' Addresses Vista mail
Can't email to craig's list address "sale######.org" addresses Vista mail
How to get a list of ip addresses? PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46