Blog - Title

Brijs Blogging... Looking Beyond the Obvious

  • Brijs Blogging... Looking Beyond the Obvious

    Issue: Getting 'This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.' exception while building Outlook VSTO add-in in VS 2010

    • 14 Comments

    In case you have FIPS compliance enabled and you are building VSTO/Windows applications using Visual Studio 2010 then you will get exception as mentioned below:

    Error 1 Source file 'c:\users\brijs\documents\visual studio 2010\Projects\OutlookAddInFIPS\OutlookAddInFPIS\ThisAddIn.cs' could not be opened ('This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.') OutlookAddInFIPS

    Error 1 Source file 'c:\users\brijs\documents\visual studio 2010\Projects\WindowsFormsApplicationFIPS\WindowsFormsApplicationFIPS\Form1.cs' could not be opened ('This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.') WindowsFormsApplicationFIPS

    To know more about FIPS refer The effects of enabling the "System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing" security setting in Windows XP and in later versions of Windows

    In order to enable FIPS you need to follow steps mentioned below

    • This security setting affects the following registry value in Windows Server 2008 and in Windows Vista: HKLM\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy\Enabled
      This registry value reflects the current FIPS setting. If this setting is enabled, the value is 1. If this setting is disabled, the value is 0.
    • This security setting affects the following registry value in Windows Server 2003 and in Windows XP: HKLM\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy
      This registry value reflects the current FIPS setting. If this setting is enabled, the value is 1. If this setting is disabled, the value is 0.

    After you enable or disable the System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing security setting, you must restart your application, such as Internet Explorer, for the new setting to take effect.

    To workaround the above issue you can either opt out of FIPS compliance by changing the registry as mentioned above.

    Or In order to just avoid the issue with Visual Studio 2010 one can follow the steps mentioned below:

    • Open Devenv.exe.config from
      C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE if you are on x64 OS
      or C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ on x86 OS
    • Find </runtime> tag and add the following above that line:
      <enforceFIPSPolicy enabled="false"/>
    • After the above modification devenv config would look like:
      <configuration>
      <runtime>
      .
      .
      .
      <enforceFIPSPolicy enabled="false"/>
      </runtime>
      </configuration>
    • Restart Visual Studio

    enforceFIPSPolicy is a .Net 2.0 SP1 config file switch which helps the application to opt out FIPS checking.

    Hope this helps!!!

  • Brijs Blogging... Looking Beyond the Obvious

    How to get reference to Public Folder Store using Outlook Object Model for Outlook 2010?

    • 8 Comments

    On Outlook 2007 or previous version for the Outlook we can refer to the public folder as below:

    Set olns =Item. Application.GetNamespace("MAPI")
    Set pub = olns.Folders("Public Folders")

    However, the above given code snippet would fail on Outlook 2010 by throwing exception "Run-time error -2147221233 (8004010f) The attempted operation failed. An object could not be found" because with Outlook 2010.

    We have an option to configure multiple exchange account in the same profile and Outlook appends the user's SMTP address used to configure the account to the mailbox/public folder store name to identify each of the account and Outlook would show/refer to the mailbox/public folder  as shown in image below.

    OLPF

    Here is the sample code snippet in VBA to get reference to Public Folder Store using Outlook Object Model for Outlook 2010:

    'NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. 
    'This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment. 
    <SAMPLE CODE> 
    If InStr(Item.Application.Version, "14") Then
    Set olns =Item. Application.GetNamespace("MAPI")
    Set accs = olns.Accounts
    For Each Account In accs
        If Account.AccountType = olExchange And Account.SmtpAddress = olns.Session.DefaultStore Then
            Set pub = olns.Folders("Public Folders" & " - " & Account.SmtpAddress)
            MsgBox "Got the Pub folders"
        End If
    Next
     
        If pub Is Nothing Then
            MsgBox "No Public Folder store found for the default exchange mailbox"
        End If
    End If
    </SAMPLE CODE> 

    Hope this helps!!! Feel free to ask questions related to Outlook/Exchange development.

  • Brijs Blogging... Looking Beyond the Obvious

    How to convert Exchange Item’s EntryID to EWS unique ItemId via EWS Managed API ConvertId call?

    • 3 Comments

    One of my customer requested for some guidance for How to convert Exchange Item’s EntryID to EWS unique ItemId via EWS Managed API’s ConvertId call?

    Here is the sample code snippet for converting Exchange Item’s EntryID to EWS unique ItemId via Exchange Web Services Managed API’s ConvertId call:

    /*NOTE: Following programming examples is for illustration only, without warranty either expressed or implied,
    including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose.
    This sample code assumes that you are familiar with the programming language being demonstrated and the
    tools used to create and debug procedures. This sample code is provided for the purpose of illustration only
    and is not intended to be used in a production environment.*/

     //Call the GetConvertedEWSID to convert Item’s EntryID to EWSID 
    String sEntryID = "AAAAN0ybz+zO+JOhV4pGimkcYQHAAtH+9AAFtlUAAA==";
    String sEWSID = GetConvertedEWSID(service,sEntryID, "TestEx2010@BrijEx2010.com");
    MessageBox.Show(sEWSID);
           
    //Pass ExchaneService, ItemEntryID and SMTP address of parent Mailbox of Item as Parameters
    private String GetConvertedEWSID(ExchangeService esb,String sID,String strSMTPAdd)
    {
                // Create a request to convert identifiers.
                AlternateId objAltID = new AlternateId();
                objAltID.Format = IdFormat.EntryId;
                objAltID.Mailbox = strSMTPAdd;
                objAltID.UniqueId = sID;

                //Convert  PR_ENTRYID identifier format to an EWS identifier.
                AlternateIdBase objAltIDBase = esb.ConvertId(objAltID , IdFormat.EwsId);
                AlternateId objAltIDResp = (AlternateId)objAltIDBase;
                return objAltIDResp.UniqueId;
    }

    Here is EWS SOAP Request and Response for the ConvertId call:

     

    EwsRequest --- <EwsLogEntry EntryKind="EwsRequest" ThreadId="8" Timestamp="9/10/2010 4:26:22 AM">
      <?xml version="1.0" encoding="utf-8"?>
      <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Header>
          <t:RequestServerVersion Version="Exchange2010" />
        </soap:Header>
        <soap:Body>
          <m:ConvertId DestinationFormat="EwsId">
            <m:SourceIds>
              <t:AlternateId Format="EntryId" Id="AAAAN0ybz+zO+JOhV4pGimkcYQHAAtH+9AAFtlUAAA=="   Mailbox="TestEx2010@BrijEx2010.com" />
            </m:SourceIds>
          </m:ConvertId>
        </soap:Body>
      </soap:Envelope>
    </EwsLogEntry>

    EwsResponseHttpHeaders --- <EwsLogEntry EntryKind="EwsResponseHttpHeaders" ThreadId="8" Timestamp="9/10/2010 4:26:32 AM">200 OK
    Transfer-Encoding: chunked
    Content-Encoding: gzip
    Vary: Accept-Encoding
    X-EwsPerformanceData: RpcC=0;RpcL=0;LdapC=0;LdapL=0;
    Persistent-Auth: true
    Cache-Control: private
    Content-Type: text/xml; charset=utf-8
    Date: Thu, 09 Sep 2010 22:56:32 GMT
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 2.0.50727
    X-Powered-By: ASP.NET

    </EwsLogEntry>

    EwsResponse --- <EwsLogEntry EntryKind="EwsResponse" ThreadId="8" Timestamp="9/10/2010 4:26:32 AM">
      <?xml version="1.0" encoding="utf-8"?>
      <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Header>
          <h:ServerVersionInfo MajorVersion="14" MinorVersion="0" MajorBuildNumber="639" MinorBuildNumber="21" Version="Exchange2010" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
        </s:Header>
        <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <m:ConvertIdResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
            <m:ResponseMessages>
              <m:ConvertIdResponseMessage ResponseClass="Success">
                <m:ResponseCode>NoError</m:ResponseCode>
                <m:AlternateId xsi:type="t:AlternateIdType" Format="EwsId" Id="AAMkADM0MDhiYjI5LTY1YjktNGNjOS04ZjdmLWZhZTlmNzdiNjllOQBGAAAAAADdMVg7cuSIleOBbZVAAA=" Mailbox="TestEx2010@brijex2010.com" />
              </m:ConvertIdResponseMessage>
            </m:ResponseMessages>
          </m:ConvertIdResponse>
        </s:Body>
      </s:Envelope>
    </EwsLogEntry>

     

    For reference:

  • Brijs Blogging... Looking Beyond the Obvious

    How to check current installed version of PowerShell?

    • 3 Comments

    To determine the current installed version of PowerShell; in PowerShell type the following built in variable : $PSVersionTable.

    PSVersionTable

    If we use Get-Host it will just shows you the version of the host (i.e. of Console.Exe) as below:

    PSGet-Host

  • Brijs Blogging... Looking Beyond the Obvious

    How to configure and use EWS Impersonation on Exchange 2010/2007?

    • 0 Comments

    We can refer to the below mentioned articles for configuring and using EWS impersonation for the Exchange 2010:

    And here are the links for configuring and using EWS impersonation for the Exchange 2007:

    Hope this helps!!!

  • Brijs Blogging... Looking Beyond the Obvious

    Where is PFDAVAdmin for the Exchange Server 2010? ExFolders is here now!!!

    • 2 Comments

    Users of PFDAVAdmin on Exchange Server 2003/2007 must be wondering that with the recent release of Exchange Server 2010, PFDAVAdmin is no longer available to work because WebDAV is gone from Exchange 2010.

    However, We can accomplish a lot of the things which we used to do only in PFDAVAdmin, with Exchange PowerShell Cmdlets e.g. Get-PublicFolder and Set-PublicFolder can be used to export and import permissions; and Get-MailboxFolderPermission and Set-MailboxFolderPermission can be used to export and import mailbox permissions. However, there are still a few things we just cannot do without PFDAVAdmin.

    Fortunately, we have a solution - a tool called ExFolders. This new tool is really just a port of PFDAVAdmin to Exchange 2010. For details we can refer to the announcement from Bill Long @ Exchange, meet ExFolders. ExFolders still has the same user interface as PFDAVAdmin, so things will look very familiar. However, there are a few changes to note as mentioned below.

    • ExFolders must be run from an Exchange 2010 server - it cannot be run from a workstation as PFDAVAdmin could.
    • It can connect to Exchange 2010 or Exchange 2007, but not older versions.
    • Permissions export format between PFDAVAdmin and ExFolders are compatible.

    Here is the list of a few new features:

    • Folder property imports are now supported. We were able to do folder property exports with PFDAVAdmin, but not imports.
    • Item property exports are supported i.e. we can export a set of properties from all items in a folder. However, Item property imports are not supported.
    • ExFolders supports the new free/busy permissions that were introduced in Exchange 2007 and Outlook 2007.
    • We can now connect to multiple mailbox stores at the same time, so you can run a batch operation against several mailbox stores or all mailboxes in the organization as well.

    I would also suggest you to go through the readme for more details. I would also like to mention that there is No official support for the ExFolders (as like for PFDAVAdmin).

    We can download ExFolders @ http://msexchangeteam.com/files/12/attachments/entry453398.aspx

    Enjoy!!!

  • Brijs Blogging... Looking Beyond the Obvious

    Getting “Derived types must either match the security accessibility of the base type or be less accessible” exception after migrating VSTO add-in project to Visual Studio 2010 and targeting it to .Net 4.0 Framework.

    • 3 Comments

    We are getting following exception after migrating Outlook 2007 VSTO add-in project to Visual Studio 2010 and targeting it to .Net 4.0 Framework for Outlook 2010:

    Inheritance security rules violated by type: 'VS2008_FR_OLAddIn.ThisAddIn'. Derived types must either match the security accessibility of the base type or be less accessible.

    ************** Exception Text **************

    System.TypeLoadException: Inheritance security rules violated by type: 'VS2008_FR_OLAddIn.ThisAddIn'. Derived types must either match the security accessibility of the base type or be less accessible.

    at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)

    at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)

    at Microsoft.VisualStudio.Tools.Office.Runtime.DomainCreator.ExecuteCustomization.CreateEntryPoint(String entryPointTypeName)

    at Microsoft.VisualStudio.Tools.Office.Runtime.DomainCreator.ExecuteCustomization.Microsoft.VisualStudio.Tools.Office.Runtime.Interop.IExecuteCustomization2.LoadEntryPoints(IntPtr serviceProvider)

     

    The above issue is happening in case if we upgrade an Office project from Visual Studio 2008. In this case, you must remove the SecurityTransparentAttribute.

    Visual Studio does not automatically remove these attributes when the target framework is changed.

    StepsTo remove the SecurityTransparentAttribute

    • With the project open in Visual Studio, open Solution Explorer.
    • Under the Properties node (for C#) or the My Project node (for Visual Basic), double-click the AssemblyInfo code file to open it in the code editor.
    • Locate the SecurityTransparentAttribute and either remove it from the file or comment it out.

    For more detail refer @ Removing Obsolete Attributes from Office Projects that You Migrate to the .NET Framework 4.

     

    We would also need to keep in consideration Required Changes to Run Office Projects that You Migrate to the .NET Framework 4 to avoid other issue.

    Hope this helps!!!

  • Brijs Blogging... Looking Beyond the Obvious

    How to do FindItem and GetItem Operations of Exchange Web Services using VB.net

    • 2 Comments

    It does seem to be a bit of a dearth of VB.net samples for Exchange Web Service. So here is a sample Vb.net code which demonstrates:

    • FindItem(How to perform FindItem Operation to list all items from the inbox folder of a use mailbox)
    • GetItem (How to perform GetItem Operation to get an item with all properties)

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment. 

    'List all the items from the inbox folder
     Private Function ListFolderItems(ByRef esb As ExchangeServiceBinding) As List(Of MessageType)
            Dim Messages As New List(Of MessageType)
            Messages = Nothing
     
            ' Form the FindItem request
            Dim findRequest As FindItemType = New FindItemType()
            findRequest.Traversal = ItemQueryTraversalType.Shallow
     
            ' Define which item properties are returned in the response
            Dim itemProperties As ItemResponseShapeType = New ItemResponseShapeType()
            itemProperties.BaseShape = DefaultShapeNamesType.AllProperties
     
            ' Add properties shape to request
            findRequest.ItemShape = itemProperties
     
            ' Identify which folders to search to find items
            Dim folderIDArray() As DistinguishedFolderIdType = New DistinguishedFolderIdType(1) {}
            folderIDArray(0) = New DistinguishedFolderIdType()
            folderIDArray(0).Id = DistinguishedFolderIdNameType.inbox
     
            ' Add folders to request
            findRequest.ParentFolderIds = folderIDArray
     
     
            'Send the listing (find) request and get the response
            Dim findResp As New FindItemResponseType
            findResp = esb.FindItem(findRequest)
     
            ' Get the response messages
            Dim responseMessage As ResponseMessageType
            For Each responseMessage In findResp.ResponseMessages.Items
                ' Cast to the correct response message type
                Dim findItemResponseMessage As FindItemResponseMessageType = responseMessage
                If findItemResponseMessage.ResponseClass = ResponseClassType.Success Then
     
                    ' Get the actual payload of items
                    Dim realItems As ArrayOfRealItemsType = findItemResponseMessage.RootFolder.Item
                    If Not realItems.Items Is Nothing Then
                        ' Initialize list of messages and fill
                        Messages = New List(Of MessageType)(realItems.Items.Length)
                        Dim message As MessageType = Nothing
                        Dim item As ItemType = Nothing
                        For Each item In realItems.Items
                            If TypeOf item Is MessageType Then
                                message = item
                                Messages.Add(message)
                            End If
                        Next
                    End If
                End If
            Next
            Return Messages
        End Function
     
    'To get a specific item based on ItemId
    Public Shared Function GetItem(ByVal serviceBinding As ExchangeServiceBinding, ByVal itemID As String) As ItemType
            ' Form the GetItem request
            Dim getRequest As GetItemType = New GetItemType()
     
            ' Define which item properties are returned in the response
            Dim itemProperties As ItemResponseShapeType = New ItemResponseShapeType()
            itemProperties.BaseShape = DefaultShapeNamesType.AllProperties
     
            ' Add properties shape to request
            getRequest.ItemShape = itemProperties
     
            ' Set the itemID of the desired item to retrieve
            Dim id As ItemIdType = New ItemIdType()
            id.Id = itemID
     
            getRequest.ItemIds = New ItemIdType() {id}
            ' Send the listing (find) request and get the response
            Dim getResp As New GetItemResponseType
            getResp = serviceBinding.GetItem(getRequest)
     
            ' Get the response message
            If getResp.ResponseMessages.Items(0).ResponseClass = ResponseClassType.Success Then
                Dim iirmt As ItemInfoResponseMessageType = getResp.ResponseMessages.Items(0)
                If iirmt.Items.Items.Length > 0 Then
                    Return iirmt.Items.Items(0)
                Else
                    Return Nothing
                End If
            Else
                Return Nothing
            End If
        End Function
     
     

    Here are the few link related to EWS for basis understanding :

    Please share you comments or questions with me related to subjects on my blog. I would like to explore the messaging world further with you...

  • Brijs Blogging... Looking Beyond the Obvious

    How to send email and create appointment item using EWS Managed API in VB.net?

    • 0 Comments

    It does seem to be a bit of a dearth of VB.net samples for Exchange Web Service Managed API. So here is a sample VB.net code which demonstrates:

    • Send Email
    • Create Appointment

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment. 

    Imports System.Net
    Imports System.Net.Security
    Imports Microsoft.Exchange.WebServices.Data
    Imports System.Security.Cryptography.X509Certificates
     
    Public Class Form1
        'Creating Servie object for EWS service binding endpoint
        Dim service As New ExchangeService(requestedServerVersion:=ExchangeVersion.Exchange2007_SP1)
     
        Private Sub cmdSendMail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSendMail.Click
            Try
                'Create new message object and set properties required to send a mail
                Dim message As EmailMessage = New EmailMessage(service)
                message.Subject = "Hello from the EWS Managed API"
                message.Body = "Now that's easy!"
                message.ToRecipients.Add("testex2007@bex2007.com")
                message.SendAndSaveCopy()
                MessageBox.Show("Email Sent!!!")
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
     
        End Sub
     
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            'Add a valid EWS service end point here or user Autodiscover
            service.Url = New Uri("https://server/ews/exchange.asmx")
            'Add a valid user credentials
            service.Credentials = New WebCredentials("User", "Password", "Domain")
            'To address the SSL challenge
            ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateCertificate)
     
        End Sub
     
        Private Function ValidateCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal 
     
    chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
            'Return True to force the certificate to be accepted.
            Return True
        End Function
     
        Private Sub cmdCreateAppointment_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 
    Handles cmdCreateAppointment.Click
            Try
                'Create appointment object and set properties as required
                Dim appt As Appointment = New Appointment(service)
                appt.Subject = "Holidays"
                appt.Body = "The appointment is for holiday placeholder"
                appt.Start = New DateTime(2010, 11, 1)
                appt.End = appt.Start.AddHours(24)
                appt.IsAllDayEvent = True
                appt.LegacyFreeBusyStatus = LegacyFreeBusyStatus.OOF
                appt.Save(WellKnownFolderName.Calendar, SendInvitationsMode.SendToNone)
                MessageBox.Show("Appointment Added to Calendar")
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
    End Class

    We can refer to the articles mentioned below for further reading:

    Enjoy EWS and Happy Holidays!!!

  • Brijs Blogging... Looking Beyond the Obvious

    How to do FindFolder and MoveItem Operations of Exchange Web Services using VB.net

    • 1 Comments

    In continuations of my previous post How to do FindItem and GetItem Operations of Exchange Web Services using VB.net ; Here is the Exchange Web Services sample in VB.net to perform following task:

    • FindFolder(How to perform FindFolder Operation to get FolderId of specific folder for the root of the mailbox)
    • MoveItem (How to perform MoveItem Operation to move an item to the another folder within the mailbox)

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment. 

    Private Sub cmdMove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdMove.Click
            Try
                If lstMails.SelectedItems.Count = 1 Then
                    Dim itemID As New ItemIdType
                    itemID.Id = lstMails.SelectedItems(0).SubItems(3).Text
     
                    'Find the folderId to which we want to move item
                    Dim parentFolder As New DistinguishedFolderIdType
                    parentFolder.Id = DistinguishedFolderIdNameType.root
                    Dim tfTargetFolder As New FolderIdType
                    'Change the name of the folder we are searching for FolderID
                    tfTargetFolder = FindFolder(ServiceBinding, parentFolder, "Test")
     
                    Dim newItemID As New ItemIdType
                    'Move am Item based on ItemId and FolderID
                    newItemID = MoveItemtoTest(ServiceBinding, itemID.Id, tfTargetFolder)
                    Dim strId As String
                    strId = "New ItemID " + newItemID.Id.ToString
                    MessageBox.Show(strId, "Item Moved", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Else
                    MessageBox.Show("Please select a item in list to move", "Item to Move", MessageBoxButtons.OK, MessageBoxIcon.Information)
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
     
    Public Shared Function FindFolder(ByVal serviceBinding As ExchangeServiceBinding, ByVal fiFolderID As DistinguishedFolderIdType, ByVal fnFldName As String) As FolderIdType
     
            Dim rvFolderID As New FolderIdType
            ' Create the request and specify the travesal type
            Dim findFolderRequest As FindFolderType = New FindFolderType()
            findFolderRequest.Traversal = FolderQueryTraversalType.Deep
     
            ' Define the properties returned in the response
            Dim responseShape As FolderResponseShapeType = New FolderResponseShapeType()
            responseShape.BaseShape = DefaultShapeNamesType.Default
            findFolderRequest.FolderShape = responseShape
     
            ' Identify which folders to search
            Dim folderIDArray() As DistinguishedFolderIdType = New DistinguishedFolderIdType(1) {}
            folderIDArray(0) = New DistinguishedFolderIdType()
            folderIDArray(0).Id = fiFolderID.Id
     
            'Add Restriction for DisplayName
            Dim ffRestriction As New RestrictionType
            Dim ieToType As New IsEqualToType
            Dim diDisplayName As New PathToUnindexedFieldType
            diDisplayName.FieldURI = UnindexedFieldURIType.folderDisplayName
     
            Dim ciConstantType As New FieldURIOrConstantType
            Dim cvConstantValueType As New ConstantValueType
            cvConstantValueType.Value = fnFldName
            ciConstantType.Item = cvConstantValueType
            ieToType.Item = diDisplayName
            ieToType.FieldURIOrConstant = ciConstantType
            ffRestriction.Item = ieToType
            findFolderRequest.Restriction = ffRestriction
     
            ' Add the folders to search to the request
            findFolderRequest.ParentFolderIds = folderIDArray
     
            Try
                ' Send the request and get the response
                Dim findFolderResponse As FindFolderResponseType = serviceBinding.FindFolder(findFolderRequest)
                ' Get the response messages
                If findFolderResponse.ResponseMessages.Items(0).ResponseClass = ResponseClassType.Error Then
                    MessageBox.Show("Error Occured")
                    MessageBox.Show(findFolderResponse.ResponseMessages.Items(0).MessageText)
                    Return Nothing
                Else
                    Dim rmta() As ResponseMessageType = findFolderResponse.ResponseMessages.Items
                    Dim rmt As ResponseMessageType
                    For Each rmt In rmta
                        ' Cast to the correct response message type
                        Dim ffResponse As FindFolderResponseMessageType = rmt
                        Dim fFoundFolder As FolderType
                        For Each fFoundFolder In ffResponse.RootFolder.Folders
                            rvFolderID = fFoundFolder.FolderId
                            'MessageBox.Show(fFoundFolder.DisplayName)
                        Next
                    Next
                    'Return the FolderID of the last folder found
                    Return (rvFolderID)
                End If
            Catch e As Exception
                MessageBox.Show(e.Message)
                Return Nothing
            End Try
        End Function
    Public Shared Function MoveItemtoTest(ByVal serviceBinding As ExchangeServiceBinding, ByVal itemID As String, ByVal trgfldID As FolderIdType) As ItemIdType
     
            'Setup FolderId and ItemId to be passed to MoveItem
            Dim tfTargetFolder As TargetFolderIdType = New TargetFolderIdType()
            tfTargetFolder.Item = trgfldID
     
            Dim iiItemId As ItemIdType = New ItemIdType()
            iiItemId.Id = itemID
     
            'Create request to move Item and specify properties
            Dim miMoveItemRequest As MoveItemType = New MoveItemType()
            miMoveItemRequest.ItemIds = New ItemIdType(1) {}
            miMoveItemRequest.ItemIds(0) = iiItemId
            miMoveItemRequest.ToFolderId = tfTargetFolder
     
            Dim nID As New ItemIdType
            Try
                ' Send the request and get the response
                Dim miResponse As MoveItemResponseType = serviceBinding.MoveItem(miMoveItemRequest)
                If miResponse.ResponseMessages.Items(0).ResponseClass = ResponseClassType.Error Then
                    MessageBox.Show("Error Occured")
                    MessageBox.Show(miResponse.ResponseMessages.Items(0).MessageText)
                    Return Nothing
                Else
                    Dim iirmt As ItemInfoResponseMessageType = miResponse.ResponseMessages.Items(0)
                    If iirmt.Items.Items.Length > 0 Then
                        'Get updated ItemId from the Response Message
                        nID = iirmt.Items.Items(0).ItemId
                        MessageBox.Show("Item Moved")
                        'Return updated ItemID
                        Return nID
                    Else
                        Return Nothing
                    End If
                End If
            Catch e As Exception
                MessageBox.Show(e.Message)
                Return Nothing
            End Try
        End Function

    We can refer to the following articles related to the EWS:

    While we can workout more with Exchange Web Service auto generated proxies but don’t forget to have look at Microsoft Exchange Web Services (EWS) Managed API 1.0 to do stuff with less sweat. :)

  • Brijs Blogging... Looking Beyond the Obvious

    Service Pack 3 for Exchange Server 2007 is now available to download

    • 0 Comments

    Service Pack 3 is now available to download for the Microsoft Exchange Server 2007. With this service pack now we can install Exchange Server 2007 on the Windows Server 2008 R2.

    We can download Exchange 2007 SP3 here. 

    For an overview of the new features that are available in Exchange Server 2007 SP3, see "What's New in Exchange Server 2007 SP3".

    Additionally, Exchange 2007 SP3 includes all the updates that are included in Update Rollup 4 and earlier for Exchange 2007 SP2. For more information, see Microsoft Knowledge Base article 981383, Description of Update Rollup 4 for Exchange Server 2007 Service Pack 2.

    For a list of schema changes that are made by Exchange 2007 SP3, see Active Directory Schema Changes (SP3).

  • Brijs Blogging... Looking Beyond the Obvious

    Visual Studio 2010 Service Pack(SP) 1 is released and available for download

    • 0 Comments

    Microsoft has released Visual Studio 2010 Service Pack(SP) 1.This service pack release addresses issues that were found through a combination of customer and partner feedback, as well as internal testing. These service packs offer Visual Studio users improvements in responsiveness and stability, as well as completes some high-impact scenarios requested by customers. The full list of updates included in this service pack can be found here.

    To obtain Visual Studio 2010 SP1, visit the following Microsoft website:

    Microsoft Visual Studio 2010 Service Pack 1

    Important:

    • Visual Studio 2010 Service Pack 1 (SP1) will upgrade all editions and languages of Visual Studio 2010 you have already installed. If you install any other editions or languages of Visual Studio 2010 after SP1, you must reapply SP1.
    • If you installed Visual Studio 2010 Service Pack 1 Beta, you should not uninstall it before installing this release of SP1.
    • Prior to installation, you should carefully review the readme to be aware of any known issues with this release.

    Note: Do not install this service pack if you have downloaded and installed the stand-alone ‘Microsoft Windows SDK for Windows 7 and .NET Framework 4 (Windows SDK v7.1)’ and you are using the x64 or IA64 compilers that were included in that download. Please see the related article for more information.

  • Brijs Blogging... Looking Beyond the Obvious

    Download for Office 2010 Service Pack 1(SP1) is available now

    • 0 Comments

    The Microsoft Office Sustained Engineering Team announced availability of  Service Pack 1 (SP1) for Microsoft Office 2010 family of products. SP1 contains all Cumulative Updates and Public Updates for 2010 that have already shipped. SP1 also contains new fixes for areas of each product. For those of you seeking a complete list of changes for each product contained in SP1, please visit this Excel Workbook – this is a very handy reference for those building test / evaluation plans for Office Client SP1. The workbook containing the changes for SharePoint Server 2010 is located under this link.

    Specifically, these are the key areas of improvement in SP1 for Outlook 2010 SP1

    • Outlook 2010 SP1 includes Office 365 support.
    • Outlook 2010 SP1 can be set to always use the default sending account.
    • Fixes an issue in which the snooze time does not between appointments.

    We can refer to the KB Articles referenced below for the further details and download links:

  • Brijs Blogging... Looking Beyond the Obvious

    Remove all PST from the Outlook Mailbox using VBScript

    • 1 Comments

    If you would like to remove all of the Personal Folders file .PSTs attached to the Outlook Mailbox profile then we can use RemoveStore Method.

    Here is a sample VBScript to perform the job for us:

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.

    'Sample script to remove Personal Folders files (.pst) from the current MAPI profile or session
    RemoveAllPST
     
    Sub RemoveAllPST()
    Dim objOL 'As New Outlook.Application
    Dim objFolders 'As Outlook.MAPIFolders
    Dim objFolder 'As Outlook.MAPIFolder
    Dim i 'As Interger
    Dim strPrompt 'As String
     
    Set objOL = CreateObject("Outlook.Application")
    Set objFolders = objOL.Session.Folders
    For i = objFolders.Count To 1 Step -1
    On Error Resume Next
        Set objFolder = objFolders.Item(i)
         
        'Prompt the user for confirmation
        If (InStr(1, objFolder.Name, "Mailbox") = 0) And (InStr(1, objFolder.Name, "Public Folders") = 0) Then
        
        strPrompt = ""
        strPrompt = "Are you sure you want to remove " & objFolder.Name
       
        If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
            objOL.Session.RemoveStore objFolder
        End If
        End If
    Next
     
    End Sub

    We can also refer to the article mentioned below related to RemoveStore Method:

    NameSpace.RemoveStore Method
    http://msdn.microsoft.com/en-us/library/bb219923.aspx

    Hope this helps.

  • Brijs Blogging... Looking Beyond the Obvious

    How to enable EWS Tracing using Exchange Web Services (EWS) Managed API in VB.net?

    • 1 Comments

    Debugging a Web service–based application can be difficult because part of the processing is performed on a computer to which you do not have access. Because you cannot step through the code on the server, it can be helpful to see the XML requests and responses that are exchanged between the client and the server to determine which part of the application is causing an error. When you are using the Microsoft Exchange Web Services (EWS) Managed API, you can use the tracing methods on the ExchangeService object to capture the XML request that is sent to Exchange Web Services and the response that the server returns to the application.

    To enable tracing on the ExchangeService object:

    Dim _exchangeService As New ExchangeService
    Dim TC As New EWSTrace.TraceListener
    _exchangeService.TraceFlags = TraceFlags.All
    _exchangeService.TraceEnabled = True
    _exchangeService.TraceListener = TC

    The following code example shows simple object that implements the ITraceListener interface and stores the traced requests and responses in XML or text files.

    'NOTE: Following programming examples is for illustration only, without warranty either expressed or implied,
    'including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. 
    'This sample code assumes that you are familiar with the programming language being demonstrated and
    'the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment. 
    Imports System
    Imports System.Text
    Imports Microsoft.Exchange.WebServices.Data
     
    Namespace EWSTrace
     
        Class TraceListener
            Implements ITraceListener
     
            Public Sub Trace(ByVal traceType As String, ByVal traceMessage As String) Implements ITraceListener.Trace
                CreateXMLTextFile(traceType + " --- " + traceMessage.ToString())
            End Sub
     
            Private Sub CreateXMLTextFile(ByVal traceContent As String)
                'Get the path of the application to create log files at
                Dim strPath As String = System.AppDomain.CurrentDomain.BaseDirectory
                strPath = strPath + "\\EWSLog.txt"
                Dim FS As System.IO.FileStream
                If System.IO.File.Exists(strPath) = False Then
                    FS = System.IO.File.Create(strPath)
                Else
                    FS = System.IO.File.OpenWrite(strPath)
                End If
                FS.Close()
     
                ' Create an instance of StreamWriter to write text to a file.
                Dim sw As System.IO.StreamWriter = System.IO.File.AppendText(strPath)
                sw.WriteLine(System.DateTime.Now.ToString() + " : " + traceContent)
                sw.Close()
                FS = Nothing
                sw = Nothing
            End Sub
        End Class
    End Namespace

    For reference and C# sample code snippet refer:

  • Brijs Blogging... Looking Beyond the Obvious

    How to set msExchRecipientTypeDetails Active Directory Attribute using VBScript.

    • 1 Comments

    When we move Mailbox from Exchange 2003 to Exchange 2007, it may be shown as Linked Mailbox.

    This issue can occur if the associated external account was set on the user's Microsoft Exchange Server 2003 or Exchange 2000 Server mailbox.

    To resolve the problem, modify the user account attribute msExchRecipientTypeDetails from a value of 2 to a value of 1 using ADSI Edit.

    We can refer to the article mentioned below:

    Or use the sample VBScript given below:

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied,
    including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose.
    This sample code assumes that you are familiar with the programming language being demonstrated and the tools used
    to create and debug procedures.

       1:  Dim obj
       2:  'ToDo: Modifiy the UserAlias, Domain, DomainExtn
       3:  Set obj = GetObject("LDAP://CN=UserAlias,CN=Users,DC=Domain,DC=DomainExtn")
       4:  obj.msExchRecipientTypeDetails = 1
       5:  obj.SetInfo()
       6:  Set obj = nothing
     
    Hope this helps! Enjoy
  • Brijs Blogging... Looking Beyond the Obvious

    How enumerate mailbox permission using ADSI VBScript?

    • 2 Comments

    We can use ADSI VBScript sample given below to enumerate mailbox permission from the exchange server.

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.

    OPTION EXPLICIT
     
    Const ADS_ACETYPE_ACCESS_ALLOWED = &H00
    Const ADS_ACETYPE_ACCESS_DENIED = &H01
    Const ADS_ACETYPE_SYSTEM_AUDIT = &H02
    Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &H05
    Const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &H06
    Const ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = &H07
    Const ADS_ACETYPE_SYSTEM_ALARM_OBJECT = &H08
    Const ADS_ACETYPE_ACCESS_ALLOWED_CALLBACK = &H09
    Const ADS_ACETYPE_ACCESS_DENIED_CALLBACK = &H0A
    Const ADS_ACETYPE_ACCESS_ALLOWED_CALLBACK_OBJECT = &H0B
    Const ADS_ACETYPE_ACCESS_DENIED_CALLBACK_OBJECT = &H0C
    Const ADS_ACETYPE_SYSTEM_AUDIT_CALLBACK = &H0D
    Const ADS_ACETYPE_SYSTEM_ALARM_CALLBACK = &H0E
    Const ADS_ACETYPE_SYSTEM_AUDIT_CALLBACK_OBJECT = &H0F
    Const ADS_ACETYPE_SYSTEM_ALARM_CALLBACK_OBJECT = &H10
     
    Const ADS_ACEFLAG_INHERIT_ACE = &H02
    Const ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = &H04
    Const ADS_ACEFLAG_INHERIT_ONLY_ACE = &H08
    Const ADS_ACEFLAG_INHERITED_ACE = &H10
    Const ADS_ACEFLAG_VALID_INHERIT_FLAGS = &H1f
    Const ADS_ACEFLAG_SUCCESSFUL_ACCESS = &H40
    Const ADS_ACEFLAG_FAILED_ACCESS = &H80
     
    Const ADS_RIGHT_DELETE = &H00010000
    Const ADS_RIGHT_READ_CONTROL = &H00020000
    Const ADS_RIGHT_WRITE_DAC = &H00040000
    Const ADS_RIGHT_WRITE_OWNER = &H00080000
    Const ADS_RIGHT_SYNCHRONIZE = &H00100000
    Const ADS_RIGHT_ACCESS_SYSTEM_SECURITY = &H01000000
    Const ADS_RIGHT_GENERIC_READ = &H80000000
    Const ADS_RIGHT_GENERIC_WRITE = &H40000000
    Const ADS_RIGHT_GENERIC_EXECUTE = &H20000000
    Const ADS_RIGHT_GENERIC_ALL = &H10000000
    Const ADS_RIGHT_DS_CREATE_CHILD = &H00000001
    Const ADS_RIGHT_DS_DELETE_CHILD = &H00000002
    Const ADS_RIGHT_ACTRL_DS_LIST = &H00000004
    Const ADS_RIGHT_DS_SELF = &H00000008
    Const ADS_RIGHT_DS_READ_PROP = &H00000010
    Const ADS_RIGHT_DS_WRITE_PROP = &H00000020
    Const ADS_RIGHT_DS_DELETE_TREE = &H00000040
    Const ADS_RIGHT_DS_LIST_OBJECT = &H00000080
    Const ADS_RIGHT_DS_CONTROL_ACCESS = &H00000100
     
    Const FULLCONTROL = 983551
     
    Const ReceiveAs = "{AB721A56-1E2F-11D0-9819-00AA0040529B}"
    Const SendAs = "{AB721A54-1E2F-11D0-9819-00AA0040529B}"
     
    Dim objUser
    Dim oSecurityDescriptor 
    Dim dacl 
    Dim ace 
    Dim strOutput
    Dim strPath
    Dim strOutputPath
    Dim fso
    Dim fOutput
    Dim strAccount 
    Dim strAccess
    Dim Conn
    Dim Comm
    Dim RSAll
    Dim iAdRootDSE
    Dim strNameingContext
    Dim Query
     
     
    strOutput = InputBox("File Output", "", "ExportData.csv")
     
    strPath = WScript.ScriptFullName
    stroutputPath = Left(strPath, InStrRev(strPath, "\"))
     
    set fso = CreateObject("Scripting.FileSystemObject")
    set fOutput = fso.CreateTextFile(strOutputPath & strOutput, 8)
     
     
    Set iAdRootDSE = GetObject("LDAP://RootDSE")
    strNameingContext = iAdRootDSE.Get("defaultNamingContext")
    Query = "<LDAP://" & strNameingContext & ">;(&(mailnickname=*)(objectCategory=person)(objectClass=user));samaccountname,displayname,distinguishedName;subtree"
     
     
    set conn = createobject("ADODB.Connection")
     
    Conn.Provider = "ADsDSOObject"
    Conn.Open "ADs Provider"
     
    set comm = createobject("ADODB.Command")
    Comm.ActiveConnection = conn
    Comm.CommandText = Query
    Comm.Properties("Page Size") = 1000
     
    Set RsAll = Comm.Execute
     
    Dim dn
    While Not RSAll.EOF
        dn = "LDAP://" & replace(RSAll.Fields("distinguishedName").Value,"/","\/")
        GetPermissions(dn)
        RSAll.movenext
    Wend
     
    WScript.Echo "Done viewing the security descriptor"
    WScript.Quit
        
     
    '====================================================================
    ' Get the msExchMailboxSecurityDescriptor attribute and break it down
    '====================================================================
    sub GetPermissions(DN)
     
    'Get directory user object.
    Set objUser = GetObject(DN)
    'Here we can use Display name as well to print.
    strAccount = objUser.Get("samAccountName")
    'strAccount = objUser.Get("displayName")
    fWriteLine("*Permission Info for :" & strAccount & vbcrlf) 
    Set oSecurityDescriptor = objUser.Get("msExchMailboxSecurityDescriptor")
     
    Set dacl = oSecurityDescriptor.DiscretionaryAcl
    Set ace = CreateObject("AccessControlEntry")
     
    For Each ace In dacl
    ' Display all the properties of the ACEs using the IADsAccessControlEntry interface.
     
    strAccess = "Access Mask: " & vbcrlf
     
    if (ace.AccessMask AND ADS_RIGHT_DELETE ) then strAccess = strAccess & " Delete Permission" & vbcrlf
    if (ace.AccessMask AND ADS_RIGHT_READ_CONTROL ) then strAccess = strAccess & " Read Permission " & vbcrlf
    if (ace.AccessMask AND ADS_RIGHT_WRITE_DAC ) then strAccess = strAccess & " Change Permission" & vbcrlf
    if (ace.AccessMask AND ADS_RIGHT_WRITE_OWNER ) then strAccess = strAccess & " Take Ownership " & vbcrlf
    if (ace.AccessMask AND ADS_RIGHT_ACTRL_DS_LIST ) then strAccess = strAccess & " Associated External Account" & vbcrlf
    if (ace.AccessMask AND ADS_RIGHT_DS_CREATE_CHILD ) then strAccess = strAccess & " Full Rights " & vbcrlf
     
    fWriteLine("*==========================================================================*")
    'fWriteLine("* RAW Info:" & vbcrlf & "TRUSTEE :" & vbcrlf & " " & ace.Trustee & vbcrlf & _
    '"AccessMask:" & vbcrlf & " " & ace.AccessMask & vbcrlf & _
    '"AceType :" & vbcrlf & " " & ace.AceType & vbcrlf & _
    '"AceFlags :" & vbcrlf & " " & ace.AceFlags & vbcrlf & _
    '"Flags :" & vbcrlf & " " & ace.Flags & vbcrlf & _
    '"ObjectType:" & vbcrlf & " " & ace.ObjectType & vbcrlf & _
    '"Inherited :" & vbcrlf & " " & ace.InheritedObjectType)
     
    'fWriteLine("*--------------------------------------------------------------------------*")
    fWriteLine("* Access Info:" & vbcrlf & "TRUSTEE :" & vbcrlf & " " & ace.Trustee & vbcrlf & strAccess)
    Next
     
     
    End Sub
     
     
    '====================================================================
    ' Write the data to a file
    '====================================================================
    sub fWriteLine(data)
    fOutput.WriteLine data
    end sub

    For a version of the above script which uses CDOEXM checkout my colleague's post @ http://blogs.msdn.com/vikas/archive/2008/11/01/howto-programmatically-enumerate-permissions-on-exchange-2003-mailbox-store.aspx
  • Brijs Blogging... Looking Beyond the Obvious

    How to retrieve email address from the “From” and “To” field of mail item using EWS Managed API?

    • 1 Comments

    In case we are calling FindItem for EWS Managed API then, it will provide much of the information that a client application needs. It basically returns a summary of an item. FindItem returns only the first 512 bytes of any streamable property. For Unicode, it returns the first 255 characters by using a null-terminated Unicode string.

    FindItem does not return a message body, attachments, or recipient lists.

    Use GetItemType to get the details of specific items. GetItem returns more properties than FindItem. If more information is required, a client application must perform a FindItem call and then use the item identifiers in a GetItem call to get the properties that are not available in the FindItem call.

    IMP NOTE: Although the Sender property is returned in both FindItem and GetItem calls, only the DisplayName is returned in the FindItem call. DisplayName, EmailAddress, and RoutingType (EmailAddress) are returned by the GetItem call.

    So, here’s sample code snippet to get DisplayName, EmailAddress in C#

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.

     

    //We are making GetItem call using ManagedAPI here after getting the ItemId from FindItem call
     
    EmailMessage message = EmailMessage.Bind(service, myItem.Id ,
     new PropertySet (BasePropertySet.FirstClassProperties , ItemSchema.Attachments));
    MessageBox.Show( message.From.Name + " " + message.From.Address );
    MessageBox.Show( message.ToRecipients.Count.ToString());
    foreach( EmailAddress eAdd in message.ToRecipients )
    {
            MessageBox.Show(eAdd.Name + " " +eAdd.Address);
    }
     
     
    EWS Managed API Rocks!!!
  • Brijs Blogging... Looking Beyond the Obvious

    Delegate Access and Delegate Access Management with Exchange Web Services.

    • 1 Comments

    One of the common request from our customers is to provide interface to work programmatically with Delegate Settings for Outlook.

    Microsoft Exchange Server 2007 Service Pack 1 (SP1) introduces delegate access and delegate access management through Exchange Web Services. The following delegate access functionality is available starting with Exchange 2007 SP1:

    • Delegates can access the mailbox of a principal and perform search, create, delete, update, and copy operations.
    • You can enable delegate access to items based on folder-level permissions that are set by using the delegate management operations.
    • Delegates can create and send meeting messages on behalf of the principal.
    • Delegates can receive meeting messages that are forwarded by the principal and respond to them for the principal.
    • Users who have owner rights on a shared mailbox can open the mailbox and act as the owner.
    • Delegates can create notification subscriptions on folders in the mailbox of the principal.

    Here are the few links related to it:

    And if you would like to do it with ease then try out Exchange Web Services Managed API Beta

    And if you would like to do deep dive about how delegate access works with Outlook then explore it:

    So, there is lot to explore in the Messaging World… Feel free to drop me your question related to Microsoft Messaging APIs

  • Brijs Blogging... Looking Beyond the Obvious

    BUG: "Value does not fall within the expected range." error after installing VSTO 3.0 MSI package

    • 5 Comments

    If you are getting "There was an error during installation. Value does not fall within the expected range." error along with following exception:

    ************** Exception Text **************
    System.ArgumentException: Value does not fall within the expected range.
    at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.GetManifests(TimeSpan timeout)
    at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.InstallAddIn()

    and getting prompt as displayed below:

    VSTO_MSI_ISSUE

    Please make sure that, We are not using special character like "&" in the manufacturer property of the VSTO 3.0 Add-in MSI setup project.

    In the above scenario we have Manufacturer Property value as “ABC & XYZ Inc” and we are getting exception as mentioned above when we start Outlook 2007 after installing add-in.

    We can easily see from the snapshot that VSTO runtime is escaping "&" from the file path.

    However, if we remove “&” from the Manufacturer Property value as “ABC XYZ Inc” add-in get installed and loaded as expected.

    So, We should not use special character in the Manufacturer Property for VSTO 3.0 Add-ins MSI setup to workaround this bug.

  • Brijs Blogging... Looking Beyond the Obvious

    Issue: Getting HTTP 404 error on every request made via Exchange Web Services using EWS HTTP endpoint for Exchange Server 2010

    • 0 Comments

    Few of our customer reported that they are getting HTTP 404 Error reported; when they tries to use EWS HTTP service endpoint for their application for Exchange Server 2010. However, the same application work fine with EWS HTTP service endpoint with Exchange Server 2007 without any issue.

    If we go into Internet Information Services (IIS) on Exchange 2010 RTM and uncheck the box 'Require secure channel (SSL)' on the EWS virtual directory. And then we attempt to make a request using HTTP using EWS service endpoint as “http://host:port/EWS/Exchange.asmx” then we would receive a HTTP 404 Resource Not Found.

    Exchange 2010 Web Services are now based on Windows Communication Foundation (WCF). We receive a HTTP 404 because WCF attempts to locate the endpoint for HTTP but cannot find it and throws a System.ServiceModel.EndpointNotFoundException exception which throws up to the client as a 404 exception.

    Using HTTP instead of HTTPS is not the recommended approach for Exchange Web Services but sometimes it is helpful in debugging/troubleshooting to have this option.

    Here are the steps posted by my colleague Dave @ How to configure a HTTP endpoint for Exchange Web Services in Exchange 2010 to workaround the issue.

  • Brijs Blogging... Looking Beyond the Obvious

    How to set Outlook Folder Description and Folder Homepage URL properties using EWS Managed API?

    • 2 Comments

    One of our customer is trying to update the Folder Description and Folder Homepage URL properties for Outlook 2007/2010 having mailbox on Exchange 2007/2010.

    We could use below mentioned code snippet to set Folder Description property as Extended Property using EWS Managed API.

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.

    <SAMPLE CODE>

    public static ExtendedPropertyDefinition FolderDescription = new ExtendedPropertyDefinition(0x3004, MapiPropertyType.String);


    Folder fl = new Folder(service);
    fl.DisplayName = "Test";
    fl.SetExtendedProperty(FolderDescription, "Blogging Mail Folder");
    fl.Save(WellKnownFolderName.Inbox);

    </SAMPLE CODE>

    image

     

    In order to set Outlook Folder Homepage URL property(as shown in below snapshot) we could refer Henning Krause post @ http://www.infinitec.de/post/2011/10/05/Setting-the-Homepage-of-an-Exchange-folder-using-the-EWS-Managed-API.aspx

    image

    IMP: However, We need to keep in mind that, when we set the Outlook Homepage URL within Outlook it configures the PR_FOLDER_WEBVIEWINFO or http://schemas.microsoft.com/mapi/proptag/0x36DF0102  property. This property is a Binary property and its format is UNDOCUMENTED and hence NOT SUPPORTED by Microsoft. The one thing to note is this it is an unsupported thing to do so make sure we do plenty of testing first.

    Hope this helps!

  • Brijs Blogging... Looking Beyond the Obvious

    How to delete an attendee from Meeting Request using Exchange Web Services?

    • 1 Comments

    In order to remove attendees from an attendee collection, we have to call the UpdateItem Web method for the meeting with the SetItemField change description to include all current members of the attendee array minus those you want removed.

    Please refer to the sample code below which demonstrates:

    • CreateItem (How to create a meeting request)
    • GetItem (How to perform GetItem with additional properties)
    • UpdateItem (How to delete an attendee from the Meeting Request)

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used
    to create and debug procedures.

    using System;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Security;
    using EWSDeleteAnMeetingAttendee.EWSMsgEX07;
    using System.Security.Cryptography.X509Certificates;
     
    namespace EWSDeleteAnMeetingAttendee
    {
        class DeleteAttendee
        {
            private static ExchangeServiceBinding binding = null;
            private static string itemID = "";
            private static string email = "user@domain.com";
     
            static void Main(string[] args)
            {
                // Setup the binding with credentials and URL.
                DeleteAttendee prg = new DeleteAttendee();
     
                binding = new ExchangeServiceBinding();
                //Update UserName, Password, Domain, EWS URL
                binding.Credentials = new NetworkCredential("User", "Password", "domain.com");
                binding.Url = @"https://Server/EWS/Exchange.asmx";
     
                System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                {
                    // Replace this line with code to validate server certificate.
                    return true;
                };
     
                prg.CreateMeetingRequest();
                prg.DeleteMeetingAttendee(email);
            }
     
            public void CreateMeetingRequest()
            {
                //Migrating to Exchange Web Services, Part 2: Calendaring
                //http://msdn.microsoft.com/en-us/library/cc788131.aspx
                // Create the appointment.
                CalendarItemType appointment = new CalendarItemType();
     
                // Set the properties of the appointment.
                appointment.Start = new DateTime(2009, 01, 29, 8, 30, 0, DateTimeKind.Unspecified);
                appointment.StartSpecified = true;
                appointment.End = new DateTime(2009, 01, 29, 9, 30, 0, DateTimeKind.Unspecified);
                appointment.EndSpecified = true;
                appointment.Subject = "New Planning meeting";
                appointment.Location = "Building 007";
                appointment.Body = new BodyType();
                appointment.Body.BodyType1 = BodyTypeType.Text;
                appointment.Body.Value = "This is a Meeting Invite for discussion";
     
                // Add required attendees.
                appointment.RequiredAttendees = new AttendeeType[2];
                appointment.RequiredAttendees[0] = new AttendeeType();
                appointment.RequiredAttendees[0].Mailbox = new EmailAddressType();
                appointment.RequiredAttendees[0].Mailbox.EmailAddress = "User1@domain.com";
     
                appointment.RequiredAttendees[1] = new AttendeeType();
                appointment.RequiredAttendees[1].Mailbox = new EmailAddressType();
                appointment.RequiredAttendees[1].Mailbox.EmailAddress = "User2@domain.com";
     
                // Create the array of items that will contain the appointment.
                NonEmptyArrayOfAllItemsType arrayOfItems = new NonEmptyArrayOfAllItemsType();
                arrayOfItems.Items = new ItemType[1];
     
                // Add the appointment to the array of items.
                arrayOfItems.Items[0] = appointment;
     
                // Create the CreateItem request.
                CreateItemType createRequest = new CreateItemType();
     
                // The SendMeetingInvitations attribute is required for calendar items.
                createRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToAllAndSaveCopy;
                createRequest.SendMeetingInvitationsSpecified = true;
     
                // Add the destination folder to the CreateItem request.
                DistinguishedFolderIdType folder = new DistinguishedFolderIdType();
                folder = new DistinguishedFolderIdType();
                folder.Id = DistinguishedFolderIdNameType.calendar;       
                createRequest.SavedItemFolderId = new TargetFolderIdType();
                createRequest.SavedItemFolderId.Item = folder ;
                
                // Add the items to the CreateItem request.
                createRequest.Items = arrayOfItems;
     
                // Create the appointment by calling the CreateItem method, which has
                // the side effect of sending invitations to attendees.
                CreateItemResponseType createResponse = binding.CreateItem(createRequest);
     
                // Check the result.
                if (createResponse.ResponseMessages.Items[0].ResponseClass !=  ResponseClassType.Success)
                {
                    throw new Exception("Create Meeting failed.");
                }
                
                ItemInfoResponseMessageType iirmt = ((ItemInfoResponseMessageType)createResponse.ResponseMessages.Items[0]);
                if (iirmt.ResponseClass == ResponseClassType.Success)
                {
                    ItemType it = (ItemType)iirmt.Items.Items[0];
                    itemID = it.ItemId.Id;
                }
            }
     
            static CalendarItemType  GetCalItem(string itemIDCal)
            {
                // Create the request.
                GetItemType request = new GetItemType();
     
                // Create the response shape.
                ItemResponseShapeType responseShape = new ItemResponseShapeType();
                responseShape.BodyType = BodyTypeResponseType.Text;
                responseShape.BodyTypeSpecified = true;
                responseShape.BaseShape = DefaultShapeNamesType.Default;
                // Add more properties to the request.
     
                PathToUnindexedFieldType[] attendees = new PathToUnindexedFieldType[1];
                attendees[0] = new PathToUnindexedFieldType();
                attendees[0].FieldURI = UnindexedFieldURIType.calendarRequiredAttendees;
                responseShape.AdditionalProperties = attendees;
                     
                // Add the response shape to the request.
                request.ItemShape = responseShape;
                
                // Identify the items to get.
                ItemIdType[] items = new ItemIdType[1];
                items[0] = new ItemIdType();
                items[0].Id = itemIDCal;
                           
                // Add items to the request.
                request.ItemIds = items;
     
                try
                {
                    // Send the request and get the response.
                    GetItemResponseType resp = binding.GetItem(request);
                    ArrayOfResponseMessagesType aormt = resp.ResponseMessages;
                    ResponseMessageType[] rmta = aormt.Items;
     
                    foreach (ResponseMessageType rmt in rmta)
                    {
                        ItemInfoResponseMessageType iirmt = (rmt as ItemInfoResponseMessageType);
                        ArrayOfRealItemsType aorit = iirmt.Items;
                        ItemType[] myItems = aorit.Items;
                        
                        if (myItems[0] is CalendarItemType)
                        {
                            CalendarItemType calendar = (myItems[0] as CalendarItemType);
                            return calendar;
                        }
                        else
                        {
                            // Check for other item types.
                            return null;
                        }
                    }
                    return null;
                }
                catch (Exception e)
                {
                    throw new Exception("GetItem failed");
                }
            }
     
            public void DeleteMeetingAttendee(string email)
            {
                CalendarItemType cal = GetCalItem(itemID); 
                CalendarItemType newcalendar = new CalendarItemType();
                newcalendar.RequiredAttendees = new AttendeeType[2];
                Int32 oi = 0;
                foreach (AttendeeType oattendee in cal.RequiredAttendees)
                {
                    if (oattendee.Mailbox.EmailAddress != email)
                    {
                        newcalendar.RequiredAttendees[oi] = new AttendeeType();
                        newcalendar.RequiredAttendees[oi].Mailbox = new EmailAddressType();
                        newcalendar.RequiredAttendees[oi].Mailbox.EmailAddress = oattendee.Mailbox.EmailAddress;
                        oi++;
                    }
                }
     
                // Create calendar items to contain each non-deletion update.
                // Add the calendar item and the identified set field to
                // the ItemChangeDescriptionType. This is a SetItemFieldType.
     
                PathToUnindexedFieldType att = new PathToUnindexedFieldType();
                att.FieldURI = UnindexedFieldURIType.calendarRequiredAttendees;
                
                SetItemFieldType set = new SetItemFieldType();
                set.Item = att;
                set.Item1 = newcalendar;
                           
                // Create the identifier of the item to update.
                ItemIdType itemId = new ItemIdType();
                itemId.Id = cal.ItemId.Id ;
                itemId.ChangeKey = cal.ItemId.ChangeKey  ;
     
                // Create and populate the request.
                UpdateItemType request = new UpdateItemType();
                request.ItemChanges = new ItemChangeType[1] { new ItemChangeType() };
                request.ItemChanges[0].Item = itemId;
                request.ItemChanges[0].Updates = new ItemChangeDescriptionType[1];
                request.ItemChanges[0].Updates[0] = set;
                
                request.ConflictResolution = ConflictResolutionType.AutoResolve;
                request.SendMeetingInvitationsOrCancellations = CalendarItemUpdateOperationType.SendToAllAndSaveCopy;
                request.SendMeetingInvitationsOrCancellationsSpecified = true;
     
                // Send the update request and receive the response.
                UpdateItemResponseType response = binding.UpdateItem(request);
                ArrayOfResponseMessagesType aormt = response.ResponseMessages;
                ResponseMessageType[] rmta = aormt.Items;
     
                foreach (ResponseMessageType rmt in rmta)
                {
                    ItemInfoResponseMessageType respMsg = (rmt as ItemInfoResponseMessageType);
                    foreach (ItemType item in respMsg.Items.Items)
                    {
                        Console.WriteLine("Item ID: " + item.ItemId.Id);
                        Console.WriteLine("New change key: " + item.ItemId.ChangeKey);
                        Console.ReadLine();
                    }
                }
            }
        }
    }
      

    Remember, If we try to use a DeleteItemField change description, we would remove all attendees from the collection. Any attendee who is removed from an attendee list as the result of an update will be sent a meeting cancellation (unless the SendMeetingInvitationsOrCancellations value was set to "SendToNone").

    Any attendee who has been removed from all attendee collections, but has not been sent a meeting cancellation, will still have a copy of the meeting on his calendar. The removed attendee may still register a response even after being removed from the attendee list. If that happens, the removed attendee will be re-added to the optional attendees collection on the meeting in the organizer's calendar.

    Best Practices
    As a general rule, we recommend you not to use the combination of a ConflictResolution value of 'AlwaysOverwrite' and a SendMeetingInvitationsOrCancellations value of 'SendToNone' in your calls to the UpdateItem Web method. The combination of these values will result in any removed attendees not receiving a meeting message indicating they have been removed.

    I also recommend you to refer to the following articles:

    EWS Rocks!

  • Brijs Blogging... Looking Beyond the Obvious

    "Condition is not valid" error on Items.Find for Appointment Item using GlobalAppointmentID as filter

    • 1 Comments

    We are getting "Condition is not valid" error on Items.Find for Appointment Item using GlobalAppointmentID as filter.

    We are using the filter as: strFilter = "[GlobalAppointmentID] = 'apptidhere'" and getting following exception:

    runtime error '-2147352567(80020009)'  "Condition is not valid"

    Then we have tried finding the Item using DSAL  query based on Proptag for GlobalAppointmentID  to avoid exception as below:

    strFilter = "@SQL=""http://schemas.microsoft.com/mapi/id/{6ED8DA90-450B-101B-98DA-00AA003F1305}/00030102"" = 'ApptIDHere'"

    but it would NOT return any Item as result because for both Jet and DASL queries, you cannot restrict on a binary property such as EntryID.

    So, Binary properties are NOT SUPPORTED to Find or Restrict Outlook Items.

    However, We can store GlobalAppointmentID in UserDefinedProperty to find item based on it using Find or Restrict as a workaround.

    Here's what I have done in my sample VBA code and able to get Item from Items.Find using Custom Property :

    NOTE: Following programming examples is for illustration only, without warranty either expressed or implied,
    including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose.
    This sample code assumes that you are familiar with the programming language being demonstrated and the tools used
    to create and debug procedures.

       1:  'Creating Apptointment Item with Custom property.
       2:  Sub CreateTestAppointmentWithCustomProp()
       3:      Dim myOlApp As Outlook.Application
       4:      Dim myItem As Outlook.AppointmentItem
       5:      Set myOlApp = CreateObject("Outlook.Application")
       6:      Set myItem = myOlApp.CreateItem(olAppointmentItem)
       7:      myItem.Start = DateAdd("n", 16, Now)
       8:      myItem.End = DateAdd("n", 60, myItem.Start)
       9:      myItem.Subject = "TestAppointment"
      10:      myItem.ItemProperties.Add "GAI", olText, True
      11:      myItem.Save
      12:      myItem.ItemProperties.Item("GAI").Value = myItem.GlobalAppointmentID
      13:      myItem.Save
      14:      myItem.Display
      15:  End Sub
      16:   
      17:  'Finding Item based on Custom Property
      18:  Sub FindItem()
      19:          Dim objOutlook As Outlook.Application
      20:          Set objOutlook = New Outlook.Application
      21:          Dim objNS As Outlook.NameSpace
      22:          Set objNS = objOutlook.Session
      23:          Dim objFolder As Outlook.MAPIFolder
      24:          Set objFolder = objNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar)
      25:          Dim objAppts As Outlook.Items
      26:          Set objAppts = objFolder.Items
      27:          Dim objAppt As Outlook.AppointmentItem
      28:          
      29:          Dim strFilter As String
      30:          strFilter = "@SQL=""http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/GAI"" = 'ApptIDHere'"
      31:       
      32:          Set objAppt = objAppts.Find(strFilter)
      33:          If objAppt Is Nothing Then
      34:              MsgBox ("Nothing Found")
      35:          Else
      36:              MsgBox ("Appt Found")
      37:          End If
      38:  End Sub

    To get property tag of your custom property for your DASL query we can use MFCMAPI available @ http://www.codeplex.com/MFCMAPI.

    I have also referred following articles:

  • Brijs Blogging... Looking Beyond the Obvious

    How to create a Service Account with full access to all mailboxes on Exchange Server 2007 mailboxstore?

    • 0 Comments

    We can use following Exchange PowerShell cmdlet to grant a Service Account full access to all the mailboxes on Exchange Server 2007 mailboxstore, but do so only in accordance with your organization's security and privacy policies:

    Get-mailboxserver <servername> | add-adpermission –user <service account> -accessrights GenericRead, 
    GenericWrite -extendedrights Send-As, Receive-As, ms-Exch-Store-Admin

    We need to modify <servername> as the Exchange Server name and <service account> as the account for which we would like to grant access.

    If you have further questions related to Exchange 2007 Permissions then please refer to
    Exchange 2007 Permissions: Frequently Asked Questions

    And if you writing a custom application using EWS or Exchange Web Services Managed API for Exchange 2007 then you can also have look at nice post @ Exchange Impersonation vs Delegate Access. which explain difference between Exchange Impersonation and  Delegate Access to access an Exchange mailbox using Exchange Web Services.

Page 1 of 4 (78 items) 1234