![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| 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. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | 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 Specs![]() |
| | #2 (permalink) |
| | 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 > > /****************/ 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 Specs![]() |
| | #3 (permalink) |
| | 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 Specs![]() |
| | #4 (permalink) |
| | 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 Specs![]() |
| | #5 (permalink) |
| | 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 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 Specs![]() |
| | #6 (permalink) |
| | 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). 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 Specs![]() |
| | #7 (permalink) |
| | 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 Specs![]() |
![]() |
| 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 | |||