[转载]【翻译】ASP.NET操作WMI——用代码向IIS6添加站点、虚拟目录和主机头 | 天机不可泄漏.
原文:WMI Functions from ASP.NET
作者:JeroenMX
前言
本文介绍了ASP.NET如何通过WMI创建站点、添加虚拟目录和添加主机头。并且已在Windows Server 2003及IIS6的环境下测试通过。
这玩意儿花了老子3天时间才搞定,用了几个小时写代码,而且当中还花了不少时间解决Win32: Access denied error的问题。当然我要指出的是,无论NETWORK SERVER帐户还是IUSR_<servername>帐户都不要设置过大的权限。对于WMI和IIS metabase的安全机理,我还是一无所知的。我只不过解决问题而已。
看代码
首先要从Internet信息服务(IIS)管理器中获取网站标识符,点击“网站”根节点,右侧“标识符”显示的就是网站的ID。默认网站的标识符 通常是1。
获取网站标识的功能,我们要用到一个namespace,代码如下:
1 |
using System.Management; |
下文所有’ServerName’都表示你的服务器名称,或者如果你的代码是本地运行的,也可以用一个点来表示。
创建一个站点,你会用到如下函数。这个函数返回新网站的ID,这样你可以进一步对这个网站进行操作。
01 |
public static string CreateWebsite( string serverName, string appPoolName, string ip, string pathToRoot, string hostName, string domainName, int port) |
03 |
ConnectionOptions options = new ConnectionOptions(); |
04 |
options.Authentication = AuthenticationLevel.Connect; |
05 |
options.EnablePrivileges = true ; |
06 |
options.Impersonation = ImpersonationLevel.Impersonate; |
07 |
ManagementScope scope = new ManagementScope( string .Format(@\\{0}\root\MicrosoftIISv2, serverName), options); |
09 |
ManagementObject oW3SVC = new ManagementObject(scope, |
10 |
new ManagementPath( @"IIsWebService='W3SVC'" ), null ); |
12 |
ManagementBaSEObject[] serverBindings = new ManagementBaSEObject[1]; |
13 |
serverBindings[0] = CreateServerBinding(scope, string .Format( "{0}.{1}" , hostName, domainName), ip, port); |
14 |
ManagementBaSEObject inputParameters = oW3SVC.GetMethodParameters( "CreateNewSite" ); |
15 |
inputParameters[ "ServerComment" ] = string .Format( "{0}.{1}" , hostName, domainName); |
16 |
inputParameters[ "ServerBindings" ] = serverBindings; |
17 |
inputParameters[ "PathOfRootVirtualDir" ] = pathToRoot; |
18 |
ManagementBaseObject outParameter = oW3SVC.InvokeMethod( "CreateNewSite" , inputParameters, null ); |
20 |
string siteId = Convert.ToString(outParameter.Properties[ "ReturnValue" ].Value).Replace( "IIsWebServer='W3SVC/" , "" ).Replace( "'" , "" ); |
21 |
ManagementObject oWebVirtDir = new ManagementObject(scope, new ManagementPath( string .Format( @"IIsWebVirtualDirSetting.Name='W3SVC/{0}/root'" , siteId)), null ); |
22 |
oWebVirtDir.Properties[ "AppFriendlyName" ].Value = string .Format( "{0}.{1}" , hostName, domainName); |
23 |
oWebVirtDir.Properties[ "AccessRead" ].Value = true ; |
24 |
oWebVirtDir.Properties[ "AuthFlags" ].Value = 5; |
25 |
oWebVirtDir.Properties[ "AccessScript" ].Value = true ; |
26 |
oWebVirtDir.Properties[ "AuthAnonymous" ].Value = true ; |
27 |
oWebVirtDir.Properties[ "AppPoolId" ].Value = appPoolName; |
30 |
ManagementObject site = new ManagementObject(scope, new ManagementPath(Convert.ToString(outParameter.Properties[ "ReturnValue" ].Value)), null ); |
31 |
site.InvokeMethod( "Start" , null ); |
创建一个虚拟目录:
01 |
public static void AddVirtualFolder( string serverName, string websiteId, string name, string path){ |
02 |
ManagementScope scope = new ManagementScope( string .Format( @"\\{0}\root\MicrosoftIISV2" , serverName)); |
05 |
string siteName = string .Format( "W3SVC/{0}/Root/{1}" , websiteId, name); |
07 |
ManagementClass mc = new ManagementClass(scope, new ManagementPath( "IIsWebVirtualDirSetting" ), null ); |
08 |
ManagementObject oWebVirtDir = mc.CreateInstance(); |
10 |
oWebVirtDir.Properties[ "Name" ].Value = siteName; |
11 |
oWebVirtDir.Properties[ "Path" ].Value = path; |
12 |
oWebVirtDir.Properties[ "AuthFlags" ].Value = 5; |
13 |
oWebVirtDir.Properties[ "EnableDefaultDoc" ].Value = true ; |
15 |
oWebVirtDir.Properties[ "DirBrowseFlags" ].Value = 0x4000003E; |
16 |
oWebVirtDir.Properties[ "AccessFlags" ].Value = 513; |
19 |
ManagementObject mo = new ManagementObject(scope, new System.Management.ManagementPath( "IIsWebVirtualDir='" + siteName + "'" ), null ); |
20 |
ManagementBaseObject inputParameters = mo.GetMethodParameters( "AppCreate2" ); |
21 |
inputParameters[ "AppMode" ] = 2; |
22 |
mo.InvokeMethod( "AppCreate2" , inputParameters, null ); |
23 |
mo = new ManagementObject(scope, new System.Management.ManagementPath( "IIsWebVirtualDirSetting='" + siteName + "'" ), null ); |
24 |
mo.Properties[ "AppFriendlyName" ].Value = name; |
给网站添加一个主机头:
01 |
public static void AddHostHeader( string serverName, string hostHeader, string ip, int port, string websiteID){ |
02 |
ManagementScope scope = new ManagementScope( string .Format( @"\\{0}\root\MicrosoftIISV2" , serverName)); |
05 |
string siteName = string .Format( "'W3SVC/{0}'" , websiteID); |
07 |
ManagementObject mo = new ManagementObject(scope, new System.Management.ManagementPath( "IIsWebServerSetting=" + siteName), null ); |
08 |
ManagementBaseObject[] websiteBindings = (ManagementBaseObject[])mo.Properties[ "ServerBindings" ].Value; |
10 |
ManagementObject mco = CreateServerBinding(scope, hostHeader, ip, port); |
12 |
ManagementBaseObject[] newWebsiteBindings = new ManagementBaseObject[websiteBindings.Length+1]; |
13 |
websiteBindings.CopyTo(newWebsiteBindings, 0); |
14 |
newWebsiteBindings[newWebsiteBindings.Length - 1] = mco; |
16 |
mo.Properties[ "ServerBindings" ].Value = newWebsiteBindings; |
最后别忘了这个函数,它可以为网站绑定一个网络标识。
03 |
<pre> private static ManagementObject CreateServerBinding(ManagementScope scope, string hostName, string ip, int port) |
05 |
ManagementClass mc = new ManagementClass(scope, new ManagementPath( "ServerBinding" ), null ); |
06 |
ManagementObject mco = mc.CreateInstance(); |
08 |
mco.Properties[ "Hostname" ].Value = hostName; |
09 |
mco.Properties[ "IP" ].Value = ip; |
10 |
mco.Properties[ "Port" ].Value = port; |
注意的几点
安全。如果之用上面的那坨代码还不行。我千方百计想让其运行,但貌似忽视了2件事情。访问WMI和IIS metabase。 ASP.NET在Windows Server 2003和IIS6.0上运行默认使用的是NETWORK SERVICE帐户。但是,我们还是要使用客户端模拟。 所以在Web.config中添加下面一个配置:
1 |
< identity impersonate = "true" /> |
使用了这个配置,IUSR_<servername>会使用客户端模拟的方式去访问IIS metabase。在后面的文章里,我就用IUSR_来表示这个帐户。不要忘记,在IUSR_后面加上你的服务器名称才是这个帐户的名字。
WMI权限设置
- 控制面板 –> 管理工具 –> 计算机管理 –> 服务和应用程序。
- 右键WMI控制,点击“属性”。
- 选择“安全”选项卡。
- 展开Root树
- 点击MicrosoftIISv2。
- 点击“安全设置”。
- 点击“高级”。
- 双击IUSR_(如果“组或用户名称”里面没有的话,就把它添加进去)
- 把IUSR_ “应用到”设置成“这个名称控件和子名称空间”
- “允许”所有权限。
- 所有窗口都点击“确定”。
IIS metabase权限设置
- 下载并安装IIS6 Resource Kit。
- 运行MetaBase Explorer (在开始菜单的IIS Resource Kit中可以找到)。
- 展开树形目录,右键第一个或第二个节点并且选择“Permissions”。
- 如果提示你“The current key inherits its security permissions from the key /”,点击“是”。
- 选择“IIS_IUSRS”,如果没有的话,把它添加进去。
- 选择“Full Control”。
- 所有窗口都点击“确定”。
有了足够的权限就能运行了。
如果有高人能对这个方法谈谈自己的感想,并且能指出更好的配置IIS和WMI的方法,那就更赞了。记得之前,我都是自己捣鼓出来的,所以我不知道这 个方法是不是最佳的方案。
如果你在运行代码的时候碰到任何问题,我愿意效劳。
译者注:
网上能搜索到的还有一种方法:使用DirectoryEntry方法,方法差不多,关键是要把权限设置好。