4

I'm using Exchange 2003, Outlook 2007/2003. Is there a way to push a set of contacts to users? I would prefer to not use the GAL and I really don't want to send csv files for them to import.

Any help is appreciated.

EDIT:

If someone has a great method of managing contacts with a mobile workforce, I'd love to hear that as well.

5 Answers 5

0

This is an extremely mangled vbscript I've been using to push a sub-folder of contacts from one user to a list of users provided in a text file:

snServername = "exchange"
mnMailboxname = "user.to.copy.from"
mndestmailbox = ""

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
    ("c:\scripts\users.txt", ForReading)
Do Until objTextFile.AtEndOfStream
    mndestmailbox = objTextFile.Readline

    wscript.echo ""
    wscript.echo mndestmailbox


SourceURL = "http://" & snServername & "/exchange/" & mnMailboxname & "/contacts/folder to copy/"
DestinURL = "http://" & snServername & "/exchange/" & mndestmailbox & "/contacts/folder to copy/"
set req = createobject("microsoft.xmlhttp")

set CDOSession = CreateObject("MAPI.Session")
strProfile = snServername & vbLf & mnMailboxname
CDOSession.Logon "",,, False,, True, strProfile
set RDOSession = CreateObject("Redemption.RDOSession")
RDOSession.MAPIOBJECT = CDOSession.MAPIOBJECT
set cfCalendarFolder1 = RDOSession.GetSharedDefaultFolder(mndestmailbox, 10)
For Each fld In cfCalendarFolder1.Folders
    If fld.name = "folder to copy" Then 
        Set cfCalendarFolder = fld 
    End if
next

colbblob = Collabblobget()
wscript.echo colbblob
QueryMailbox(colbblob)

wscript.echo "Done"

Loop


Sub QueryMailbox(colbblob)

strQuery = "<?xml version=""1.0""?><D:searchrequest xmlns:D = ""DAV:"" xmlns:R=""http://schemas.microsoft.com/repl/""><R:repl><R:collblob>" & colbblob & "</R:collblob></R:repl>"
strQuery = strQuery & "<D:sql>SELECT ""DAV:href"", ""urn:schemas:httpmail:subject"", ""http://schemas.microsoft.com/mapi/proptag/x0fff0102"",""http://schemas.microsoft.com/repl/repl-uid"" "
strQuery = strQuery & " FROM scope('shallow traversal of """
strQuery = strQuery & SourceURL & """') Where NOT ""urn:schemas:calendar:instancetype"" = 2 AND NOT ""urn:schemas:calendar:instancetype"" = 3 AND ""DAV:ishidden"" = False AND ""DAV:isfolder"" = False "
strQuery = strQuery & "</D:sql></D:searchrequest>"
req.open "SEARCH", SourceURL, false, "", ""
req.setrequestheader "Content-Type", "text/xml"
req.setRequestHeader "Translate","f"
req.send strQuery
If req.status >= 500 Then
   wscript.echo "Status: " & req.status
   wscript.echo "Status text: An error occurred on the server."
ElseIf req.status = 207 Then
   wscript.echo "Status: " & req.status
   wscript.echo "Status text:  " & req.statustext
   set oResponseDoc = req.responseXML
   set oNodeList = oResponseDoc.getElementsByTagName("d:collblob")
   For i = 0 To (oNodeList.length -1)
    set oNode = oNodeList.nextNode
        colblob =  oNode.Text
    Collabblobset(colblob)
   Next
   set idNodeList = oResponseDoc.getElementsByTagName("f:x0fff0102")
   set replidNodeList = oResponseDoc.getElementsByTagName("d:repl-uid")
   set replchangeType = oResponseDoc.getElementsByTagName("d:changetype")
   for id = 0 To (idNodeList.length -1)
    set oNode1 = idNodeList.nextNode
    set oNode2 = replidNodeList.nextNode
    set oNode3 = replchangeType.nextNode
    select case oNode3.text
        case "new" call Copyapt(Octenttohex(oNode1.nodeTypedValue),oNode2.text)
        case "delete" wscript.echo oNode3.text
                  wscript.echo oNode2.text
                  DeleteContact(oNode2.text)
        case "change" Wscript.echo "Change"
                  call DeleteContact(oNode2.text)
                  call Copyapt(Octenttohex(oNode1.nodeTypedValue),oNode2.text)
    end select
   next
Else
   wscript.echo "Status: " & req.status
   wscript.echo "Status text: " & req.statustext
   wscript.echo "Response text: " & req.responsetext
End If

End Sub

function Collabblobget()

xmlreqtxt = "<?xml version='1.0'?><a:propfind xmlns:a='DAV:' xmlns:cp='" & SourceURL & "'><a:prop><cp:collblob/></a:prop></a:propfind>"
req.open "PROPFIND", DestinURL, false, "", ""
req.setRequestHeader "Content-Type", "text/xml; charset=""UTF-8"""
req.setRequestHeader "Depth", "0"
req.setRequestHeader "Translate", "f"
req.send xmlreqtxt
set oResponseDoc = req.responseXML
set oCobNode = oResponseDoc.getElementsByTagName("d:collblob")
For i1 = 0 To (oCobNode.length -1)
   set oNode = oCobNode.nextNode
   Collabblobget = oNode.Text   
Next

End function

