<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1847802855466380543</id><updated>2012-02-16T20:26:04.822-08:00</updated><category term='C#'/><category term='log4net'/><category term='Linq'/><category term='Active Directory'/><category term='WSS'/><category term='Sharepoint'/><title type='text'>Codedump</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1847802855466380543.post-3108869012897700640</id><published>2009-09-21T06:30:00.001-07:00</published><updated>2009-09-21T06:40:32.888-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Update static event handlers in WSS 3.0</title><content type='html'>I had a little problem the other day where I was creating a new version of a product we have in my company. We were going from version 1.0 to 1.1 and we had been selling the product to quite a few companies.



The problem was that the strong name key had changed so that I couldn't do &lt;assemblyredirect&gt;in web.config in order for us to point to the new .dll



Overall this wasn't a problem unless in Event Handlers on lists, these handlers are statically stored in the configuration database. Therefore I had to go through each list and update the handlers.



I wasn't going to do that by hand for all our customers, so I created a simple console app that does this for me. You only need to send in the url of the site to update as a command argument



&lt;pre class="brush: js"&gt;
class Program
    {
        #region Log4Net
        /// &lt;summary&gt;
        /// Static logger for the class
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// Uses reflection to find the class type and can therefore be copied without change for use in other classes.
        /// &lt;/remarks&gt;
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        #endregion
             
        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();
            SPSite site = null;
            try
            {
                site = new SPSite(args[0]);
                logger.Info(string.Format("Site opened - Url: {0}", site.Url));
                foreach (SPWeb web in site.AllWebs)
                {
                    logger.Info(string.Format("Web opened - Url: {0}", web.Url));
                    for (int l = web.Lists.Count - 1; l &gt;= 0; l--)
                    {
                        SPList list = web.Lists[l];
                        logger.Info(string.Format("List opened - Title: {0}", list.Title));
                        for (int e = list.EventReceivers.Count - 1; e &gt;= 0; e--)
                        {
                            SPEventReceiverDefinition eventReceiver = list.EventReceivers[e];
                            logger.Info(string.Format("Checking eventReceiver - Id: {0}", eventReceiver.Id));
                            if (eventReceiver.Assembly.StartsWith("{Old assembly full name}"))
                            {
                                logger.Debug(string.Format("Event receiver matches assembly name - Assembly: {0}", eventReceiver.Assembly));
                                eventReceiver.Assembly = "{New assembly full name}";
                                eventReceiver.Update();
                                logger.Info("Event receiver updated");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error("An error occurred", ex);
                Console.WriteLine("There was an error while updating event receivers");
            }
            finally
            {
                if (site != null)
                {
                    site.Dispose();
                }
            }
        }
&lt;/pre&gt;

You need to add assembly reference to Microsoft.Sharepoint.dll (WSS 3.0) and log4net (Version 1.2.10.0)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1847802855466380543-3108869012897700640?l=khlavkalashcode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/3108869012897700640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/09/update-static-event-handlers-in-wss.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/3108869012897700640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/3108869012897700640'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/09/update-static-event-handlers-in-wss.html' title='Update static event handlers in WSS 3.0'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1847802855466380543.post-7262182147290126735</id><published>2009-09-18T08:22:00.000-07:00</published><updated>2009-09-21T06:22:12.511-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Parsing keyword data from html string</title><content type='html'>I created this simple console app which opens a list of urls from a file, opens up the web page, strips the html and finds text following a specified keyword. An optional argument can be provided to show only a substring of the resulting text which can be helpful if the user is searching for a predefined info, e.g. MAC address

The input file is in the following format 

&lt;pre class="brush: js"&gt;
http://10.199.200.54
http://10.199.200.18
&lt;/pre&gt;

The code for the application is the following
&lt;pre class="brush: js"&gt;
static void Main(string[] args)
        {
            string ipSetPlain = string.Empty;
            string filePath = args[0].ToString();
            string itemToSearchFor = args[1].ToString().Trim();
            int resultStringLength = -1;

            if (args.Length &gt; 2)
            {
                 resultStringLength = Convert.ToInt32(args[2]);
            }

            using (StreamReader sr = new StreamReader(filePath))
            {
                ipSetPlain = sr.ReadToEnd();
            }

            string[] ipSetDelimiterChars = {"\r\n" };
            foreach (string ip in ipSetPlain.Split(ipSetDelimiterChars, StringSplitOptions.RemoveEmptyEntries))
            {
                string requestHtml = string.Empty;
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(ip);
                WebResponse response = GetWebResponse(webRequest);

                if (response != null)
                {
                    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                    {
                        requestHtml = sr.ReadToEnd();
                    }

                    string strippedString = Regex.Replace(requestHtml, "&lt;.*?&gt;", string.Empty); //replace all HTML tags
                    strippedString = strippedString.Replace("\n", string.Empty);
                    string[] strippedStringDelimeterChars = { "\t" };
                    foreach (string info in strippedString.Split(strippedStringDelimeterChars, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string infoTrimmed = info.Trim();
                        if (!infoTrimmed.Equals(string.Empty) &amp;&amp; infoTrimmed.Contains(itemToSearchFor))
                        {
                            string data = string.Empty;

                            if (resultStringLength &gt;= 0)
                            {
                                data = infoTrimmed.Substring(infoTrimmed.IndexOf(itemToSearchFor) + itemToSearchFor.Length, resultStringLength);
                            }
                            else
                            {
                                data = infoTrimmed.Substring(infoTrimmed.IndexOf(itemToSearchFor) + itemToSearchFor.Length);
                            }
                            Console.WriteLine(ip + "\t" + data);
                        }
                    }
                }
                else
                {
                    Console.WriteLine(ip + "\t" + "Could not be resolved");
                }
            }
            Console.ReadLine();
        }

        private static WebResponse GetWebResponse(HttpWebRequest request)
        {
            try 
            {  
                return request.GetResponse();
            }
            catch //If exception thrown then couldn't get response from address
            {  
                return null;
            } 
        }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1847802855466380543-7262182147290126735?l=khlavkalashcode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/7262182147290126735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/09/parsing-keyword-data-from-html-string.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/7262182147290126735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/7262182147290126735'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/09/parsing-keyword-data-from-html-string.html' title='Parsing keyword data from html string'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1847802855466380543.post-6886906483996413914</id><published>2009-09-09T03:30:00.000-07:00</published><updated>2009-09-09T03:37:59.826-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='log4net'/><title type='text'>Web page to view log4net file</title><content type='html'>Here is a simple web page I created to fetch log4net files from the server. This file should be included in the web application so that people don't have to contact IT operation departments to get log files.

I kept the HTML site as it is created by default with the exception that I added a style into the title tag
&lt;pre class="brush: js"&gt;
    &lt;style type="text/css"&gt;
       BODY {
       font-family:Lucida Console;
       font-size:12px }
    &lt;/style&gt;
&lt;/pre&gt;

Then this is the code-behind class for the page
&lt;pre class="brush: js"&gt;
public partial class LogOutput : System.Web.UI.Page
    {
        #region Log4Net
        /// &lt;summary&gt;
        /// Static logger for the class
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// Uses reflection to find the class type and can therefore be copied without change for use in other classes.
        /// &lt;/remarks&gt;
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        #endregion
                 
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                string appenderIndexParamName = "appenderIndex";
                string filePostfixParamName = "filePostfix";
                string outputTypeParamName = "outputType";

                Response.Write(string.Format("Log file parameter {0} signal log FileAppender index
", appenderIndexParamName));
                Response.Write(string.Format("Log file parameter {0} to fetch file with specified log name postfix
", filePostfixParamName));
                Response.Write(string.Format("Log file parameter {0} to fetch file using different output method, e.g. set as 1 to get text file
", outputTypeParamName));
                Response.Write("

");

                int appenderIndex = Request.Params[appenderIndexParamName] == null ? 0 : Convert.ToInt32(Request.Params[appenderIndexParamName]);
                string filePostfix = Request.Params[filePostfixParamName] == null ? string.Empty : Request.Params[filePostfixParamName];
                int outputType = Request.Params[outputTypeParamName] == null ? 0 : Convert.ToInt32(Request.Params[outputTypeParamName]);

                FileAppender fileAppender = (FileAppender)((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Appenders[appenderIndex];
                string filename = fileAppender.File + filePostfix;

                if (outputType == 0) //Text output
                {
                    using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        using (StreamReader streamReader = new StreamReader(fileStream))
                        {
                            String line;
                            while ((line = streamReader.ReadLine()) != null)
                            {
                                Response.Write(line + "
");
                            }
                        }
                    }
                }
                else if (outputType == 1) //Ttext file output
                {
                    Response.ContentType = "text/plain";
                    Response.Clear();
                    Response.AddHeader("Content-Disposition", "attachment;filename=log.txt");
                    using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        byte[] fileContent = null;
                        using (BinaryReader br = new BinaryReader(fileStream))
                        {
                            long numBytes = fileStream.Length;
                            fileContent = br.ReadBytes((int)numBytes);
                            if (fileContent.Length &gt; 0)
                            {
                                Response.BinaryWrite(fileContent);
                            }
                        }
                    }
                    Response.End(); //So that the client won't output the page HTML in the returned file
                }
            }
            catch (Exception ex)
            {
                Response.Clear();
                Response.Write("Could not get log file information

");
                Response.Write(ex.Message + " " + ex.StackTrace);
            }
        }
    }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1847802855466380543-6886906483996413914?l=khlavkalashcode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/6886906483996413914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/09/web-page-to-view-log4net-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/6886906483996413914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/6886906483996413914'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/09/web-page-to-view-log4net-file.html' title='Web page to view log4net file'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1847802855466380543.post-8674821266473898536</id><published>2009-08-29T15:33:00.000-07:00</published><updated>2009-09-02T04:47:06.921-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Localizing enum</title><content type='html'>I've always been thinking about properly localizing enum values in some elegant way. I finally found some time doing that with the following code :)

Started by creating my own Localizing attribute

&lt;pre class="brush: js"&gt;
/// &lt;summary&gt;
/// Attribute used for localization. Description field should contain a reference to the Resource file for correct localization
/// &lt;/summary&gt;
public class LocalizationAttribute : Attribute
{
    public LocalizationAttribute(string description)
    {
        this._description = description;
    }

    private string _description;
    /// &lt;summary&gt;
    /// Used to reference a resource key
    /// &lt;/summary&gt;
    public string Description
    {
        get
        {
            return this._description;
        }
    }
}
&lt;/pre&gt;



From there I create the enum itself

&lt;pre class="brush: js"&gt;
[TypeConverter(typeof(EnumToLocalizedString))]
public enum ReviewReason
{
    [LocalizationAttribute("ReviewReasonNewDocument")]
    NewDocument = 1,

    [LocalizationAttribute("ReviewReasonInternalAudit")]
    InternalAudit = 2,

    [LocalizationAttribute("ReviewReasonExternalAudit")]
    ExternalAudit = 3,

    [LocalizationAttribute("ReviewReasonChangedWorkBehaviour")]
    ChangedWorkBehaviour = 4,

    [LocalizationAttribute("ReviewReasonChangedWorkBehaviourBecauseOfComplaints")]
    ChangedWorkBehaviourBecauseOfComplaints = 5,

    [LocalizationAttribute("ReviewReasonMovedFromOlderSystem")]
    MovedFromOlderSystem = 6,

    [LocalizationAttribute("ReviewReasonPeriodicUpdate")]
    PeriodicUpdate = 7,

    [LocalizationAttribute("ReviewReasonDocumentChanged")]
    DocumentChanged = 8
}
&lt;/pre&gt;

Then I created a type converter which will fetch the LocalizationAttribute description key and access the Resource file to get the localization (Attribute description must match the resource key :))


&lt;pre class="brush: js"&gt;
public class EnumToLocalizedString : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return (sourceType.Equals(typeof(Enum)));
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return (destinationType.Equals(typeof(String)));
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (!destinationType.Equals(typeof(String)))
            {
                throw new ArgumentException("Can only convert to string.", "destinationType");
            }
            if (!value.GetType().BaseType.Equals(typeof(Enum)))
            {
                throw new ArgumentException("Can only convert an instance of enum.", "value");
            }
           
            string name = value.ToString();
            object[] attrs = value.GetType().GetField(name).GetCustomAttributes(typeof(LocalizationAttribute), false);
            if (attrs.Length != 1  !(attrs[0] is LocalizationAttribute))
            {
                throw new ArgumentException("Invalid enum argument");
            }
            return Handbok.Code.Resources.handbok.ResourceManager.GetString(((LocalizationAttribute)attrs[0]).Description);
        }
    }
&lt;/pre&gt;








Finally I created the client which uses the TypeConverter, which in this case is a collection

&lt;pre class="brush: js"&gt;
public class ReviewReasonCollection
{
    private static Collection&lt;keyvaluepair&lt;reviewreason,&gt;&gt; _reviewReasons;

    public static Collection&lt;keyvaluepair&lt;reviewreason,&gt;&gt; AllReviewReasons
    {
        get
        {
            if (_reviewReasons == null)
            {
                _reviewReasons = new Collection&lt;keyvaluepair&lt;reviewreason,&gt;&gt;();
                TypeConverter t = TypeDescriptor.GetConverter(typeof(ReviewReason));

                foreach (ReviewReason reviewReason in Enum.GetValues(typeof(ReviewReason)))
                {
                    _reviewReasons.Add(new KeyValuePair&lt;reviewreason,&gt;(reviewReason, t.ConvertToString(reviewReason)));
                }
            }
            return _reviewReasons;
        }
    }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1847802855466380543-8674821266473898536?l=khlavkalashcode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/8674821266473898536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/08/localizing-enum.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/8674821266473898536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/8674821266473898536'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/08/localizing-enum.html' title='Localizing enum'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1847802855466380543.post-7123608238067758386</id><published>2009-05-22T03:59:00.000-07:00</published><updated>2009-05-22T04:14:13.835-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>Filter Collections with Linq</title><content type='html'>I've always been really angry with C# for the lack of support with Collections and Lists. This was especially true in cases I had to filter the collection according to some criteria, e.g. Count on items of specific type.

Before I always had to do an annoying foreach loop (or encapsulate this myself in some common method). 

But now I've discovered the power of linq that has changed how I code around these structure

The following code gives me the number of WorkItems of the type Scenario
&lt;pre class="brush: js"&gt;
int count = _linkedWorkItems.Count((WorkItem w) =&gt; w.Type.Equals("Scenario"));
&lt;/pre&gt;

The following code is the same except returns a List
&lt;pre class="brush: js"&gt;
List&lt;WorkItem&gt; _linkedScenarioWorkItems = _linkedWorkItems.Where((WorkItem w) =&gt; w.Type.Name.Equals("Scenario")).ToList(); 
&lt;/pre&gt;

This of course is just a small example of how Linq can help you in your programming. &lt;a href="http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx"&gt;Here &lt;/a&gt; are more Linq sample to give you a thought of how powerful this can really be&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1847802855466380543-7123608238067758386?l=khlavkalashcode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/7123608238067758386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/05/filter-collections-with-linq.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/7123608238067758386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/7123608238067758386'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/05/filter-collections-with-linq.html' title='Filter Collections with Linq'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1847802855466380543.post-5327582691206366365</id><published>2009-04-29T07:19:00.000-07:00</published><updated>2009-05-22T04:14:30.384-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Active Directory'/><title type='text'>Find users in Active Directory folder using GUID</title><content type='html'>&lt;span style="font-size:85%;"&gt;I was recently asked to create a simple utility that fetches all users from a given organizational unit in Active Directory (This was really a part of a bigger project but that's another story). The problem was that the name of the organizational unit keeps getting changed (changed 3 times this year because of company merges and stuff like that).

That means I couldn't do my normal ldap query
-&gt; LDAP://&lt;domain&gt;/User,OU=Software,DC=DEVTEST,DC=local

because after some time the Software OU would be something else and everything would fail.

Because of that I had the idea to fetch by using the object Guid which means that my program really wouldn't care if the Software OU name changed

In order to accomplish that I wrote 2 small console applications to do a proof-of-concept.

&lt;span&gt;
The first code is to fetch the GUID of all the organization unit in the Active Directory tree
&lt;/span&gt;

&lt;/span&gt;&lt;span style="font-size:85%;"&gt;
&lt;pre class="brush: js"&gt;DirectoryEntry entry = new DirectoryEntry("LDAP://domaincontroller", @"domain\user", "password");
entry.AuthenticationType = AuthenticationTypes.Delegation;

DirectorySearcher ds = new DirectorySearcher(entry);
//ds.Filter = "(objectClass=container)";
ds.Filter = "(objectClass=organizationalUnit)";
ds.SearchScope = SearchScope.Subtree;
ds.ServerTimeLimit = TimeSpan.FromSeconds(60);

SearchResultCollection results = ds.FindAll();

Console.WriteLine(String.Format("Found {0} results", results.Count));
foreach (SearchResult result in results)
{
   DirectoryEntry directoryEntry = result.GetDirectoryEntry();
   Console.WriteLine(String.Format("Name: {0} - GUID: {1}", directoryEntry.Name, directoryEntry.Guid));
}
Console.ReadLine();
&lt;/pre&gt;&lt;/span&gt;


&lt;span style="font-size:85%;"&gt;The second code is to fetch all the users that reside in the organization unit (and sub units) with a specified GUID



&lt;/span&gt;&lt;/span&gt;
&lt;span style="font-size:85%;"&gt;&lt;pre class="brush: js"&gt;DirectoryEntry entry = new DirectoryEntry("LDAP://domaincontroller/&lt;guid=d552c570-6ede-4f7c-9618-25d536d2bfad&gt;", @"domain\username", "password"); //Software organizational unit

entry.AuthenticationType = AuthenticationTypes.Delegation;

DirectorySearcher ds = new DirectorySearcher(entry);
ds.Filter = "(objectClass=user)";
ds.SearchScope = SearchScope.Subtree;
ds.ServerTimeLimit = TimeSpan.FromSeconds(60);

//Load the properties that you need
ds.PropertiesToLoad.Add("Name"); //The name of the user
ds.PropertiesToLoad.Add("SAMAccountName"); //Logon name

SearchResultCollection results = ds.FindAll();

Console.WriteLine(String.Format("Found {0} users", results.Count));
foreach (SearchResult result in results)
{
   if (result.GetDirectoryEntry().Properties["Name"].Value != null)
   {
      //Do something with the result
     Console.WriteLine(result.GetDirectoryEntry().Properties["Name"].Value.ToString() + " - " + result.GetDirectoryEntry().Path.ToString());
   }
}
Console.ReadLine();
&lt;/pre&gt;&lt;/span&gt;


&lt;span style="font-size:85%;"&gt;This works and I've been changing the OU name without affecting the final results.


&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1847802855466380543-5327582691206366365?l=khlavkalashcode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://khlavkalashcode.blogspot.com/feeds/5327582691206366365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/04/find-users-in-active-directory-folder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/5327582691206366365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1847802855466380543/posts/default/5327582691206366365'/><link rel='alternate' type='text/html' href='http://khlavkalashcode.blogspot.com/2009/04/find-users-in-active-directory-folder.html' title='Find users in Active Directory folder using GUID'/><author><name>Khlav Kalash</name><uri>http://www.blogger.com/profile/03045935622582677459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
