Programmatically rejoin active directory domain after virtual machines snapshot is reverted

There is a problem with active directory computer accounts in combination with virtual machine snapshots. After virtual machine is added into domain computer account’s password gets updated in AD once in a while. In case you are coppying, moving, snapshoting or cloning machine which is joined to a domain you must have domain membership problems on those machines very often. It happens if password which is storred on your virtual machine and password on the account object in AD are out of sync. There are some administrative ways to fix that.

For example:

a) changing computer account password configuration policies in AD,

b) rejoining the domain by hand everytime domain membership is broken,

c) snapshoting not only virtual machine but Domain controller and restoring both snapshots in one atomic action

After I become tired of fixing those issues manually I decided to search for programmatic way to join the domain.

I wrote c#.net console application which is able to identify if the machine has broken domain membership and if it has it is able to fix it.

You can download the msi file here.

https://i0.wp.com/are.ehibou.com/wp-content/plugins/downloads-manager/img/icons/default.gif?w=525 download: FixDomainMembership.msi (450.5KB)
added: 22/05/2012
clicks: 577
description: Command Line Utility to fix domain membership

After the executable is installed on the machine with broken domain membership execute the command with command line parameter –help and follow the manual …

Funny regular expression experience

I was working on a regex to check if all the symbols in the string are from the range of allowed ones.

My initial regex, which  was working was:

^[a-zA-Z0-9_-]*$

Later I decided to allow spaces and dots and wrote a new regex:

^[a-zA-Z0-9_-\. ]*$

This one was not working! I’ve spent quite a time until I figured out that the peace “_-\.” was treated the same way as “a-z”. It assumed I am providing a scope. My issue was fixed after I escaped “-” and my final regex looked like this:

^[a-zA-Z0-9_\-\. ]*$

c# .net code snippet to cache xslt objects

XslCompiledTransform class is used to perform xslt transformation. Construction of the instance of the object of this type takes some time as it has to load, parse and compile xslt file and all the includes. You have to think about caching of the XslCompiledTransform object instance if your application uses xslt transformation based on the same xslt file more than once.

var xslFilePath = "path\\to\\your\\xsl\\file";
ObjectCache cache = MemoryCache.Default; // I used MemoryCache - there are more possibilities
//Check if there is something in the cache. Cache key is xslt file path
var xsl = cache[xslFilePath] as XslCompiledTransform;
if (xsl == null)
{
// If nothing construct the XslCompiledTransform objects instance and cache it
xsl = new XslCompiledTransform();
var xsltSettings = new XsltSettings(false, true);
xsl.Load(xslFilePath, xsltSettings, new XmlUrlResolver());
var policy = new CacheItemPolicy();
List paths = null;
// retrieve all the dependent file paths
ConstructCacheItemPolicy(xslFilePath,ref paths);
policy.ChangeMonitors.Add(new HostFileChangeMonitor(paths));
cache.Set(xslFilePath,xsl,policy);
}
var ms = new MemoryStream();
xsl.Transform(xInput, null, ms);
ms.Position = 0;
var result = ms;

A function to collect all the dependent xslt includes for the cache dependency

private static void ConstructCacheItemPolicy(string xslFilePath, ref List paths )
{
// Add current xslt file path into our result set
if (paths == null) paths = new List();
if (!paths.Contains(xslFilePath)) paths.Add(xslFilePath);
var xmlDocument=new XmlDocument();
// load xslt file into XmlDocument
xmlDocument.Load(xslFilePath);
// Take care of xml namespaces
var xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
xmlNamespaceManager.AddNamespace("xsl","http://www.w3.org/1999/XSL/Transform");
// Select includes
var xNL = xmlDocument.SelectNodes("//xsl:include",xmlNamespaceManager);
if (xNL != null)
// iterated through the includes and perform recursive iterations to collect everything what is in scope
foreach (XmlElement xE in xNL)
{
var pathRoot = Path.GetDirectoryName(xslFilePath);
if (pathRoot != null)
{
var xslIncludeFilePath = Path.Combine(pathRoot, xE.GetAttribute("href"));
ConstructCacheItemPolicy(xslIncludeFilePath, ref paths);
}
}
}