Is there an AD property that will tell me if an account uses ActiveSync?
I know that Exchange needs to hold onto sync status information for mailboxes, so I'm hoping I can use a related property to know who's using a smartphone to check mail.
We're still on Exchange 2003 so far. It seems like the nicest method would be a saved query in ADUC, which I could hopefully use to create a distribution group? But whatever you've got is better than what I have, so thanks in advance.
No, but you can ask exchange if a user is using activesync. You need to find if Microsoft-Server-ActiveSync exists on that mailbox. You need to look for the Glen Scales wrote a script to do just that. You can also parse the logs. I couldn't find it on his site so here's the code:
servername = wscript.arguments(0)
set shell = createobject("wscript.shell")
strValueName = "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias"
minTimeOffset = shell.regread(strValueName)
toffset = datediff("h",DateAdd("n", minTimeOffset, now()),now())
report = "<table border=""1"" width=""100%"">" & vbcrlf
report = report & " <tr>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">DisplayName</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">Email Address</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">Device Type</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">Device ID</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">FolderSync</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">ContactSync</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">CalendarSync</font></b></td>" & vbcrlf
report = report & "<td align=""center"" bgcolor=""#000080""><b><font color=""#FFFFFF"">autdstate.xml</font></b></td>" & vbcrlf
report = report & "</tr>" & vbcrlf
set req = createobject("microsoft.xmlhttp")
set com = createobject("ADODB.Command")
set conn = createobject("ADODB.Connection")
Set iAdRootDSE = GetObject("LDAP://RootDSE")
strNameingContext = iAdRootDSE.Get("configurationNamingContext")
strDefaultNamingContext = iAdRootDSE.Get("defaultNamingContext")
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"
polQuery = "<LDAP://" & strNameingContext & ">;(&(objectCategory=msExchRecipientPolicy)(cn=Default Policy));distinguishedName,gatewayProxy;subtree"
svcQuery = "<LDAP://" & strNameingContext & ">;(&(objectCategory=msExchExchangeServer)(cn=" & Servername & "));cn,name,legacyExchangeDN;subtree"
Com.ActiveConnection = Conn
Com.CommandText = polQuery
Set plRs = Com.Execute
while not plRs.eof
for each adrobj in plrs.fields("gatewayProxy").value
if instr(adrobj,"SMTP:") then dpDefaultpolicy = right(adrobj,(len(adrobj)-instr(adrobj,"@")))
next
plrs.movenext
wend
wscript.echo dpDefaultpolicy
Com.CommandText = svcQuery
Set Rs = Com.Execute
while not rs.eof
GALQueryFilter = "(&(&(&(& (mailnickname=*)(!msExchHideFromAddressLists=TRUE)(| (&(objectCategory=person)(objectClass=user)(msExchHomeServerName=" & rs.fields("legacyExchangeDN") & ")) )))))"
strQuery = "<LDAP://" & strDefaultNamingContext & ">;" & GALQueryFilter & ";displayname,mail,distinguishedName,mailnickname,proxyaddresses;subtree"
com.Properties("Page Size") = 100
Com.CommandText = strQuery
Set Rs1 = Com.Execute
while not Rs1.eof
falias = "http://" & servername & "/exadmin/admin/" & dpDefaultpolicy & "/mbx/"
if not isnull(rs1.fields("proxyaddresses").value) then
for each paddress in rs1.fields("proxyaddresses").value
if instr(paddress,"SMTP:") then falias = falias & replace(paddress,"SMTP:","") & "/non_ipm_subtree"
next
wscript.echo falias
SerachAsync(falias)
else
wscript.echo "*** Null Proxy **** : " & rs1.fields("mailnickname")
end if
rs1.movenext
wend
rs.movenext
wend
rs.close
set conn = nothing
set com = nothing
report = report & "</table>" & vbcrlf
Set fso = CreateObject("Scripting.FileSystemObject")
set wfile = fso.opentextfile("c:\temp\asreport.htm",2,true)
wfile.write report
wfile.close
set wfile = nothing
set fso = nothing
wscript.echo "Done"
sub SerachAsync(furl)
strQuery = "<?xml version=""1.0""?><D:searchrequest xmlns:D = ""DAV:"" >"
strQuery = strQuery & "<D:sql>SELECT ""http://schemas.microsoft.com/mapi/proptag/x3001001E"""
strQuery = strQuery & " FROM scope('shallow traversal of """
strQuery = strQuery & furl & """') Where ""DAV:ishidden"" = False AND ""DAV:isfolder"" = True AND "
strQuery = strQuery & """http://schemas.microsoft.com/mapi/proptag/x3001001E"" = 'Microsoft-Server-ActiveSync'</D:sql></D:searchrequest>"
req.open "SEARCH", furl, false
req.setrequestheader "Content-Type", "text/xml"
req.setRequestHeader "Translate","f"
on error resume next
req.send strQuery
if err.number <> 0 then wscript.echo err.description
on error goto 0
If req.status >= 500 Then
ElseIf req.status = 207 Then
set oResponseDoc = req.responseXML
set oNodeList = oResponseDoc.getElementsByTagName("d:x3001001E")
if oNodeList.length <> 0 then
wscript.echo "Active-Sync Folder Exists"
displayAyncSub(furl & "/Microsoft-Server-ActiveSync")
else
wscript.echo "No Active-Sync Folder"
end if
Else
End If
end sub
sub displayAyncSub(furl)
strQuery = "<?xml version=""1.0""?><D:searchrequest xmlns:D = ""DAV:"" >"
strQuery = strQuery & "<D:sql>SELECT ""http://schemas.microsoft.com/mapi/proptag/x3001001E"""
strQuery = strQuery & " FROM scope('shallow traversal of """
strQuery = strQuery & furl & """') Where ""DAV:ishidden"" = False AND ""DAV:isfolder"" = True</D:sql></D:searchrequest>"
req.open "SEARCH", furl, false
req.setrequestheader "Content-Type", "text/xml"
req.setRequestHeader "Translate","f"
on error resume next
req.send strQuery
if err.number <> 0 then wscript.echo err.description
on error goto 0
If req.status >= 500 Then
ElseIf req.status = 207 Then
set oResponseDoc = req.responseXML
set oNodeList = oResponseDoc.getElementsByTagName("d:x3001001E")
for each node in oNodeList
call displaydeviceSub(furl & "/" & node.text,node.text)
next
Else
End If
end sub
sub displaydeviceSub(furl,fname)
strQuery = "<?xml version=""1.0""?><D:searchrequest xmlns:D = ""DAV:"" >"
strQuery = strQuery & "<D:sql>SELECT ""http://schemas.microsoft.com/mapi/proptag/x3001001E"""
strQuery = strQuery & " FROM scope('shallow traversal of """
strQuery = strQuery & furl & """') Where ""DAV:ishidden"" = False AND ""DAV:isfolder"" = True</D:sql></D:searchrequest>"
req.open "SEARCH", furl, false
req.setrequestheader "Content-Type", "text/xml"
req.setRequestHeader "Translate","f"
on error resume next
req.send strQuery
if err.number <> 0 then wscript.echo err.description
on error goto 0
If req.status >= 500 Then
ElseIf req.status = 207 Then
set oResponseDoc = req.responseXML
set oNodeList = oResponseDoc.getElementsByTagName("d:x3001001E")
for each node in oNodeList
report = report & "<tr>" & vbcrlf
report = report & "<td align=""center"">" & rs1.fields("displayname") & " </td>" & vbcrlf
report = report & "<td align=""center"">" & rs1.fields("mail") & " </td>" & vbcrlf
report = report & "<td align=""center"">" & fname & " </td>" & vbcrlf
report = report & "<td align=""center"">" & node.text & " </td>" & vbcrlf
report = report & finditems(furl & "/" & node.text)
report = report & "</tr>" & vbcrlf
next
Else
End If
end sub
function finditems(furl)
hascalsyc = 0
hasfolsyc = 0
hasconsyc = 0
hasautd = 0
rback = ""
strQuery = "<?xml version=""1.0""?><D:searchrequest xmlns:D = ""DAV:"" >"
strQuery = strQuery & "<D:sql>SELECT ""DAV:displayname"", ""DAV:getlastmodified"""
strQuery = strQuery & " FROM scope('shallow traversal of """
strQuery = strQuery & furl & """') Where ""DAV:isfolder"" = False</D:sql></D:searchrequest>"
req.open "SEARCH", furl, false
req.setrequestheader "Content-Type", "text/xml"
req.setRequestHeader "Translate","f"
on error resume next
req.send strQuery
if err.number <> 0 then wscript.echo err.description
on error goto 0
rem wscript.echo req.responsetext
If req.status >= 500 Then
ElseIf req.status = 207 Then
set oResponseDoc = req.responseXML
set oNodeList = oResponseDoc.getElementsByTagName("a:displayname")
set oNodemodlist = oResponseDoc.getElementsByTagName("a:getlastmodified")
wscript.echo oNodeList.length
for i = 1 to oNodeList.length
set onode = oNodeList.nextNode
set onode1 = oNodemodlist.nextNode
select case lcase(onode.text)
case "calendarsyncfile" hascalsyc = 1
hascalsycval = DateAdd("h",toffset,(left(replace(replace(onode1.text,"T"," "),"Z",""),19)))
case "foldersyncfile" hasfolsyc = 1
hasfolsycval = DateAdd("h",toffset,(left(replace(replace(onode1.text,"T"," "),"Z",""),19)))
case "contactssyncfile" hasconsyc = 1
hasconsycval = DateAdd("h",toffset,(left(replace(replace(onode1.text,"T"," "),"Z",""),19)))
case "autdstate.xml" hasautd = 1
hasautdval = DateAdd("h",toffset,(left(replace(replace(onode1.text,"T"," "),"Z",""),19)))
end select
next
Else
End If
wscript.echo hasfolsyc
if hasfolsyc = 1 then
rback = rback & "<td align=""center"">" & hasfolsycval & " </td>" & vbcrlf
else
rback = rback & "<td align=""center"">No </td>" & vbcrlf
end if
if hasconsyc = 1 then
rback = rback & "<td align=""center"">" & hasconsycval & " </td>" & vbcrlf
else
rback = rback & "<td align=""center"">No </td>" & vbcrlf
end if
if hascalsyc <> 0 then
rback = rback & "<td align=""center"">" & hascalsycval & " </td>" & vbcrlf
else
rback = rback & "<td align=""center"">No </td>" & vbcrlf
end if
if hasautd <> 0 then
rback = rback & "<td align=""center"">" & hasautdval & " </td>" & vbcrlf
else
rback = rback & "<td align=""center"">No </td>" & vbcrlf
end if
finditems = rback
end function
Looks like it's controlled by one of the bits in msExchOmaAdminWirelessEnable. Here's the bit description listed by someone in this post.
1 (bit 0) = 1 to disable Server Activesync, 0 to enable it
2 (bit 1) = 1 to disable OMA, 0 to enable it
4 (bit 2) = 1 to disable Always Up-To-Date (AUTD), 0 to enbable it
Looks like the value is a decimal value in AD so you'd need to AND the bits together and convert that to decimal to set it. Thus:
Disable everything = 0x111 = 7
Enable ActiveSync, Disable OMA, Disable AUTD = 0x110 = 6
Enable ActiveSync, Disable OMA, Enable Autd = 0x010 = 4
etc...
Have a look at this first: http://support.microsoft.com/kb/830188
So, basically, the "msExchOmaAdminWirelessEnable" attribute isn't set on all user objects by default, and access using ActiveSync is allowed. If you elect to turn it off for all users, and then enable it only for the users who require it, then you can filter / query on this "msExchOmaAdminWirelessEnable" attribute.
So, it's a chicken and egg problem. If you don't know who is using it, you can't change this attribute.
I'd consider parsing the logs on your IIS server to determine who is using ActiveSync, then consider setting the flag on all users who are not using it. It's painful, but it looks like the best way I can see to do what you want.