{"id":204,"date":"2007-12-24T13:47:19","date_gmt":"2007-12-24T01:47:19","guid":{"rendered":"http:\/\/craig.dubculture.co.nz\/blog\/2007\/12\/24\/c-how-to-tell-if-an-iis-metabase-property-is-inherited\/"},"modified":"2007-12-24T13:50:37","modified_gmt":"2007-12-24T01:50:37","slug":"c-how-to-tell-if-an-iis-metabase-property-is-inherited","status":"publish","type":"post","link":"http:\/\/craig.dubculture.co.nz\/blog\/2007\/12\/24\/c-how-to-tell-if-an-iis-metabase-property-is-inherited\/","title":{"rendered":"C#: How to tell if an IIS metabase property is inherited"},"content":{"rendered":"<p>How can you tell, using managed code, if an IIS metabase property is inherited?<\/p>\n<p>Scenario: I am using System.DirectoryServices to manage the IIS configuration (known as the \"metabase\", and stored in an XML file). I want to remove a property on a metabase node, but only if it is explicitly set here. This allows me to inherit the correct value from up the tree.<\/p>\n<p><b>First attempt:<\/b><\/p>\n<pre>\r\nif (dirEntry.Properties[\"AnonymousUserName\"].Count &gt; 0) {\r\n    dirEntry.Properties[\"AnonymousUserName\"].Clear();\r\n    Console.WriteLine(\"Log: Local value found for AnonymousUserName, removing\");\r\n}<\/pre>\n<p>My assumption was that this would remove the entry the first time, if it exists, and ignore it every time afterwards.  However, every time it runs, Count is 1 and the property appears set.<\/p>\n<p>It turns out that the Properties method on a DirectoryEntry object shows <b>all<\/b> the properties, including ones that are set on parent items in the tree.<\/p>\n<p>How can we see only items that are defined on this particular node? This problem shows up <a href=\"http:\/\/www.dotnet247.com\/247reference\/msgs\/21\/106618.aspx\">all<\/a> <a href=\"http:\/\/forums.iis.net\/t\/1146298.aspx\">over<\/a> <a href=\"http:\/\/forums.iis.net\/t\/1146077.aspx\">the<\/a> <a href=\"http:\/\/www.c-sharpcorner.com\/Forums\/ShowMessages.aspx?ThreadID=34800\">Internet <\/a>with no solution. However, Microsoft's <a href=\"http:\/\/blogs.msdn.com\/david.wang\/\">David Wang <\/a>isn't one to leave a newsgroup question unanswered:<\/p>\n<blockquote><p>Never tried it in .Net, but with ADSI you can determine this.<br \/>\n<i>Set objNode = GetObject( \"IIS:\/\/foo\/W3SVC\" &amp; \"\/\" &amp; \"AppPools\/AnAppPool\" )<br \/>\nSet objNodeAttribute = objNode.GetPropertyAttribObj( \"WamUserName\" )<br \/>\nIf ( objNodeAttribute.IsInherit = true ) Then<br \/>\nEnd If  <\/i><\/p><\/blockquote>\n<p>I just needed a way to run GetPropertyAttribObj from C#, which was a much easier problem to solve.  There were only a couple of relevant hits, the best one being some <a href=\"http:\/\/72.14.205.104\/search?q=cache:3YXT1QCKGK0J:pastebin.com\/pastebin.php%3Fdl%3Dm1682284a+DirectoryEntry+IsInherit&amp;hl=en&amp;client=firefox-a&amp;strip=1\">abandoned Pastebin code in Google's cache<\/a>.<\/p>\n<p>We now have an answer:<\/p>\n<pre>\r\n\/\/\/ &lt;summary&gt;\r\n\/\/\/ Establish if a metabase property is set explicitly on this node.\r\n\/\/\/ &lt;\/summary&gt;\r\n\/\/\/ &lt;param name=\"iisNode\"&gt;Metabase node&lt;\/param&gt;\r\n\/\/\/ &lt;param name=\"propertyName\"&gt;Property name&lt;\/param&gt;\r\n\/\/\/ &lt;returns&gt;True if the property is defined on this node explicitly; false if the property is not defined at all, or is inherited.&lt;\/returns&gt;\r\nprivate static bool PropertyDefinedExplicitly(DirectoryEntry iisNode, String propertyName)\r\n{\r\n\r\n    \/\/ check 1. this node has a valid key-type, and 2. it contains the required property\r\n    if (iisNode.Properties.Contains(\"KeyType\") &amp;&amp;\r\n    iisNode.Properties[\"KeyType\"].Value.ToString().Length &gt; 0 &amp;&amp;\r\n    iisNode.Properties.Contains(propertyName))\r\n    {\r\n\r\n        \/\/ call ADSI GetPropertyAttribObject method directly\r\n        Object propertyAttributes = iisNode.Invoke(\"GetPropertyAttribObj\",\r\n        new String[] { propertyName });\r\n        IISOle.IISPropertyAttribute attributes =\r\n        (IISOle.IISPropertyAttribute)propertyAttributes;\r\n\r\n        \/\/ Isinherit will be set if the property is inherited\r\n        if (attributes.Isinherit)\r\n        {\r\n            return false; \/\/ property was inherited\r\n        }\r\n        else\r\n        {\r\n            return true; \/\/ property explicitly defined on this node\r\n        }\r\n\r\n    }\r\n    else\r\n    {\r\n        return false; \/\/ not a valid IIsObject node, or property not found\r\n    }\r\n}<\/pre>\n<p>We then rewrite the original function like so:<\/p>\n<pre>\r\nif (PropertyDefinedExplicitly(dirEntry, \"AnonymousUserName\")) {\r\n    dirEntry.Properties[\"AnonymousUserName\"].Clear();\r\n    Console.WriteLine(\"Log: Local value found for AnonymousUserName, removing\");\r\n}<\/pre>\n<p>There is a lesson to learn here for Windows programmers: Microsoft support is in the newsgroups.  Don't fear Usenet because it's older than you are!<\/p>\n<p>With useful tips like this, I'll win the <a href=\"http:\/\/www.dot.net.nz\/Default.aspx?tabid=78\">NZ .NET blog of the year<\/a> for sure!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How can you tell, using managed code, if an IIS metabase property is inherited? Scenario: I am using System.DirectoryServices to manage the IIS configuration (known as the \"metabase\", and stored in an XML file). I want to remove a property on a metabase node, but only if it is explicitly set here. This allows me [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[66,68],"tags":[3,27,4],"_links":{"self":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts\/204"}],"collection":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=204"}],"version-history":[{"count":0,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts\/204\/revisions"}],"wp:attachment":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=204"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}