Wednesday, April 06, 2005

Modify Public Folder custom attributes via script and .Net

Somebody asked today about a script to change the custom attributes of a public folder on Exchange 2x. I was supprised that i couldn't find any samples out there to do this (maybe i didn't look hard enough) so I thought i'd bolt one together. Its some pretty simple ADSI code just uses one LDAP filter to find the public folder's DN based on the public folders emailaddress (its about the only real unique property you can search on) and then connects to the folder and makes the mod using ADSI. Its designed to run with two commandline parameters the first is the email address of the public folder and the second is the value for the custom attribute. The script modifies extensionAttribute1 but its can be easly adapted to modify other attributes. I've also included a VB.NET sample that does the same thing using System.Directoryservices just for fun.

I've posted a downloadable copy of both sample here

The script looks like

pfnamemail = wscript.arguments(0)
customvalue = wscript.arguments(1)
set conn = createobject("ADODB.Connection")
set com = createobject("ADODB.Command")
Set iAdRootDSE = GetObject("LDAP://RootDSE")
strNameingContext = iAdRootDSE.Get("defaultNamingContext")
rangeStep = 999
lowRange = 0
highRange = lowRange + rangeStep
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"
pfQuery = ";(&(&(&(& (mailnickname=*) (| (objectCategory=publicFolder) )))(objectCategory=publicFolder)(mail=" & pfnamemail & ")));name,distinguishedName;subtree"
Com.ActiveConnection = Conn
Com.CommandText = pfQuery
Set Rs = Com.Execute
While Not Rs.EOF
set objuser = getobject("LDAP://" & rs.fields("distinguishedName"))
objuser.extensionAttribute1 = customvalue
objuser.setinfo
wscript.echo "Modified folder " & objuser.displayname & " Added attribute " & objuser.extensionAttribute1
rs.movenext
Wend

The .NET sample looks like

Dim strnewvalue As String = "newvalue"
Dim strpfnamemail As String = "email@domain.com"
Dim objsearch As New System.DirectoryServices.DirectorySearcher
Dim strrootdse As String = objsearch.SearchRoot.Path
Dim objdirentry As New System.DirectoryServices.DirectoryEntry(strrootdse)
Dim objresult As System.DirectoryServices.SearchResult
Dim stremailaddress As String
Dim strhomeserver As String
Dim pffolder As System.DirectoryServices.DirectoryEntry
Dim pffolderdn As String
objsearch.Filter = "(&(&(&(& (mailnickname=*) (| (objectCategory=publicFolder) )))(objectCategory=publicFolder)(mail=" & strpfnamemail & ")))"
objsearch.SearchScope = DirectoryServices.SearchScope.Subtree
objsearch.PropertiesToLoad.Add("distinguishedName")
Dim colresults As DirectoryServices.SearchResultCollection = objsearch.FindAll()
For Each objresult In colresults
pffolderdn = "LDAP://" & objresult.GetDirectoryEntry().Properties("distinguishedName").Value
pffolder = New System.DirectoryServices.DirectoryEntry(pffolderdn)
pffolder.Properties("extensionAttribute1").Item(0) = strnewvalue
pffolder.CommitChanges()
pffolder.Close()
Next

9 comments:

Prateek said...

hi Glen i need a script by which i can change the email address of all the pulic folders.

i have aroung 500 public folders in my exchange server so i cant do it manualy therefore i need a script so as to change the email address

Thanks,
Prateek

Glen said...

If you have a look at CDOEXM there is a IMailRecipient interface along with a IFolder interface that can be used to script changing email address on folder.With 500 folder your going to need to write a custom solution that address's your particular needs yourself pretty easy script though.

Anonymous said...

Hi Glen, Is it possible to find the folder path of the public folder by its email address?

It would be easy to find the folder if I had something less than about 60000 public folders. For example, i need to find folder which already has address itservices@domain.biz. By using ADUC or freeware util ADFIND I can get displayname of the folder not the path (only legacy path, which in most cases isn't valid anymore - a known issue caused by migration from Exchange 5.5). So in this example I would have returned about seven folders with name IT SERVICES and no idea about where they are located in Public Folders structure. Do you know how to find folder along with its path by knowing only it's email address?

Thanks,

Glen said...

What you can do is query Active Directory to find the proxy object for that public folder based on the email address you have. The if you transpose the GUID you can then use it to query WMI to retrieve the Public folder path eg

Email = "smtp:folder@domain.com"
ExchangeServer = "servername"
Set rootDSE = GetObject("LDAP://RootDSE")
domainContainer = rootDSE.Get("defaultNamingContext")
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADSDSOObject"
conn.Open "ADs Provider"
LDAPStr = "<LDAP://" & DomainContainer & ">(&(objectCategory=publicfolder)(proxyAddresses=" & email & "));adspath,objectguid;subtree"
Set rs = conn.Execute(LDAPStr)
If rs.RecordCount = 1 Then
wscript.echo FindPublicFolderWMI(transposeGuid(ConvertObjectGuidToString(rs.fields("objectguid"))))
End If

Function ConvertObjectGuidToString(ByVal arrRawObjectGUID)
Dim i, strByte
Dim arrObjectGUID(15)
For i = 1 To LenB(arrRawObjectGUID)
strByte = Hex(AscB(MidB(arrRawObjectGUID, i, 1)))
If Len(strByte) = 1 Then strByte = "0" & strByte
arrObjectGUID(i - 1) = strByte
Next
ConvertObjectGuidToString = Join(arrObjectGUID, "")
End Function

Function transposeGuid(guid)
transposeGuid = "{" & mid(guid,7,2) & mid(guid,5,2) & mid(guid,3,2) _
& mid(guid,1,2) & "-" & mid(guid,11,2) & mid(guid,9,2) _
& "-" & mid(guid,15,2) & mid(guid,13,2) & "-" & mid(guid,17,4) _
& "-" & mid(guid,21,12) & "}"
end function

Function FindPublicFolderWMI(AdproxyPath)

Const cWMINameSpace = "root/MicrosoftExchangeV2"
Const cWMIInstance = "Exchange_PublicFolder"
strWinMgmts = "winmgmts:{impersonationLevel=impersonate}!//"& _
ExchangeServer &"/"&cWMINameSpace
Set objWMIServices = GetObject(strWinMgmts)
Set objPubInstances = objWMIServices.ExecQuery ("Select * From Exchange_PublicFolder Where adproxyPath='" & AdproxyPath & "'")
For Each objExchange_PublicFolder in objPubInstances
path = objExchange_PublicFolder.Path
Next
FindPublicFolderWMI = path
End function

Anonymous said...

Hi Glen,
I'm looking for a script (.NET) that will enable me to show a public folder calendar on my intranet website. Do you have a script like that or know where to find? mailto:m_brunnstrom@hotmail.com

denu_love said...

Hi Glen,
Can I change CustomAttribute of Every Mailbox, taking an Excel File OR CSV file as a source?

Thanks,
Denis

Glen said...

Sure if you use ADSI you could script something like this. If you just want to update each account to the same value you might want to look at using ADMODIFY.NET

Cheers
Glen

Kevin Sl said...

dear glen,

i'm trying to find a script where i can delete al custom attributes in exchange management console.
is this possible?

kind regards,

kevin

Glen said...

see http://groups.google.com/group/microsoft.public.exchange.applications/browse_thread/thread/8def79c672790fb6/ea7c5ab8efeb6f4c?#ea7c5ab8efeb6f4c

Cheers
Glen