.netiis-6directoryservicesmetabaseoval

How to get the numeric ID of an IIS 6 Metabase property in C#?


The code below works OK and can read everything in a remote IIS 6 server's metabase -- except the frikkin' numeric ID of the properties. I can't find them in the PropertyValueCollection object.

var site = new DirectoryEntry("IIS://" + tbHost.Text + 
                    "/W3SVC/1", tbUsername.Text, tbPassword.Password);

Console.Write("Site {0}\n", site.Name);

foreach (PropertyValueCollection prop in site.Properties)
{
    Console.Write("    {0} (Type {1})\n", prop.PropertyName, 
                                               prop.Value.GetType());
    foreach (var thingInProp in prop)
    {
        Console.Write("        {0}\n", thingInProp);
    }
}

You can see the numeric IDs in the picture below. The code above successfully reads, for example, that LogFilePeriod equals 4, but it can't get the fact that the ID of the LogFilePeriod property is 4003. I need the IDs in order to make a collection conforming to the OVAL standard.

enter image description here

What I do get from the server is this. Where are the IDs? (As an aside, it seems this code also get inherited properties from upper-level paths. Is that correct?)

Site 1
    LogExtFileFlags (Type System.Int32)
        2199519
    LogFileLocaltimeRollover (Type System.Boolean)
        False
    LogFilePeriod (Type System.Int32)
        4
    LogFileTruncateSize (Type System.Int32)
        20971520
    MaxConnections (Type System.Int32)
        1000
    ServerSize (Type System.Int32)
        1
    ServerState (Type System.Int32)
        2
    Win32Error (Type System.Int32)
        0
    AppPoolId (Type System.String)
        DefaultAppPool
    DefaultDoc (Type System.String)
        Default.htm,Default.asp,index.htm,iisstart.htm
    KeyType (Type System.String)
        IIsWebServer
    ServerComment (Type System.String)
        Default Web Site
    SslCtlIdentifier (Type System.String)
        {E553F318-89D9-4C9F-9C09-91FF12A3BFAF}
    SslCtlStoreName (Type System.String)
        CA
    ServerBindings (Type System.String)
        :80:
    AllowKeepAlive (Type System.Boolean)
        True
    AppAllowClientDebug (Type System.Boolean)
        False
    AppAllowDebugging (Type System.Boolean)
        False
    AspAllowOutOfProcComponents (Type System.Boolean)
        True
    AspAllowSessionState (Type System.Boolean)
        True
    AspAppServiceFlags (Type System.Int32)
        0
    AspBufferingLimit (Type System.Int32)
        4194304
    AspBufferingOn (Type System.Boolean)
        True
    AspCalcLineNumber (Type System.Boolean)
        True
    AspCodepage (Type System.Int32)
        0
    AspEnableApplicationRestart (Type System.Boolean)
        True
    AspEnableAspHtmlFallback (Type System.Boolean)
        False
    AspEnableChunkedEncoding (Type System.Boolean)
        True
    AspEnableParentPaths (Type System.Boolean)
        False
    AspEnableTypelibCache (Type System.Boolean)
        True
    AspErrorsToNTLog (Type System.Boolean)
        False
    AspExceptionCatchEnable (Type System.Boolean)
        True
    AspExecuteInMTA (Type System.Int32)
        0
    AspKeepSessionIDSecure (Type System.Int32)
        0
    AspLCID (Type System.Int32)
        2048
    AspLogErrorRequests (Type System.Boolean)
        True
    AspMaxDiskTemplateCacheFiles (Type System.Int32)
        2000
    AspMaxRequestEntityAllowed (Type System.Int32)
        204800
    AspProcessorThreadMax (Type System.Int32)
        25
    AspQueueConnectionTestTime (Type System.Int32)
        3
    AspQueueTimeout (Type System.Int32)
        -1
    AspRequestQueueMax (Type System.Int32)
        3000
    AspRunOnEndAnonymously (Type System.Boolean)
        True
    AspScriptEngineCacheMax (Type System.Int32)
        250
    AspScriptErrorSentToBrowser (Type System.Boolean)
        True
    AspScriptFileCacheSize (Type System.Int32)
        500
    AspScriptTimeout (Type System.Int32)
        90
    AspSessionMax (Type System.Int32)
        -1
    AspSessionTimeout (Type System.Int32)
        20
    AspTrackThreadingModel (Type System.Boolean)
        False
    AuthFlags (Type System.Int32)
        1
    CacheISAPI (Type System.Boolean)
        True
    CGITimeout (Type System.Int32)
        300
    ConnectionTimeout (Type System.Int32)
        120
    ContentIndexed (Type System.Boolean)
        True
    DirBrowseFlags (Type System.Int32)
        1073741886
    LogType (Type System.Int32)
        1
    PasswordChangeFlags (Type System.Int32)
        6
    AnonymousUserName (Type System.String)
        IUSR_OVAL-IIS6-A
    AnonymousUserPass (Type System.String)
        n;x7u'8(H<8&4h
    AspScriptErrorMessage (Type System.String)
        An error occurred on the server when processing the URL.  Please contact the system administrator.
    AspScriptLanguage (Type System.String)
        VBScript
    LogOdbcDataSource (Type System.String)
        HTTPLOG
    LogOdbcPassword (Type System.String)
        sqllog
    LogOdbcTableName (Type System.String)
        InternetLog
    LogOdbcUserName (Type System.String)
        InternetAdmin
    LogPluginClsid (Type System.String)
        {FF160663-DE82-11CF-BC0A-00AA006111E0}
    AspDiskTemplateCacheDirectory (Type System.String)
        %windir%\system32\inetsrv\ASP Compiled Templates
    LogFileDirectory (Type System.String)
        C:\WINDOWS\system32\LogFiles
    HttpErrors (Type System.Object[])
        400,*,FILE,C:\WINDOWS\help\iisHelp\common\400.htm
        401,1,FILE,C:\WINDOWS\help\iisHelp\common\401-1.htm
        401,2,FILE,C:\WINDOWS\help\iisHelp\common\401-2.htm
        401,3,FILE,C:\WINDOWS\help\iisHelp\common\401-3.htm
        401,4,FILE,C:\WINDOWS\help\iisHelp\common\401-4.htm
        401,5,FILE,C:\WINDOWS\help\iisHelp\common\401-5.htm
        401,7,FILE,C:\WINDOWS\help\iisHelp\common\401-1.htm
        403,1,FILE,C:\WINDOWS\help\iisHelp\common\403-1.htm
        403,2,FILE,C:\WINDOWS\help\iisHelp\common\403-2.htm
        403,3,FILE,C:\WINDOWS\help\iisHelp\common\403-3.htm
        403,4,FILE,C:\WINDOWS\help\iisHelp\common\403-4.htm
        403,5,FILE,C:\WINDOWS\help\iisHelp\common\403-5.htm
        403,6,FILE,C:\WINDOWS\help\iisHelp\common\403-6.htm
        403,7,FILE,C:\WINDOWS\help\iisHelp\common\403-7.htm
        403,8,FILE,C:\WINDOWS\help\iisHelp\common\403-8.htm
        403,9,FILE,C:\WINDOWS\help\iisHelp\common\403-9.htm
        403,10,FILE,C:\WINDOWS\help\iisHelp\common\403-10.htm
        403,11,FILE,C:\WINDOWS\help\iisHelp\common\403-11.htm
        403,12,FILE,C:\WINDOWS\help\iisHelp\common\403-12.htm
        403,13,FILE,C:\WINDOWS\help\iisHelp\common\403-13.htm
        403,15,FILE,C:\WINDOWS\help\iisHelp\common\403-15.htm
        403,16,FILE,C:\WINDOWS\help\iisHelp\common\403-16.htm
        403,17,FILE,C:\WINDOWS\help\iisHelp\common\403-17.htm
        403,18,FILE,C:\WINDOWS\help\iisHelp\common\403.htm
        403,19,FILE,C:\WINDOWS\help\iisHelp\common\403.htm
        403,20,FILE,C:\WINDOWS\help\iisHelp\common\403-20.htm
        404,*,FILE,C:\WINDOWS\help\iisHelp\common\404b.htm
        404,2,FILE,C:\WINDOWS\help\iisHelp\common\404b.htm
        404,3,FILE,C:\WINDOWS\help\iisHelp\common\404b.htm
        405,*,FILE,C:\WINDOWS\help\iisHelp\common\405.htm
        406,*,FILE,C:\WINDOWS\help\iisHelp\common\406.htm
        407,*,FILE,C:\WINDOWS\help\iisHelp\common\407.htm
        412,*,FILE,C:\WINDOWS\help\iisHelp\common\412.htm
        414,*,FILE,C:\WINDOWS\help\iisHelp\common\414.htm
        415,*,FILE,C:\WINDOWS\help\iisHelp\common\415.htm
        500,12,FILE,C:\WINDOWS\help\iisHelp\common\500-12.htm
        500,13,FILE,C:\WINDOWS\help\iisHelp\common\500-13.htm
        500,15,FILE,C:\WINDOWS\help\iisHelp\common\500-15.htm
        500,16,FILE,C:\WINDOWS\help\iisHelp\common\500.htm
        500,17,FILE,C:\WINDOWS\help\iisHelp\common\500.htm
        500,18,FILE,C:\WINDOWS\help\iisHelp\common\500.htm
        500,19,FILE,C:\WINDOWS\help\iisHelp\common\500.htm
    ScriptMaps (Type System.Object[])
        .asp,C:\WINDOWS\system32\inetsrv\asp.dll,5,GET,HEAD,POST,TRACE
        .cer,C:\WINDOWS\system32\inetsrv\asp.dll,5,GET,HEAD,POST,TRACE
        .cdx,C:\WINDOWS\system32\inetsrv\asp.dll,5,GET,HEAD,POST,TRACE
        .asa,C:\WINDOWS\system32\inetsrv\asp.dll,5,GET,HEAD,POST,TRACE
        .idc,C:\WINDOWS\system32\inetsrv\httpodbc.dll,5,GET,POST
        .shtm,C:\WINDOWS\system32\inetsrv\ssinc.dll,5,GET,POST
        .shtml,C:\WINDOWS\system32\inetsrv\ssinc.dll,5,GET,POST
        .stm,C:\WINDOWS\system32\inetsrv\ssinc.dll,5,GET,POST
    MaxBandwidth (Type System.Int32)
        -1
    AdminACL (Type System.__ComObject)
        System.__ComObject

