Wednesday, August 25, 2010

SDC Tasks Failed to Update IIS website on Windows Server 2008 R2 IIS7

I just moved a website to IIS 7 on Windows Server 2008 R2 and the automate deployment builds failed to update IIS to set the website in maintenance mode (app offline) by simply changing the website path using the SDCTasks.

Error:


A task error has occured. Message = Unknown error (0x80005000) MachineName = \\LOCALQA01 HostName = Description = acme.com Path = D:\websites\app_offline\acme Identifier = AuthFlags = AppPoolId = AnonymousUsername = AnonymousPassword = HttpExpires = DirBrowseFlags = DefaultDocs = at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.get_IsContainer() at System.DirectoryServices.DirectoryEntries.ChildEnumerator..ctor(DirectoryEntry container) at Microsoft.Sdc.Tasks.Configuration.Web.WebSite.GetIdentifierFromDescription(String machineName, String description) in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\Configuration\Web\WebSite.cs:line 264 at Microsoft.Sdc.Tasks.Configuration.Web.WebSite.Exists(String machineName, String description) in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\Configuration\Web\WebSite.cs:line 241 at Microsoft.Sdc.Tasks.Web.WebSite.Modify.InternalExecute() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\Web\WebSite\Modify.cs:line 225 at Microsoft.Sdc.Tasks.TaskBase.Execute() in c:\projects\codeplex\sdctasks\Solutions\Main\Tasks\TaskBase.cs:line 67

I did just digging around and finally go to the real issue. Looks like DirectoryServices which is what SDC tasks uses to update the IIS was the caused of this problem.
I created a simple consolde app to try updating the website with DirectoryServices:





static void Main(string[] args)
{

try
{

string MachineName = "LOCALQA01";
var Identifier = GetIdentifierFromDescription("LOCALQA01", "Acme.com").ToString();
string path = @"D:\websites\app_offline\Acme";

// load the site
DirectoryEntry site = new DirectoryEntry("IIS://" + MachineName + "/w3svc/" + Identifier + "/ROOT");

// make the changes we need to make
if (!string.IsNullOrEmpty(System.IO.Path.GetFullPath(path)))
{
// Log.LogMessage(string.Format("Setting Path: {0}", path));
site.Properties["Path"][0] = path;
}
site.CommitChanges();

Console.WriteLine(Identifier);

}
catch(Exception ex){
Console.WriteLine(ex.ToString());

}

Console.ReadLine();
}

public static int GetIdentifierFromDescription(string machineName, string description)
{
// load the W3SVC and check all the children for a property that matches

DirectoryEntry de = new DirectoryEntry("IIS://" + machineName + "/W3SVC");

foreach (DirectoryEntry o in de.Children)
{
if (o.SchemaClassName == "IIsWebServer")
{
if ((string)o.Properties["ServerComment"][0] == description)
{
return Convert.ToInt32(o.Name);
}
}
}
return 0;
}




Bu when I run this from the build machine I was then getting this error:

[System.Runtime.InteropServices.COMException] {"Unknown error (0x80005000)"}
System.Runtime.InteropServices.COMException

Unknown error (0x80005000)
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_IsContainer()
at System.DirectoryServices.DirectoryEntries.CheckIsContainer()
at System.DirectoryServices.DirectoryEntries.Find(String name, String schemaC
lassName)



Without going to further details the caused of this error was because I did not had IIS 6 Metabase Compability role service installed for IIS7 on the build machine where I was running the scripts from. You can installed this by going to :

Server Manager > Roles> Web Server (IIS) > Add Role Services





After you fix this and still have issues probably the next error will be "Access Denied".
This is because of the UAC in Windows Server 2008 R2 which is annoying if you ask me. You can then make the account service that runs your builds local admin on the server your trying to update. This will take care of the issue. Or you can just disable the UAC and be done with it.

Hope this helps.