Hobby Chef
THIS IS A DRAFT DOCUMENT AND MAY CHANGE WITHOUT PRIOR NOTICE.
PURPOSE: Collect ETL trace from Exchange Server 2007 & 2010 to troubleshoot Exchange Web Services related issues.
Applies to: Microsoft® Exchange Server© 2007 & 2010
Steps
1) Go to CAS Server and fire up Extra.exe (%PROGRAMFILES%\Microsoft\Exchange Server\Bin\ExTRA.exe) 2) This will bring the following window, click on ‘Select a task’
3) Click on “Trace Control”
4) Configure the trace options, file location, maximum file size (100-200mb should be enough for normal scenarios) 5) Select sequential logging, and run traces for a time period in which you should be able to reproduce the issue. Usually 300 seconds are good enough to switch over and reproduce the error. 6) Click “Set components and tags for the type of tracing selected” 7) Type of tracing will be “6. OWA Tracing”
8) Under trace types, select all of them to get a verbose log 9) Under components, OWA will be selected by default – you might want to uncheck that as it will add logs for OWA traffic as well 10) Choose trace components according to your problem, in basic scenarios and EWS issues MSExchangeWebServices should be sufficient. 11) These are the providers which looks good to get a detailed log and uncovering the hidden issues somewhere in the communication. a. ADProvider b. ADRecipientCache c. ADExpansion d. AuthenticationProvider e. Common f. Diagnostics g. MSExchangeWebServices h. NetworkingLayer 12) Once done, hit Start tracing
13) It will run the trace for the specified duration, keep it running and reproduce the problem
14) Once done it will generate a binary file (.ETL) which contains all the proprietary & confidential debugging information related to the product.
15) Take instructions from the Microsoft Support Professional on how to send the file back to him/her.
DISCLAIMER: THE STEPS BELOW CAN IMPACT THE PERFORMANCE OF THE EXCHANGE SERVER AND MUST BE PERFORMED IN GUADIANCE OF MICROSOFT SUPPORT PROFESSIONAL. IN NO EVENT SHALL MICROSOFT, ITS AUTHORS, OR ANYONE ELSE INVOLVED IN THE CREATION, PRODUCTION, OR DELIVERY OF THE DOCUMENT BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE DOCUMENTATION, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
This happened to be a second recent case among many others facing the similar issue, and they could not update an existing contact using EWS Managed API.
I got this customer, like all others complaining that they cannot set the contact’s Physical Address to a blank value. The same contact can be updated using EWS SOAP API but not with managed API… hmm… I knew the answer already
Error Message: The request failed schema validation: The element 'Updates' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types' has incomplete content. List of possible elements expected: 'AppendToItemField, SetItemField, DeleteItemField' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.
Here is the code which was causing the trouble
static void UpdateContact(ExchangeService svc,ItemId id)
{
Contact myContact = Contact.Bind(svc, id);
PhysicalAddressEntry paEntryHome = null;
PhysicalAddressEntry paEntryBusiness = null;
paEntryHome = new PhysicalAddressEntry();
paEntryHome.Street = "";
paEntryHome.City = "";
paEntryHome.PostalCode = "";
paEntryHome.State = "";
paEntryHome.CountryOrRegion = "";
paEntryBusiness = new PhysicalAddressEntry();
paEntryBusiness.Street = "";
paEntryBusiness.City = "";
paEntryBusiness.PostalCode = "";
paEntryBusiness.State = "";
paEntryBusiness.CountryOrRegion = "";
myContact.PhysicalAddresses[PhysicalAddressKey.Home] = paEntryHome;
myContact.PhysicalAddresses[PhysicalAddressKey.Business] = paEntryBusiness;
try
myContact.Update(ConflictResolutionMode.AlwaysOverwrite);
}
catch(Exception e)
Console.WriteLine(e.ToString());
So what was the trouble in the code, it look pretty neat.. huh? Not exactly. You are creating a new instance of PhysicalAddressEntry instead of using the existing object given by Managed API..
Only, few lines of code change and it started to work like charm.. here is the working code for the same.
paEntryHome = myContact.PhysicalAddresses[PhysicalAddressKey.Home];
paEntryBusiness = myContact.PhysicalAddresses[PhysicalAddressKey.Business];
Hope this helps you all.
Happy coding / debugging!!!
So I got this friend of mine who works for MS IT and was curious to find Outlook’s install location programmatically irrespective of 32/64 bit installation of OS or Outlook.
First thought was registry, but that gets little messy.. you go to HKCR & then parse through it to find the location of Outlook.exe… I didn’t like that much, and that was not sure shot way… I could delete the Outlook.exe and it will still point me to the same path. You might ask why would someone delete the Outlook.exe and leaving other registry entries? My answer is because you can and then the registry solution will break.
So why not ask the Outlook itself where are you buddy? Nice, you would say, if only he can speak… yes he can!!! Here is how its done in C#
I am using Reflection to create an object to Outlook.Application. You can use this to create an object of any COM Object though. Whenever you create the object to a COM server inside EXE, its EXE is launched if not running already. So all you need to do is use System.Diagnostics.Process class to get its Process Path.
using System; using System.Reflection; using System.Diagnostics; namespace OutlookLocationFinder { class Program { static void Main(string[] args) { System.Type objType = null; object comObject = null; string version = string.Empty; Process[] p = null; try { // Create an object to Outlook.Application , replace with your COM Server's ProgID objType = System.Type.GetTypeFromProgID("Outlook.Application"); // Activate the object comObject = System.Activator.CreateInstance(objType); // This is Outlook specific, I am calling the member property to get the version of Outlook version = (string)objType.InvokeMember("Version", BindingFlags.InvokeMethod, null, comObject, null); } catch { Console.Write("Unable to create the object of type \"Outlook.Application\""); } // Whenever you create the object to a COM server inside EXE, its EXE is launched if not running already // Now, just get hold of the Process by its name p = Process.GetProcessesByName("Outlook"); // Beware there could be multiple instances running of the same application, we just care about first one. if (null != p && p.Length > 0) Console.WriteLine("Outlook ({0}) is launched from: {1}", version, p[0].MainModule.FileName); else Console.WriteLine("Outlook does not seem to be installed properly on this machine, could not find process running on local machine"); Console.Write("Press any key to exit."); Console.ReadKey(false); } } }
Happy Coding / Debugging !!!