Solution

  • Metabase schema identifiers aren't surfaced in the ADSI API (which is what System.DirectoryServices.DirectoryEntry wraps. But you can use the metabase schema file as a lookup:

    C:\WINDOWS\system32\inetsrv\MBSchema.xml

    Here's your code (modified slightly to access my local metabase):

    XNamespace ns = "x-urn:microsoft-catalog:MetaData_V7";
    XDocument schema = XDocument.Load(@"C:\WINDOWS\system32\inetsrv\MBSchema.xml");
    
    using (DirectoryEntry site = new DirectoryEntry("IIS://Localhost/W3SVC/1"))
    {
        foreach (PropertyValueCollection prop in site.Properties)
        {
            var schemaProperty = schema.Descendants(ns + "Property")
                    .FirstOrDefault(a => 
                         (string)a.Attribute("InternalName") == prop.PropertyName);
    
            Console.Write("    {0}[ID:{1}] (Type {2})\n", 
                prop.PropertyName,
                schemaProperty.Attribute("ID"),
                prop.Value.GetType());
            foreach (var thingInProp in prop)
            {
                Console.Write("        {0}\n", thingInProp);
            }
        }
    }
    

    I'm assuming you're using .NET Framework 3.5 or later so you'll need to add a reference to System.Xml.Linq.

    I should add the caveat that if you're trying this on IIS7+ using the IIS6 compatibility layer then you'll need to copy the schema file from an IIS6 server to your IIS7 box.

    Further, you should really be using the Managed Microsoft.Web.Administration API to gather config data about IIS7+ servers. The reason for this is that not all IIS6 Metabase objects map onto IIS7's admin host config. Also there will be properties in IIS7 that won't have visibility in the IIS6 wrappers because there are no matching types.

    There is also no guarantee that future versions of IIS (IIS8 for example) will provide the IIS6 metabase compatibility layer.

    Finally, these ID's are just numeric identifiers for named properties, i.e. they don't uniquely identify any particular object in the metabase, that's done through metabase path strings.

    Metadata ID's exist mostly for the benefit of the IIS ABO API which uses these ID's rather than property names. I'd advise using the string property names as identifiers instead because as I mentioned earlier there are new IIS7 objects and properties that don't have these ID's.