Sub Collabblobset(colblob)
xmlstr = "<?xml version=""1.0""?>" _
& "<g:propertyupdate " _
& "    xmlns:g=""DAV:"" xmlns:e=""http://schemas.microsoft.com/exchange/""" _ 
& "    xmlns:dt=""urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"" " _
& "    xmlns:cp=""" & SourceURL & """ " _
& "    xmlns:header=""urn:schemas:mailheader:"" " _
& "    xmlns:mail=""urn:schemas:httpmail:"">  " _
& "    <g:set>  " _
& "        <g:prop>  " _
& "            <cp:collblob>" & colblob & "</cp:collblob>  " _
& "        </g:prop>  " _
& "    </g:set>  " _ 
& "</g:propertyupdate>" 

req.open "PROPPATCH", DestinURL, False
req.setRequestHeader "Content-Type", "text/xml;"
req.setRequestHeader "Translate", "f"
req.setRequestHeader "Content-Length:", Len(xmlstr)
req.send(xmlstr)


end sub

Sub CopyApt(messageEntryID,ReplID)
set objapt = CDOSession.GetMessage(messageEntryID)
set objCopyapt = objapt.copyto(cfCalendarFolder.EntryID)
objCopyapt.Unread = false
objCopyapt.Fields.Add "0x8542", vbString, ReplID,"0820060000000000C000000000000046"
objCopyapt.Update
Set objCopyapt = Nothing
wscript.echo objapt.subject

end Sub

Sub CopyContact(messageEntryID,ReplID)
set objcontact = objSession.getmessage(messageEntryID)
set objCopyContact = objcontact.copyto(pfPublicFolderID,objpubstore.ID)
objCopyContact.Unread = false
objCopyContact.Fields.Add "0x8542", vbString, ReplID,"0820060000000000C000000000000046"
objCopyContact.Update
Set objCopyContact = Nothing
wscript.echo objcontact.subject

end Sub

Sub DeleteContact(replUID)

strQuery = "<?xml version=""1.0""?><D:searchrequest xmlns:D = ""DAV:"">"
strQuery = strQuery & "<D:sql>SELECT ""DAV:Displayname"""
strQuery = strQuery & " FROM scope('shallow traversal of """
strQuery = strQuery & DestinURL & """') Where ""http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/0x8542"" = '" & replUID & "' AND ""DAV:isfolder"" = False "
strQuery = strQuery & "</D:sql></D:searchrequest>"
req.open "SEARCH", DestinURL, false
req.setrequestheader "Content-Type", "text/xml"
req.setRequestHeader "Translate","f"
req.send strQuery
wscript.echo req.responsetext
If req.status >= 500 Then
   wscript.echo "Status: " & req.status
   wscript.echo "Status text: An error occurred on the server."
ElseIf req.status = 207 Then
   wscript.echo "Status: " & req.status
   wscript.echo "Status text:  " & req.statustext
   set oResponseDoc = req.responseXML
   set oNodeList = oResponseDoc.getElementsByTagName("a:href")
   For i = 0 To (oNodeList.length -1)
    set oNode = oNodeList.nextNode
    wscript.echo oNode.text
    req.open "DELETE", oNode.text, false
    req.send 
    wscript.echo "Status: " & req.status
   Next
Else
   wscript.echo "Status: " & req.status
   wscript.echo "Status text: " & req.statustext
   wscript.echo "Response text: " & req.responsetext
End If

end Sub


Function Octenttohex(OctenArry)  
  ReDim aOut(UBound(OctenArry)) 
  For i = 1 to UBound(OctenArry) + 1 
    if len(hex(ascb(midb(OctenArry,i,1)))) = 1 then 
        aOut(i-1) = "0" & hex(ascb(midb(OctenArry,i,1)))
    else
    aOut(i-1) = hex(ascb(midb(OctenArry,i,1)))
    end if
  Next 
  Octenttohex = join(aOUt,"")
End Function 

I can't remember where I found the initial script, but I will post if I find it. I think this one will only work on Exchange 2003. Also, for this to work properly, the user must have the folder to copy already in the correct place (but empty).

2
  • I'll try this out and see if it works. This might do the trick. Jul 16, 2009 at 19:11
  • You only should need to edit some of the parameters at the beginning. Please forgive the messiness, this script sort of evolved over time and has not been reworked for distribution. Some parameters to edit: exchange server name, user to copy from, text file of users to copy to, the text file must have 1 username per line, and do a find/replace for "folder to copy".
    – moshen
    Jul 16, 2009 at 19:17
0

You could have somebody code up a script to copy all of the contacts from a public folder (CSV file, etc) into a "Contacts" folder in each user's mailbox as one possible method. (A script that accesses the mailboxes through WebDAV would be fairly easy to do this with.) I'm not aware of an off-the-shelf product that does that.

If you don't want to go to that level of work, consider putting the contacts into a public folder and either asking the users to mark it a "Favorite" or asking them to copy the contacts into their mailboxes. Obviously, this isn't a "push".

1
  • Option #1 might be the best solution. I'm trying to figure out if I really want to go to those lengths though. Jul 15, 2009 at 17:39
0

What about just emailing the contacts to the users? I guess they would probably need to add them using Outlook, but it seems like it would be pretty easy to just email them to the users.

2
  • In a normal environment that is exactly what I would do. Unfortunately, these users are mostly mobile, mostly non-technical, and need extreme assistance levels. Just trying to make it as easy as possible for them. Jul 16, 2009 at 13:38
  • Ahh, my favorite kind. Jul 16, 2009 at 14:01
0

I don't know if this is one would apply to your problem but you could set up a eGroupware system.

This is free and open source. You can sync it with a lot of diffrent mobile phones and of course with any outlook or exchange. You then have to sync your system with the installation to get your contact online. Then every user needs to configure a client for syncing. As mentioned there are a lot of different plugins for mobile phones.

All contacts then get pushed to your clients phones. You can group them and set global permissions. Maybe this would help. But be warned, it's still hard to get eGroupware running and set up correctly.

0

Don't push them out, share them...

I found this article that has a decent explanation of how to share contacts through a Public Folder. And this other article with a little more information, plus more on what can be done with public folders.

Once it is setup works great.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .