Thursday, January 13, 2011

WMI Scripts + BizTalk

Recently, I moved into new BizTalk assigment and I was very happy but my happiness shattered completely as the Architecture was completely screwed up (I apologies, being 4+ yrs of exp, I don't hold qualification to comment anything on architecture but personall speaking it was screwed up :( ).

It was something like integrating 16 messages and without using any percentage of brain, people have created 16 orchestrations and that to in 16 different BizTalk projects. uff.. this made me remember my first year of career when I used to do POCs and its giving me the feeling they as well doing POCs and then moving their POCs to UAT server and finally to test server.

But truly speaking, they have a valid reason i.e. "Time constraint" so they haven't wasted single second for investigation and finally it ended-up in 12-14 hrs daily in office, effort shoot up by 200+%.

And this is not enough, to add further happiness I got the wonderful surprise on the next day itself, that the other guy is moving out and I have to carry forward the remaining development and production deployment. Soon I realized deployment will going to be real pain in a$$.



I left with 2 options: first resigning from the company, secondly to do something that will largely help me, I am not much worried for anything else.


So, I thought of doing deployment programatically i.e. using WMI.
Following are the task, I am going to achieve by deployment application:
1. Creating Host (3 Host)
2. Creating Host Instance (3 Host Instance)
3. Adding Send Handler (for 4 Adapters)
4. Adding Receive Handler (for 3 Adapters)
5. Creating BizTalk Application (4 New applications)
6. Adding Reference to applications (few numbers)
7. Installing BizTalk Assemblies (16+)
8. Loading Binding files (16+)
9. Few more minor activities.

Frankly speaking, If I have to do these many task I would rather prefer to quit my job and look for the new one.

The day I have finished my the coding for deployment, I cried tears of joy :)

WMI Application extensively uses:
System.Management namespace

So keeping this Bullshit aside let go straight to the code :

public partial class HostingTask
{
#region CONSTANTS
private const string WMI_Root = @"root\MicrosoftBizTalkServer";
private const string MSBTS_HostSetting = "MSBTS_HostSetting";
private const string MSBTS_ServerHost = "MSBTS_ServerHost";
private const string MSBTS_HostInstance = "MSBTS_HostInstance";
private const string MSBTS_AdapterSetting = "MSBTS_AdapterSetting";
private const string MSBTS_ReceiveHandler = "MSBTS_ReceiveHandler";
private const string MSBTS_SendHandler2 = "MSBTS_SendHandler2";
#endregion

private ManagementClass mgmtClass;
private ManagementObject mgmtObj;

#region AddHost Method :- This Method creates a Logical host in BizTalk Group
public void AddHost(BTHost host)
{
try
{

Console.WriteLine("Creating Host - " + host.HostName);
PutOptions options = new PutOptions();
options.Type = PutType.CreateOnly;
//create a ManagementClass object and spawn a ManagementObject instance
mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostSetting, null);
if (!Exists(mgmtClass, "Name", host.HostName))
{
mgmtObj = mgmtClass.CreateInstance();
//set the properties for the Managementobject
mgmtObj["Name"] = host.HostName;
mgmtObj["HostType"] = host.HostType;
mgmtObj["NTGroupName"] = host.NTGroupName;
mgmtObj["AuthTrusted"] = host.AuthenticationTrusted;
mgmtObj["HostTracking"] = host.AllowHostTracking;
//create Host
mgmtObj.Put(options);
Console.WriteLine("Host - " + host.HostName + " - has been created successfully");
}
else
{
Console.WriteLine("BOSS.. Host - " + host.HostName + " - already in place.. why the hell you are wasting my time.");
}
}
catch (Exception ex){
Console.WriteLine("CreateHost - " + host.HostName + " - failed. I do expect people to do some part of his/her job. Anyway following is the exception message : " + ex);
throw;
}

}
#endregion


#region RemoveHost Method :- This Method Deletes a logical host from BizTalk Group
public void RemoveHost(string hostName)
{
try{
Console.WriteLine("Removing Host : " + hostName);
mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostSetting, null);
if (Exists(mgmtClass, "Name", hostName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj["Name"] = hostName;
mgmtObj.Delete();
Console.WriteLine(hostName + "Host removed successfully");
}
else
{
}
}
catch {
throw;
}
}
#endregion


#region AddHostInstance :- This Method created the Host Instance on the physical server
public void AddHostInstance(BTHostInstance hostIns, string hostName)
{
try
{
if (hostIns.Server == null hostIns.Server == string.Empty)
{
hostIns.Server = Environment.MachineName;
}
Console.WriteLine("Creating Host Instance : " + hostName + "on Server : " + hostIns.Server);
//Creating instance of BizTalk Host.
mgmtClass = new ManagementClass(WMI_Root, MSBTS_ServerHost, null);
mgmtObj = mgmtClass.CreateInstance();
mgmtObj["ServerName"] = hostIns.Server;
mgmtObj["HostName"] = hostName;
//Map HostInstance to be created with the Host
mgmtObj.InvokeMethod("Map", null);
mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostInstance, null);
mgmtObj = mgmtClass.CreateInstance();
mgmtObj["Name"] = "Microsoft BizTalk Server " + hostName + " " + hostIns.Server;
object[] objparams = new object[3];
objparams[0] = hostIns.Logon.Username;
objparams[1] = hostIns.Logon.Password;
objparams[2] = true;
//Create Host Instance
mgmtObj.InvokeMethod("Install", objparams);

Console.WriteLine("Host Instance " + mgmtObj["Name"] + " created.");
}
catch{
throw;
}
}
#endregion


