MOSS 2007 : Get Last Accessed date for a site
I had a recent requirement to find out the last accessed date of the sites in the web applications on the farm. The idea was to find the sites which are rarely used and delete these sites (or archive their data).
By concept I should be able to get this data from the usage analysis data which is kept for each of the objects (Site, list, etc) On researching the involved API’s and the concept I found that the usage data which is available through Object Model has just 30 days of data. Not so good!! What if my last access date was way beyond the last thirty days?
Even if I accept this (Last 30 days of data access allowed by APIs), there is one more caveat on this. Think what would happen to the usage data if your site has been configured to be crawled by your indexer. What would the last accessed date show? You are spot on. The last accessed date property of the SPWeb is updated by the crawler. Darn .. Now how to get the data I want. I even checked the database and found that there is a last accessed date field in webs and this is the same data I got from the property I describe above.
After a bit of discussions with my peers and a lot of research on internet and internal resources I found we could use the FP RPC call on the owssvr.dll to get the usage data. This data is in a Byte Array format. I got the below link for reference but had to do a lot of plumbing to get this to work.
https://msdn.microsoft.com/en-us/library/ms478653.aspx
The method call of interest here is the GetUsageBlog method. After writing the plumbing framework to get the data from the call I was able to get the data. Again I was hit by the caveat of the Crawler updating the last accessed date. To get around this, the byte array data has the data from of accesses from browser. I found that this typically has three values – IE 4.0, IE 6.0 and other. IE 6.0 is understandable as I have windows 2003 server, but what is IE 4.0 doing there? On further research crawler is using this browser to access the site. To get the correct access date find the date for the rest of the browsers.
<Sample code>
static void Main(string[] args)
{
SPSite site = new SPSite("https://serverUrl");
SPWebCollection webColl = site.AllWebs;
foreach(SPWeb web in webColl)
{
UsageBlob blobOld = UsageBlob.GetUsageBlob(web.Url, false, new NetworkCredential("administrator", "Pwd", "Domain"));
UsageBlob blobNew = UsageBlob.GetUsageBlob(web.Url, true, new NetworkCredential("administrator", "Pwd", "Domain"));
DateTime tOld = GetAccessDate(blobOld);
DateTime tNew = GetAccessDate(blobNew);
int i = DateTime.Compare(tNew, tOld);
DateTime retDate = new DateTime();
if (i > 0)
{
retDate = tNew;
}
else
{
retDate = tOld;
}
Console.WriteLine("Web -- " + web.Url + " Last Accessed Date is:" + retDate.ToString());
web.Dispose();
}
site.Dispose();
Console.ReadLine();
}
public static DateTime GetAccessDate(UsageBlob blob)
{
UsageRecordCollection recordColl = blob.Browsers.UsageRecords;
DateTime t = new DateTime();
foreach (UsageRecord rec in recordColl)
{
if (!(rec.Key.ToUpper().Contains("INTERNET EXPLORER 4.01") || rec.Key.ToUpper().Contains("[OTHER]")))
{
if (t == null)
{
t = rec.LastAccessDate;
}
else
{
int i = DateTime.Compare(t, rec.LastAccessDate);
if (i < 0)
{
t = rec.LastAccessDate;
}
}
}
}
return t;
}
</Sample code>
This code would also require the plumbing class library code. I am attaching the plumbing code I have used so this can help you avoid the time and research expended by me :)
Comments
Anonymous
May 31, 2010
Great idea, however I'm having some problems with it on a MOSS publishing site it is saying every site was last accessed the day before. Any ideas?Anonymous
August 20, 2010
I had to change the url constructed in the GetUsageBlob method in the UsageBlob class as it was only getting data for the root web, regardless of the url passed in. Other then that, works great. Great work. Thanks for sharing.Anonymous
August 20, 2010
@matt : You are welcome!!Anonymous
August 25, 2010
hi, iam getting null responce data while with this code, please help me out... is there any dependecy for the GetUsageBolb method.. Please help me : My requirement is : I just need to get the users list for a sharepoint sitecollection with there last login date. Thanks in Advance.Anonymous
September 13, 2010
Hello Varun, Thanks for the information on how to get the last accessed date. Can you give me some details on how you were able to identify that the crawler uses IE4.01 to access the web pages. I also noticed that in the GetAccessDate function, you are looking also eliminating other. Can you share some details on this? Thanks for your helpAnonymous
September 29, 2010
Hello Varun, I am getting response.ContentLength as 0. Can you help me..... what am i missing.Anonymous
October 06, 2010
Varun - I am getting an "Object reference not set to an instance of an object" error when I get to "UsageRecordCollection recordColl = blob.Browsers.UsageRecords;" in the GetAccessDate method...any ideas as to why? Thanks!Anonymous
April 29, 2011
I'm getting the date of the webs within the site . Thats doesn't make sense . Could you pls help me out here . I'm confuse how come all the webs have the same access date . Your response would help us alot thanksAnonymous
June 03, 2011
Any idea how to get the last accessed date for a document in a document libary?Anonymous
August 07, 2011
Hey Matt C. How exactly did you modify the URL? I am trying but every method I try throws and error or returns nothing. Thanks.Anonymous
November 14, 2012
Does this code work for sharepoint 2003?Anonymous
July 01, 2015
Hello Varun, I am getting response.ContentLength as 0. Can you help me, I cann't proceed. Tnx TamiAnonymous
February 04, 2016
I am getting responseContent.Length as 0.Any pointers?