Things to know while automating the Transform Manager service
After writing a forum post a little while ago on this topic, I wanted to add an extra level of details and then post a blog. The issue was pertaining to the intricacies of starting/running the IIS Transform Manager service programmatically such as I was doing in my test automation. Here it is:
There are a few things to note when you wish to fully automate the IIS Transform Manager service. I can describe briefly what I do for testing internally, but keep in mind the service is not meant to be used as such, and we highly suggest using the User Interface to configure and start the service.
First you would need to make sure the service user credentials that you are using has the following privilege on the machine:
"SeServiceLogonRight"
"SeBatchLogonRight"
"SeAuditPrivilege"
"SeImpersonatePrivilege"
And make sure the user has Full access to the following directory @"%programdata%\Microsoft\IIS\Transform Manager".
Then, obviously the service credentials on the service itself needs to be updated. I use the System.Management.ManagementObject class with the following path "Win32_Service.Name='IISTMHost'" to update the credentials on the service itself. Here's a bare bones snippet that might help point you in the right direction.
string objPath = string.Format("Win32_Service.Name='{0}'", TMControler.ServiceName);
using (System.Management.ManagementObject service = new System.Management.ManagementObject(new System.Management.ManagementPath(objPath))){
object[] wmiParams = new object[11]; wmiParams[6] = argUser;wmiParams[7] = argPass;
service.InvokeMethod("Change", wmiParams);}
If you ever plan to use the UI at some point for troubleshooting, monitoring jobs or managing the service; you’ll also need to update the ApplicationHostConfig file to include the service credentials in the “credentials” collection of the system.applicationHost/transformManager section. See %systemdrive%\Windows\System32\inetsrv\Microsoft.Web.Administration.dll for accessing/editing this collection programmatically. Here's a example of how I used the Microsoft.Web.Administration library.
using (ServerManager localServer = new ServerManager()){
string attributeNameId = "id"; string attributeNameUserName = "userName"; string attributeNamePassword = "password"; string attributeNameDescription = "description"; string tmSectionName = "system.applicationHost/transformManager"; string credentialCollectionName = "credentials"; bool found = false; ConfigurationElement credential = null; ConfigurationElementCollection creds = null; Configuration config = null; ConfigurationSection tmSection = null; // Get the the Application Host Configconfig = localServer.GetApplicationHostConfiguration();
if (config == null){
//Log("Unable to get the Application Host Config");}
// Get the Transform Manager SectiontmSection = config.GetSection(tmSectionName);
if (tmSection == null){
//Log("Unable to get the Transform Manager Section of the Application Host Config");}
// Get the credentials collectioncreds = tmSection.GetCollection(credentialCollectionName);
if (creds == null){
//Log("Unable to get the credentials collection from the Transform Manager Section of the Application Host Config");}
// check if the credential already exists in the collection foreach (ConfigurationElement element in creds){
string elementId = element.GetAttributeValue(attributeNameId).ToString(); if (elementId.Equals(argId)){
credential = element;
//Log("Found Existing credential in the Transform Manager credentials Collection"); found = true; break;}
}
// if none existed create a new one but don't add it just yet if (credential == null){
credential = creds.CreateElement();
}
// Set the attributescredential.SetAttributeValue(attributeNameId, argId);
credential.SetAttributeValue(attributeNameUserName, argUsername);
credential.SetAttributeValue(attributeNamePassword, argPassword);
credential.SetAttributeValue(attributeNameDescription, argDescription);
// now we can add the new credentials after the attributes have been set. if (!found){
creds.Add(credential);
}
localServer.CommitChanges();
}
Now you should be ready to start the service and initialize it. For this you'll need to create a service reference to the IIS Transform Manager service to perform the initialization step. Here's a good blog to get you started if you have not done this already http://blogs.msdn.com/b/giuseppeguerrasio/archive/2011/06/17/monitoring-and-management-services-in-iis-transform-manager-1-0-beta.aspx. Below is a simplified version of my code to start the service and call initialized.
ServiceController tmService = new ServiceController("IISTMHost");tmService.Start();
tmService.WaitForStatus(
ServiceControllerStatus.Running, new TimeSpan(0,1,0));// Initialize the service with the service credential
TMS.ManagementServiceClient managementServiceClient = new TMS.ManagementServiceClient(NetTcpBinding, ManagementEndPointAddress); if (managementServiceClient != null){
TMS.Credential c = new TMS.Credential(){
Domain = argDomain,
UserName = argUser,
Password = argPass,
Id = argGuid,
Description = argFullUserName
};
managementServiceClient.Open();
managementServiceClient.InitializeService(c);
managementServiceClient.Close();
}
Once started, you can query if the service is properly initialized.if(!managementServiceClient.IsServiceInitialized())
{
//Log("The Transform Manager Service is not properly initialized");
}
At this point you should have the Transform Manager up and running and ready for more management and/or monitoring.