#region RemoveHostInstance Method :- This Method deletes a Host Instance from the server and BizTalk Group
public void RemoveHostInstance(BTHostInstance hostIns, string hostName)
{
try
{
string hostInstanceName = "Microsoft BizTalk Server" + " " + hostName + " " + hostIns.Server;
Console.WriteLine("Removing Host Instance : " + hostInstanceName);
ManagementClass mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostInstance, null);
ManagementObjectCollection hostInstanceCollection = mgmtClass.GetInstances();
ManagementObject mgmtObj = null;
foreach (ManagementObject instance in hostInstanceCollection)
{
if (instance["Name"].ToString().ToUpper() == hostInstanceName.ToUpper())
{
mgmtObj = instance;
}
}
if (mgmtObj == null)
return;
if (mgmtObj["HostType"].ToString() != "2" && mgmtObj["ServiceState"].ToString() == "4")
{
//If HostInstance is not stopped.. Stop it or is instance of type IsolatedHost
mgmtObj.InvokeMethod("Stop", null);
}
//Remove Host Instance
mgmtObj.InvokeMethod("UnInstall", null);
ManagementClass svrHostClass = new ManagementClass(WMI_Root, MSBTS_ServerHost, null);
ManagementObject svrHostObject = svrHostClass.CreateInstance();
svrHostObject["ServerName"] = hostIns.Server;
svrHostObject["HostName"] = hostName;
//Unmap Host-instance from Host
svrHostObject.InvokeMethod("UnMap", null);
Console.WriteLine("Host Instance : " + hostInstanceName + " removed Sucessfully");
}
catch
{
throw;
}
}
#endregion


#region AddSendHandler Method :- This method Adds the send handler for an Adapter
public void AddSendHandler(string adapterName, string handler)
{
try
{
Console.WriteLine("Adding Send Handler : " + handler + " to " + adapterName + " Adapter.");
ManagementClass mgmtClass = new ManagementClass(WMI_Root, MSBTS_SendHandler2,null);
if (!Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Put();
Console.WriteLine("Send Handler : " + handler + " added to " + adapterName + " Adapter.");
}
else
{
}
}
catch
{
throw;
}
}
#endregion


#region RemoveSendHandler Method :- This method removes the send handler for an Adapter
public void RemoveSendHandler(string adapterName, string handler)
{
try
{

Console.WriteLine("Removing Send Handler : " + handler + " from " + adapterName + " Adapter.");
mgmtClass = new ManagementClass(WMI_Root, MSBTS_SendHandler2, null);
if (Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Delete();
Console.WriteLine("Send Handler : " + handler + " removed from " + adapterName + " Adapter.");
}
else
{

}
}
catch
{
throw;
}
}
#endregion


#region AddReceiveHandler Method :- This method Adds the receive handler for an Adapter
public void AddReceiveHandler(string adapterName, string handler)
{
try
{
Console.WriteLine("Adding Receive Handler : " + handler + " to " + adapterName + " Adapter.");
mgmtClass = new ManagementClass(WMI_Root, MSBTS_ReceiveHandler, null);
if (!Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Put();
Console.WriteLine("Receive Handler : " + handler + " added to " + adapterName + " Adapter.");
}
else
{
}
}
catch
{
throw;
}
}
#endregion


#region RemoveReceiveHandler Method :- This Method removes the receive handler for an Adapter
public void RemoveReceiveHandler(string adapterName, string handler)
{
Console.WriteLine("Removing Receive Handler : " + handler + " from " + adapterName + " Adapter.");
mgmtClass = new ManagementClass(WMI_Root, MSBTS_ReceiveHandler, null);
if (Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Delete();
Console.WriteLine("Receive Handler : " + handler + " added to " + adapterName + " Adapter.");
}
else
{
}
}
#endregion


#region Exists Method :- This method checks the presence of Management object
private bool Exists(ManagementClass cls, string key , string val)
{
ManagementObjectCollection objcoll = cls.GetInstances();
foreach(ManagementObject obj in objcoll)
{
if (obj[key].ToString().ToUpper() == val.ToUpper())
return true;
}
return false;
}
#endregion


#region Exists Method :- This method checks the presence of Management object
private bool Exists(ManagementClass cls, string key, string val,string key1, string val1)
{
ManagementObjectCollection objcoll = cls.GetInstances();
foreach (ManagementObject obj in objcoll)
{
if (obj[key].ToString().ToUpper() == val.ToUpper() && obj[key1].ToString().ToUpper() == val1.ToUpper())
return true;
}
return false;
}
#endregion
}