I'm trying to programmatically add an ISAPI extension dll in IIS using ADSI. This has been working for ages on previous versions of IIS, but it seems to fail on IIS 7.
I am using similar code like shown in this question:
var web = GetObject("IIS://localhost/W3SVC/1/ROOT/specificVirtualDirectory");
var maps = web.ScriptMaps.toArray();
map[maps.length] = ".aaa,c:\\path\\to\\isapi\\extension.dll,1,GET,POST";
web.ScriptMaps = maps.asDictionary();
web.SetInfo();
After executing that code, I do see an "AboMapperCustom-12345678" entry for that specific dll in the "Handler mappings" of the specific virtual directory in which I added the script map. But when I try to use that extension in a browser, I always get
HTTP Error 404.2 Not Found
The page you are requesting cannot be served because of the ISAPI and CGI Restriction list settings on the Web server.
Even after adding an entry to allow that specific dll in the "ISAPI and CGI restrictions", I keep getting that error.
To make it actually work, I first have to undo these steps (encountering the same issue like the OP of the question mentioned above: after deleting the script map entry from the IIS manager GUI, I also have to programmatically delete it using ADSI before it's actually gone from the metabase).
And then manually add an entry like this:
- inetmgr -> webserver -> website -> virtual directory -> handler mappings -> add script map...
- path = *.dll, executable =
<path to dll>
, name =<doesn't matter, but it's mandatory>
- click "yes" on the question "do you want to allow this ISAPI extension?"
When I compare the 2 entries, they are exactly the same, except for the "Entry Type" which seems to be "Inherited" for the programmatically added one and "Local" for the one added manually.
The strange thing is, even though it says "Inherited", I don't see it anywhere in IIS on a higher level. Where is it inheriting from?
In my code, I do add the script map to the specific virtual directory so it should be "Local" as well. Maybe there is the problem, but I don't know how to add a "Local" Script Map using ADSI.
I really would like to keep using the ADSI method, as otherwise I will have to use different methods in our setup when working with IIS 7 or previous versions, and I would like to avoid that.
To recap: How can I programmatically add a script map entry and its companion CGI and ISAPI restrictions entry to IIS 7 using ADSI?
Anybody who can shed some light on this? Any help appreciated.
IIS7 isn't out of the box 100% compatible with the Metabase structure of previous versions, you need to enable it. In the "role services" for IIS, make sure you have "IIS6 Metabase Compatibility" enabled.
See the following 2 sites for more info:
http://learn.iis.net/page.aspx/125/metabase-compatibility-with-iis-7
http://learn.iis.net/page.aspx/126/how-to-use-metabase-compatibility-with-iis-7
With that being said, I've found that ADSI and Metabase compatibility don't seem to be 100% reliable. A much better solution would be to retool your script to use appcmd.exe. The command would be something like:
See this site for more info:
http://technet.microsoft.com/en-us/library/cc754147(WS.10).aspx
I eventually solved this the way I was trying to avoid, using
appcmd
. But to add to @MattB's answer, I needed to add an extra parametermodules='IsapiModule'
to make it actually work:And I also had to add an entry to the "ISAPI and CGI restrictions" section:
I check the existence of
%windir%\system32\inetsrv\appcmd.exe
to determine which way to use. If it exists, I useappcmd
, if it doesn't, I fall back toADSI
.Still interested in a pure
ADSI
way though!