How does it work?
The mod involves placing a script block of code just before the closing body tag the reason for positioning it down here is that we want this code to run after the page elements have been rendered to aid with this the defer tag is also used which should defer running of the script until the body has loaded. This could have also been done by using the Onload event in the body but this is already used by the other script files so overloading it in the template breaks other things and I wanted to avoid modifying the scripts themselves. I found the method I described above in my limited testing works okay. What this script block does is gets an array of Divs in the body and then searches through them for a div with an id of divEnts. The first div it finds will represent the upper Address Book part of this page so we don’t want to modify this. The second div it finds with this Id should represent the Contacts section which is where we want to inject the html. So what this script does is inject another entry into this list by using the Innerhtml property of the existing divEnts div. The Div that is injected contains the OWA public folderID of the public folder you want to search as well as the displayName of what you want it to appear as. These two parts need to be customized by you if you wish to use this method. To find the OWAID of the public folder you could use a tool like fiddler to look at protocol captures of OWA or I have another method that uses the EWS convertID operation to convert the Hex entry ID which can be easily obtained using the standard EMS Get-PublicFolder cmdlet.
Finding the OWAID for the Public Folder
Using the standard EMS cmdlet Get-PublicFolder you get access the EntryID of the public folder in its Hex form eg
$pfPublicFolderPath = "\Public Contacts"
$pfFolder = get-publicFolder -identity $pfPublicFolderPath
This would get the Public Folder called Public Contacts in the root and then you can access the EntryID from the EntryID property eg $pfFolder.EntryID. Once you have this EntryID you then need to convert it to the OWAID so it can be used in OWA to do this you need to use the Exchange Web Service convertid operation. I’ve added the necessary EWS code to my EWSUtil powershell library to do this so the code you need just to do the conversion looks like.
[void][Reflection.Assembly]::LoadFile("C:\temp\EWSUtil.dll")
$null = [Reflection.Assembly]::LoadWithPartialName("System.Web")
$mbMailboxEmail = "user@domain.com”
$ewc = new-object EWSUtil.EWSConnection($mbMailboxEmail,$false, "", "", "","")
$Oulookid = $ewc.convertHexidPublicFolder($pfFolder.Entryid,[EWSUtil.EWS.IdFormatType]::OWAid)
[System.Web.HttpUtility]::UrlDecode($Oulookid)
You need to add the email address of the logged on user to the varible $mbMailboxEmail.When you run this code you should see an ID like
PSF.LgAAAAAaRHOQqmYRzZvIAKoAL8RaAwACQRpk/O1eTKnFP2PCsr25AAXCkNnpAAAB
Outputted to the commandline you need to copy this ID for use in the OWA addressbook form.
Modifying the Addressbook.aspx file
Before making any changes to the addressbook.aspx file make sure you copy this file to another location so you have a backup of this file incase the modification doesn’t work and you need to roll back the changes.
On the CAS server locate the OWA forms directory and then locate the addressbook.aspx file in the premium directory see

Open this file in Notepad.
Down the bottom of the file the last three entries in this file should look something like
<% RenderEndOfFileDiv(); %>
</body>
</html>
What we are going to do is put some script in just before the end body tag so the modified end of file should look like
<% RenderEndOfFileDiv(); %>
<script type="text/javascript" language="JavaScript" defer>
var dc=0
var divCollection = document.getElementsByTagName("div");
for (var i=0; i<divCollection.length; i++) {
if(divCollection[i].getAttribute("id") == "divEnts") {
if(dc == 1){
var pfId = "PSF.LgAAAAAaRHOQqmYRzZvIAKoAL8RaAwACQRpk/O1eTKnFP2PCsr25AAXCkNnpAAAB"
var pfName = "Company Contacts"
var newContactEntry = "<div class=snlEntW><div id=divEnt class=\"snlEnt snlDef\" _onclick=onClkCntFld() _fid=\"" + pfId +"\" type=\"IPF.Contact\"><img src=\"current/themes/base/cntctsmll.gif\"><span id=spn>" + pfName + "</span></div></div>";
divCollection[i].innerHTML = divCollection[i].innerHTML + newContactEntry
}
dc++;
}
}
</script>
</body>
</html>
The two varibles
var pfId = "PSF.LgAAAAAaRHOQqmYRzZvIAKoAL8RaAwACQRpk/O1eTKnFP2PCsr25AAXCkNnpAAAB"
var pfName = "Company Contacts"
need to be set to the OWAID you retrieved before and the name of the folder you want.
Thats it the change should be pretty much live as soon as you commit the changes . You need to consider this an untested and unsupported method and only for your own experimentation and testing under lab conditions (make sure your lab has SP1 installed or this wont work). I've put a download of the code to retrieve the OWA public folder ID and the other script change here. For the OWAid code you will need the latest copy of my EWSUtil powershell library
2 comments:
Hi Glen,
your script is fabulous.
But when we need to provide a search on one contact in the public folder we can't do this because the search bar is not present.
Do you have more informations about that ?
Thanks!
David
No sorry I don’t currently have a solution for that. Its has to do with the way OWA detects the search option for Public folder vs. Mailbox folders which doesn't seem to work in the addressbook view. Because doing something like this relies heavily on reverse engineering its exceeding time consuming. I should be doable but you could spend days trying and not get a result.
Cheers
Glen
Post a Comment