Monday, July 27, 2009

Auditing with the FIM Query Tool

Brad Turner recently received a question from a blog reader:

"I am interested in knowing how can we track/audit which user did a certain change on a user/group account through the ILM portal. Have you written a previous post about this issue? Do you have any information that might help me?"

There are a few ways you could approach this challenge. First, you could find all requests on an object. Here's how you can do that with the FIM Query Tool:

  1. Run the FIM Query Tool and filter for "Request" object types.

  2. Select the following attributes to capture in your audit:
    • Created Time
    • Creator
    • Display Name
    • Operation
    • Request Parameters
    • Target

  3. Change the Reference Format to DisplayName, so that you're not just looking at GUIDs.

  4. Finally, use the following XPath filter:

    /Request[Target = /Person[DisplayName = 'Joe Zamora']]

    To kind of translate this XPath, we're looking for Request objects whose Target matches the following condition: a Person whose display name is "Joe Zamora". In a production scenario, you'd probably want to use the object's GUID to do the search (ObjectId = '12345678-ABCD-1234-ABCD-1234567890AB'), but I use the display name to make it more readable.

One nice feature of the FIM Query Tool is that, because the results are displayed in a data grid view, you can sort results without re-running the query. Just click on a column header to sort by that column.

One additional note on the results set: to see the details of the request, you'll want to pay attention to the RequestParameters attribute. This is where you'll find which attributes were updated and their new values. This is also where the FIM Query Tools falls a bit short. The attribute is stored in XML, and isn't formatted neatly for quick review. There's a good enhancement request!

Now, this query is pretty handy, but if the object has been updated many times, you may find yourself waiting longer than you'd bargained for to see the results of the audit. Brad suggested that we use the XPath historical query functions to narrow the results set down to a certain time window.

So, the second approach is to use the "betweenTime" XPath function to plug in the time window of interest. Try this in the FIM Query Tool with the rest of the settings remaining the same as above:

betweenTime(/Request[Target = /Person[DisplayName = 'Joe Zamora']], '2008-10-31', '2008-12-31')

Voila! Now you see all the users who made updates to the object during your desired time period. Brad also mentioned a few other XPath functions that he and David Lundell presented at TEC 2009:

  • allTime(filter) - Show me the objects that ever satisfied this filter

  • betweenTime(filter, begin datetime, end datetime) - Show me the objects that ever satisfied this filter during the time range specified

  • atTime(filter, datetime) - Show me the object that satisfied the filter at the specified date and time

David builds some good examples here:

Who were payroll admins at the precise moment of the theft?
atTime(/Person[ObjectID = /Group[DisplayName = 'Payroll Admins']/ComputedMember, '2009-02-01T00:00')

Who were the payroll admins in the merry merry month of of May?
betweenTime(/Person[ObjectID = /Group[DisplayName = 'Payroll Admins']/ComputedMember, '2008-05-01T00:00' , '2008-05-31T23:59:59')


  1. Marie-Ange Mhanna KhaterJuly 28, 2009 at 12:49 AM

    This is a great post Joe. Well Done!!
    Thanks for the effort.

  2. Hello Mr. Zamora
    The Fim Query Tool is a very helpful, and I also downloaded the source code in order to get some learn some functions.
    If you may, can you please point out the code portion where u connected to the ilm "2" web service.
    Thank you.

  3. Hi Mazen,

    Thanks for your question. I forgot to mention that I borrowed the PublicResourceManagementClient.dll from our ILM2 activity library ( to connect to the web service.

    The PRMC was first published by Joe Schulman here: We made a few minor changes to it for our activity library.

    The WSEnumerationClient class builds the SOAP messages for Read operations, while the WSTransferClient handles Create, Update, Delete.

    Note that the PRMC for RC0 requires that the ILMSchema.xsd file accompanies the DLL and contains the complete, updated schema. The way it's currently set up, you have to maintain this schema file manually.

    Good luck!

  4. Dear Mr. Zamora
    Since we are talking here about auditing and about the log files... do you and since you are an expert in these things I have a question.
    Is there any way that we could write in the ilm 2 logs?

    Thank you.

  5. Hi Mazen,

    I haven't tried it in RC1, but in RC0 there were public methods for logging to the service log file. Here are my notes on the subject:

    o Microsoft.ResourceManagement.Utilities namespace
    o Public methods for logging to service log file
    o ReportError
    o ReportWarning
    o ReportInformational
    o Be sure to turn on tracing!

    Good luck!

  6. Thank you Mr. Zamora
    God bless you

  7. Dear Mr. Zamora

    I’m sorry that I’m bothering you a lot lately, but I tried to use the LoggingManager and I enabled tracing using one of your older notes, but when I run my program that gets all ws logs with /* Xpath, nothing is shown there, and I used those functions:

    But everything remained as is, so do you have any extra notes about this class (LoggingManager) and how to write to the WS ILM log files? Can you also please give me an example on one of those functions above?

    Thank you.

  8. This comment has been removed by the author.

  9. To be clearer, I want to write in the Audit logs...

  10. In principle, a good happen, support the views of the author

  11. This is such a really cool post; it’s my fortuity to come to see this blog site and getting this awesome blog.

  12. Let's begin by taking a look at the very definition of an audit before we delve into the various types of network audits that are most common in the SMB space.independent auditing services uk