Moving or Copying Metabase Nodes Using Absolute ADsPaths
Move or copy metabase nodes when you want to perform configuration tasks such as moving a virtual directory from one Web site to another or copying in bulk the configuration of one node to another.
Example Code
The following example shows you how to use the C# programming language to create a new virtual directory called "MyVDir" in the default Web site, copy it to a new virtual directory called "MyVDir2", then move "MyVDir2" to "MyVDir3". Code is also included to delete the new nodes.
This example requires Windows XP Professional Service Pack 2 or Windows Server 2003 Service Pack 1.
Note
System.DirectoryServices can be used to get and set String and DWORD properties in the IIS metabase, and invoke most methods. However, you cannot move or copy metabase nodes unless you are using Windows XP Professional with Service Pack 2 or Windows Server 2003 with Service Pack 1.
To keep this code example concise, it does not include code access security (CAS) parameters or parameter checking. For more information, see Code Access Security and Validating User Input to Avoid Attacks. Additionally, you can instantiate your System.DirectoryServices.DirectoryEntry object with an authentication parameter.
using System;
using System.IO;
using System.DirectoryServices;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
namespace System_DirectoryServices_DirectoryEntry_ConfigIIS
{
class Program
{
static void Main(string[] args)
{
...
CreateVDir("IIS://Localhost/W3SVC/1/Root", "MyVDir", "D:\\Inetpub\\Wwwroot");
...
CopyMetabaseNode("IIS://Localhost/W3SVC/1/Root/MyVDir", "IIS://Localhost/W3SVC/1/Root", "MyVDir2");
MoveMetabaseNode("IIS://Localhost/W3SVC/1/Root/MyVDir2", "IIS://Localhost/W3SVC/1/Root", "MyVDir3");
DeleteTree("IIS://Localhost/W3SVC/1/Root/MyVDir");
DeleteTree("IIS://Localhost/W3SVC/1/Root/MyVDir3");
...
}
...
static void CreateVDir(string metabasePath, string vDirName, string physicalPath)
{
// metabasePath is of the form "IIS://<servername>/<service>/<siteID>/Root[/<vdir>]"
// for example "IIS://localhost/W3SVC/1/Root"
// vDirName is of the form "<name>", for example, "MyNewVDir"
// physicalPath is of the form "<drive>:\<path>", for example, "C:\Inetpub\Wwwroot"
Console.WriteLine("\nCreating virtual directory {0}/{1}, mapping the Root application to {2}:",
metabasePath, vDirName, physicalPath);
try
{
DirectoryEntry site = new DirectoryEntry(metabasePath);
string className = site.SchemaClassName.ToString();
if ((className.EndsWith("Server")) || (className.EndsWith("VirtualDir")))
{
DirectoryEntries vdirs = site.Children;
DirectoryEntry newVDir = vdirs.Add(vDirName, (className.Replace("Service", "VirtualDir")));
newVDir.Properties["Path"][0] = physicalPath;
newVDir.Properties["AccessScript"][0] = true;
// These properties are necessary for an application to be created.
newVDir.Properties["AppFriendlyName"][0] = vDirName;
newVDir.Properties["AppIsolated"][0] = "1";
newVDir.Properties["AppRoot"][0] = "/LM" + metabasePath.Substring(metabasePath.IndexOf("/", ("IIS://".Length)));
newVDir.CommitChanges();
Console.WriteLine(" Done.");
}
else
Console.WriteLine(" Failed. A virtual directory can only be created in a site or virtual directory node.");
}
catch (Exception ex)
{
Console.WriteLine("Failed in CreateVDir with the following exception: \n{0}", ex.Message);
}
}
...
static void CopyMetabaseNode(string metabasePath, string newParentPath, string newName)
{
// metabasePath is of the form "IIS://<servername>/<path>/<childPath>"
// for example "IIS://localhost/W3SVC/1/Root/MyVDir"
// newParentPath is of the form "IIS://<servername>/<path>" where it is a parent object of metabasePath
// for example "IIS://localhost/W3SVC/555/Root"
// newName is of the form "<name>", for example, "MyVDir2"
Console.WriteLine("\nCopying node at {0} to {1}:", metabasePath, newParentPath);
try
{
DirectoryEntry path = new DirectoryEntry(metabasePath);
DirectoryEntry newParent = new DirectoryEntry(newParentPath);
if (path.Parent.SchemaClassName.ToString() == newParent.SchemaClassName.ToString())
{
DirectoryEntry newPath = path.CopyTo(newParent, newName);
newParent.CommitChanges();
Console.WriteLine(" Done.");
}
else
Console.WriteLine(" Failed in CopyMetabaseNode; parent of {0} is not the same object as {1}.", metabasePath, newParentPath);
}
catch (Exception ex)
{
Console.WriteLine("Failed in CopyMetabaseNode with the following exception: \n{0}", ex.Message);
}
}
static void MoveMetabaseNode(string metabasePath, string newParentPath, string newName)
{
// metabasePath is of the form "IIS://<servername>/<path>/<childPath>"
// for example "IIS://localhost/W3SVC/1/Root/MyVDir2"
// newParentPath is of the form "IIS://<servername>/<path>" where it is a parent object of metabasePath
// for example "IIS://localhost/W3SVC/555/Root"
// newName is of the form "<name>", for example, "MyVDir3"
Console.WriteLine("\nMoving node at {0} to {1}:", metabasePath, newParentPath);
try
{
DirectoryEntry path = new DirectoryEntry(metabasePath);
DirectoryEntry newParent = new DirectoryEntry(newParentPath);
if (path.Parent.SchemaClassName.ToString() == newParent.SchemaClassName.ToString())
{
path.MoveTo(newParent, newName);
newParent.CommitChanges();
Console.WriteLine(" Done.");
}
else
Console.WriteLine(" Failed in MoveMetabaseNode; parent of {0} is not the same object as {1}.", metabasePath, newParentPath);
}
catch (Exception ex)
{
Console.WriteLine("Failed in MoveMetabaseNode with the following exception: \n{0}", ex.Message);
}
}
...
static void DeleteTree(string metabasePath)
{
// metabasePath is of the form "IIS://<servername>/<path>"
// for example "IIS://localhost/W3SVC/1/Root/MyVDir"
// or "IIS://localhost/W3SVC/AppPools/MyAppPool"
Console.WriteLine("\nDeleting {0}:", metabasePath);
try
{
DirectoryEntry tree = new DirectoryEntry(metabasePath);
tree.DeleteTree();
tree.CommitChanges();
Console.WriteLine(" Done.");
}
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(" Done.");
}
catch (Exception ex)
{
Console.WriteLine("Failed in DeleteTree with the following exception: \n{0}", ex);
Console.WriteLine("Could not delete metabase path {0}", metabasePath);
}
}
...
}
}
Imports System
Imports System.IO
Imports System.DirectoryServices
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Collections
Module Program
Sub Main(ByVal args() As String)
...
CreateVDir("IIS://Localhost/W3SVC/1/Root", "MyVDir", "D:\Inetpub\Wwwroot")
...
End Sub
...
Sub CreateVDir(ByVal strMetabasePath As String, ByVal strVdirName As String, ByVal strPhysicalPath As String)
' strMetabasePath is of the form "IIS://<servername>/<service>/<siteID>/Root[/<vdir>]"
' For example: "IIS://localhost/W3SVC/1/Root"
' strVdirName is of the form "<name>", for example, "MyNewVDir"
' strPhysicalPath is of the form "<drive>:\<path>", for example, "C:\Inetpub\Wwwroot"
Console.WriteLine(vbLf + "Creating virtual directory {0}/{1}, mapping the Root application to {2}:", strMetabasePath, strVdirName, strPhysicalPath)
Try
Dim objSite As New DirectoryEntry(strMetabasePath)
Dim strClassName As String = objSite.SchemaClassName.ToString()
If strClassName.EndsWith("Server") OrElse strClassName.EndsWith("VirtualDir") Then
Dim objVdirs As DirectoryEntries = objSite.Children
Dim objNewVdir As DirectoryEntry = objVdirs.Add(strVdirName, strClassName.Replace("Service", "VirtualDir"))
objNewVdir.Properties("Path")(0) = strPhysicalPath
objNewVdir.Properties("AccessScript")(0) = True
' These properties are necessary for an application to be created.
objNewVdir.Properties("AppFriendlyName")(0) = strVdirName
objNewVdir.Properties("AppIsolated")(0) = "1"
objNewVdir.Properties("AppRoot")(0) = "/LM" + strMetabasePath.Substring(strMetabasePath.IndexOf("/", "IIS://".Length))
objNewVdir.CommitChanges()
Console.WriteLine("Done.")
Else
Console.WriteLine("Failed. A virtual directory can only be created in a site or virtual directory node.")
End If
Catch exError As Exception
Console.WriteLine("Failed in CreateVDir with the following exception: " + vbLf + "{0}", exError.Message)
End Try
End Sub
...
End Module