WMI Functions from ASP.NET

 
Introduction

This article demonstrates how to use WMI in ASP.NET to create a website, add a virtual folder, and add host headers. I have tested it using Windows Server 2003 and IIS 6.

It took me three days to get it working, some hours to write the code, and the remaining time finding out why I got a Win32: Access denied error. I could, of course, figure out that neither the NETWORK SERVICE or the IUSR_<servername> account has too many rights. I didn't have a clue, however, how WMI and the IIS metabase security work. I still don't, much, really. I did, however, solve my problem.
Using the code

To get a website ID from Internet Information Services Manager, click the 'Web Sites' node and check the column 'Identifier' for the ID. The default website always has the ID 1.

The functions we'll use are in this namespace, so include it:

Collapse

using System.Management;

Hence the variable 'ServerName'. This is where you put your server's name, or a dot if it's the one you're running your code on.

To create a website, you'll want to use the following function. It returns the ID of the website that you can use in the functions mentioned further on.

Collapse

public static string CreateWebsite(string serverName, string appPoolName, string ip, 
string pathToRoot, string hostName, string domainName, int port)
{
ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.Connect;
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope(string.Format(@\\{0}\root\MicrosoftIISv2, 
serverName), options);
scope.Connect();
ManagementObject oW3SVC = new ManagementObject(scope, 
new ManagementPath(@"IIsWebService='W3SVC'"), null);

ManagementBaseObject[] serverBindings = new ManagementBaseObject[1];
serverBindings[0] = CreateServerBinding(scope, 
string.Format("{0}.{1}", hostName, domainName), ip, port);
ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters("CreateNewSite");
inputParameters["ServerComment"] = string.Format("{0}.{1}", hostName, domainName);
inputParameters["ServerBindings"] = serverBindings;
inputParameters["PathOfRootVirtualDir"] = pathToRoot;
ManagementBaseObject outParameter = 
oW3SVC.InvokeMethod("CreateNewSite", inputParameters, null);

string siteId = Convert.ToString(
outParameter.Properties["ReturnValue"].Value).Replace(
"IIsWebServer='W3SVC/", "").Replace("'", "");
ManagementObject oWebVirtDir = new ManagementObject(scope, 
new ManagementPath(string.Format(
@"IIsWebVirtualDirSetting.Name='W3SVC/{0}/root'", siteId)), null);
oWebVirtDir.Properties["AppFriendlyName"].Value = 
string.Format("{0}.{1}", hostName, domainName);
oWebVirtDir.Properties["AccessRead"].Value = true;
oWebVirtDir.Properties["AuthFlags"].Value = 5; // Integrated Windows Auth.
oWebVirtDir.Properties["AccessScript"].Value = true;
oWebVirtDir.Properties["AuthAnonymous"].Value = true;
oWebVirtDir.Properties["AppPoolId"].Value = appPoolName;
oWebVirtDir.Put();

ManagementObject site = new ManagementObject(scope, 
new ManagementPath(Convert.ToString(
outParameter.Properties["ReturnValue"].Value)), null);
site.InvokeMethod("Start", null);
return siteId;
}

To add a virtual folder:

Collapse

public static void AddVirtualFolder(string serverName, string websiteId, 
string name, string path)
{
ManagementScope scope = new ManagementScope(
string.Format(@"\\{0}\root\MicrosoftIISV2", serverName));
scope.Connect();

string siteName = string.Format("W3SVC/{0}/Root/{1}", websiteId, name);

ManagementClass mc = new ManagementClass(scope, 
new ManagementPath("IIsWebVirtualDirSetting"), null);
ManagementObject oWebVirtDir = mc.CreateInstance();

oWebVirtDir.Properties["Name"].Value = siteName;
oWebVirtDir.Properties["Path"].Value = path;
oWebVirtDir.Properties["AuthFlags"].Value = 5; // Integrated Windows Auth.
oWebVirtDir.Properties["EnableDefaultDoc"].Value = true;
// date, time, size, extension, longdate ;
oWebVirtDir.Properties["DirBrowseFlags"].Value = 0x4000003E;
oWebVirtDir.Properties["AccessFlags"].Value = 513; // read script 
oWebVirtDir.Put();

ManagementObject mo = new ManagementObject(scope, 
new System.Management.ManagementPath("IIsWebVirtualDir='" + 
siteName + "'"), null);
ManagementBaseObject inputParameters = mo.GetMethodParameters("AppCreate2");
inputParameters["AppMode"] = 2;
mo.InvokeMethod("AppCreate2", inputParameters, null);
mo = new ManagementObject(scope, new System.Management.ManagementPath(
"IIsWebVirtualDirSetting='" + siteName + "'"), null);
mo.Properties["AppFriendlyName"].Value = name;
mo.Put();
}

To add a host header to the website:

Collapse

public static void AddHostHeader(string serverName, string hostHeader, 
string ip, int port, string websiteID)

ManagementScope scope = new ManagementScope(string.Format(
@"\\{0}\root\MicrosoftIISV2", serverName));
scope.Connect();

string siteName = string.Format("'W3SVC/{0}'", websiteID);

ManagementObject mo = new ManagementObject(scope, 
new System.Management.ManagementPath("IIsWebServerSetting=" + siteName), null);
ManagementBaseObject[] websiteBindings = 
(ManagementBaseObject[])mo.Properties["ServerBindings"].Value;

ManagementObject mco = CreateServerBinding(scope, hostHeader, ip, port);

ManagementBaseObject[] newWebsiteBindings = 
new ManagementBaseObject[websiteBindings.Length+1];
websiteBindings.CopyTo(newWebsiteBindings, 0);
newWebsiteBindings[newWebsiteBindings.Length - 1] = mco;

mo.Properties["ServerBindings"].Value = newWebsiteBindings;

mo.Put();
}

Last but not least, add the following function. It creates an object for server binding:

Collapse

private static ManagementObject CreateServerBinding(ManagementScope scope, 
string hostName, string ip, int port)
{
ManagementClass mc = new ManagementClass(scope, 
new ManagementPath("ServerBinding"), null);
ManagementObject mco = mc.CreateInstance();

mco.Properties["Hostname"].Value = hostName;
mco.Properties["IP"].Value = ip;
mco.Properties["Port"].Value = port;
mco.Put();

return mco;
}
Points of interest

Security. This won't run just like this. Of the millions of things I've tried, there seem to be two things that need to be done. WMI and IIS metabase access.

Windows Server 2003 and IIS 6.0 run ASP.NET under NETWORK SERVICE, by default. But, we're going to use impersonation.

So you want to add this to your web.config:

Collapse

<identity impersonate="true" />

The account used to grant your permission accessing the IIS metaBase will be the IUSR_<servername> account. I will continue to refer to this account just as IUSR_. You know you have to append your server's name.
WMI permission

Go to Control Panel -> Administrative Tools -> Computer Management -> Services & Applications.

Right-click WMI Control, choose Properties.

Click Security.

Open the tree.

Click MicrosoftIISv2.

Click Security.

Click Advanced.

Double click IUSR_ (or add it if it isn't there).

Select 'Apply onto': This namespace and sub-namespaces.

Check all the checkboxes.

Apply and Close all dialogs.
IIS metabase permission

Download and install the IIS 6 Resource Kit.

Run the MetaBase Explorer (find it in the Resource Kit menu under Start).

Open the tree, and right click the first or second node and choose Permissions.

If it complains about the current key inheriting from /, click Yes.

Click IUSR_ or add it.

Check Full Control.

Apply and Close all dialogs.

You should be ready to run with enough permissions.

It would be great if someone with more experience could comment on this and point out how to properly configure IIS and WMI to run this code. As I mentioned earlier, I found this out by trying, so I don't know if this is the optimal solution to the problem.

If someone has any problems running this code, I would like to help more.

 

ASP.NET操作WMI

 
前言

本文介绍了ASP.NET如何通过WMI创建站点、添加虚拟目录和添加主机头。并且已在Windows Server 2003及IIS6的环境下测试通过。

这玩意儿花了老子3天时间才搞定,用了几个小时写代码,而且当中还花了不少时间解决Win32: Access denied error的问题。当然我要指出的是,无论NETWORK SERVER帐户还是IUSR_<servername>帐户都不要设置过大的权限。对于WMI和IIS metabase的安全机理,我还是一无所知的。我只不过解决问题而已。
看代码

首先要从Internet信息服务(IIS)管理器中获取网站标识符,点击“网站”根节点,右侧“标识符”显示的就是网站的ID。默认网站的标识符通常是1。

获取网站标识的功能,我们要用到一个namespace,代码如下:

using System.Management;

下文所有’ServerName’都表示你的服务器名称,或者如果你的代码是本地运行的,也可以用一个点来表示。

创建一个站点,你会用到如下函数。这个函数返回新网站的ID,这样你可以进一步对这个网站进行操作。

public static string CreateWebsite(string serverName, string appPoolName, string ip,string pathToRoot, string hostName, string domainName, int port)
{
ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.Connect;
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope(string.Format(@\\{0}\root\MicrosoftIISv2,
serverName), options);
scope.Connect();
ManagementObject oW3SVC = new ManagementObject(scope,
new ManagementPath(@"IIsWebService='W3SVC'"), null);

ManagementBaseObject[] serverBindings = new ManagementBaseObject[1];
serverBindings[0] = CreateServerBinding(scope,
string.Format("{0}.{1}", hostName, domainName), ip, port);
ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters("CreateNewSite");
inputParameters["ServerComment"] = string.Format("{0}.{1}", hostName, domainName);
inputParameters["ServerBindings"] = serverBindings;
inputParameters["PathOfRootVirtualDir"] = pathToRoot;
ManagementBaseObject outParameter =
oW3SVC.InvokeMethod("CreateNewSite", inputParameters, null);

string siteId = Convert.ToString(
outParameter.Properties["ReturnValue"].Value).Replace(
"IIsWebServer='W3SVC/", "").Replace("'", "");
ManagementObject oWebVirtDir = new ManagementObject(scope,
new ManagementPath(string.Format(
@"IIsWebVirtualDirSetting.Name='W3SVC/{0}/root'", siteId)), null);
oWebVirtDir.Properties["AppFriendlyName"].Value =
string.Format("{0}.{1}", hostName, domainName);
oWebVirtDir.Properties["AccessRead"].Value = true;
oWebVirtDir.Properties["AuthFlags"].Value = 5; // Integrated Windows Auth.
oWebVirtDir.Properties["AccessScript"].Value = true;
oWebVirtDir.Properties["AuthAnonymous"].Value = true;
oWebVirtDir.Properties["AppPoolId"].Value = appPoolName;
oWebVirtDir.Put();

ManagementObject site = new ManagementObject(scope,
new ManagementPath(Convert.ToString(
outParameter.Properties["ReturnValue"].Value)), null);
site.InvokeMethod("Start", null);
return siteId;
}

创建一个虚拟目录:

public static void AddVirtualFolder(string serverName, string websiteId,string name, string path)
{
ManagementScope scope = new ManagementScope(string.Format(@"\\{0}\root\MicrosoftIISV2", serverName));
scope.Connect();

string siteName = string.Format("W3SVC/{0}/Root/{1}", websiteId, name);

ManagementClass mc = new ManagementClass(scope,new ManagementPath("IIsWebVirtualDirSetting"), null);
ManagementObject oWebVirtDir = mc.CreateInstance();

oWebVirtDir.Properties["Name"].Value = siteName;
oWebVirtDir.Properties["Path"].Value = path;
oWebVirtDir.Properties["AuthFlags"].Value = 5; // Integrated Windows Auth.
oWebVirtDir.Properties["EnableDefaultDoc"].Value = true;
// date, time, size, extension, longdate ;
oWebVirtDir.Properties["DirBrowseFlags"].Value = 0x4000003E;
oWebVirtDir.Properties["AccessFlags"].Value = 513; // read script
oWebVirtDir.Put();

ManagementObject mo = new ManagementObject(scope,
new System.Management.ManagementPath("IIsWebVirtualDir='" +
siteName + "'"), null);
ManagementBaseObject inputParameters = mo.GetMethodParameters("AppCreate2");
inputParameters["AppMode"] = 2;
mo.InvokeMethod("AppCreate2", inputParameters, null);
mo = new ManagementObject(scope, new System.Management.ManagementPath(
"IIsWebVirtualDirSetting='" + siteName + "'"), null);
mo.Properties["AppFriendlyName"].Value = name;
mo.Put();
}

给网站添加一个主机头:

public static void AddHostHeader(string serverName, string hostHeader, string ip, int port, string websiteID)
{
ManagementScope scope = new ManagementScope(string.Format(
@"\\{0}\root\MicrosoftIISV2", serverName));
scope.Connect();

string siteName = string.Format("'W3SVC/{0}'", websiteID);

ManagementObject mo = new ManagementObject(scope,
new System.Management.ManagementPath("IIsWebServerSetting=" + siteName), null);
ManagementBaseObject[] websiteBindings =
(ManagementBaseObject[])mo.Properties["ServerBindings"].Value;

ManagementObject mco = CreateServerBinding(scope, hostHeader, ip, port);

ManagementBaseObject[] newWebsiteBindings =
new ManagementBaseObject[websiteBindings.Length+1];
websiteBindings.CopyTo(newWebsiteBindings, 0);
newWebsiteBindings[newWebsiteBindings.Length - 1] = mco;

mo.Properties["ServerBindings"].Value = newWebsiteBindings;

mo.Put();
}

最后别忘了这个函数,它可以为网站绑定一个网络标识。

private static ManagementObject CreateServerBinding(ManagementScope scope,string hostName, string ip, int port)
{
ManagementClass mc = new ManagementClass(scope,
new ManagementPath("ServerBinding"), null);
ManagementObject mco = mc.CreateInstance();

mco.Properties["Hostname"].Value = hostName;
mco.Properties["IP"].Value = ip;
mco.Properties["Port"].Value = port;
mco.Put();

return mco;
}

注意的几点

安全。如果之用上面的那坨代码还不行。我千方百计想让其运行,但貌似忽视了2件事情。访问WMI和IIS metabase。

ASP.NET在Windows Server 2003和IIS6.0上运行默认使用的是NETWORK SERVICE帐户。但是,我们还是要使用客户端模拟。

所以在Web.config中添加下面一个配置:

<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的方法,那就更赞了。记得之前,我都是自己捣鼓出来的,所以我不知道这个方法是不是最佳的方案。

如果你在运行代码的时候碰到任何问题,我愿意效劳。

 
 http://article.yeeyan.org/bilingual/49861

ASP.NET操作WMI的更多相关文章

  1. Asp.Net 操作XML文件的增删改查 利用GridView

    不废话,直接上如何利用Asp.NET操作XML文件,并对其属性进行修改,刚开始的时候,是打算使用JS来控制生成XML文件的,但是最后却是无法创建文件,读取文件则没有使用了 index.aspx 文件 ...

  2. ASP.NET操作ORACLE数据库之模糊查询

    ASP.NET操作ORACLE数据库之模糊查询 一.ASP.NET MVC利用OracleHelper辅助类操作ORACLE数据库 //连接Oracle数据库的连接字符串 string connect ...

  3. asp.net 操作Excel大全

    asp.net 操作Excel大全 转:http://www.cnblogs.com/zhangchenliang/archive/2011/07/21/2112430.html 我们在做excel资 ...

  4. ASP.NET 操作Cookie详解 增加,修改,删除

    ASP.NET 操作Cookie详解 增加,修改,删除 Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密).定义于RFC2109.它 ...

  5. Asp.net操作Excel----NPOI!!!!1

    前言 Asp.net操作Excel已经是老生长谈的事情了,可下面我说的这个NPOI操作Excel,应该是最好的方案了,没有之一,使 用NPOI能够帮助开发者在没有安装微软Office的情况下读写Off ...

  6. Asp.net操作Excel(终极方法NPOI)(转)

    原文:Asp.net操作Excel(终极方法NPOI) 先去官网:http://npoi.codeplex.com/下载需要引入dll(可以选择.net2.0或者.net4.0的dll),然后在网站中 ...

  7. 使用ASP.NET操作IIS7中使用应用程序

    使用ASP.NET操作IIS7中使用应用程序   在最新发布的启明星Portal里,增加了安装程序,下面说一下.NET对IIS7操作.IIS7的操作和IIS5/6有很大的不同,在IIS7里增加了 Mi ...

  8. ASP FSO操作文件(复制文件、重命名文件、删除文件、替换字符串)

    ASP FSO操作文件(复制文件.重命名文件.删除文件.替换字符串)FSO的意思是FileSystemObject,即文件系统对象.FSO对象模型包含在Scripting 类型库 (Scrrun.Dl ...

  9. ASP.NET操作Word的IIS权限配置

    ASP.NET账号在默认情况下是没有权限操作Microsoft Office对象的,如果不进行权限的配置,代码会抛出类似以下的异常: 检索 COM 类工厂中 CLSID 为 {00024500-000 ...

随机推荐

  1. 我关于SecureCRT远程连接失败的问题解决办法

    使用VirtualBox搭建一个ubuntu14.04的系统环境,为了省去主机与虚拟机直接互相直接一直切换的频繁操作,所以想到了使用SecureCRT连接,但是出现了连接问题,问题如下图:

  2. Create a Bootable MicroSD Card

    http://gumstix.org/create-a-bootable-microsd-card.html Create a Bootable MicroSD Card Beginners Note ...

  3. mysql数据库用户和权限管理记录

    一.MySQL用户的基本说明: 1.1 用户的基本结构MySQL的用户:用户名@主机 ■用户名:16个字符以内■主机:可以是主机名.IP地址.网络地址等主机名:www.111cn.net,localh ...

  4. jquery动态移除/增加onclick属性详解

     本文章给大家介绍利用jquery的removeAttr与attr事件来给a标签增加与删除onclick事件的具体操作方法,有需要了解的朋友可参考. 要实现效果:点击链接先去掉onclick属性,3秒 ...

  5. SQL Server数据库学习总结

    经过一段时间的学习,也对数据库有了一些认识,数据库基本是由表,关系,操作组成:对于初学者首先要学的     一图胜“十”言:SQL Server 数据库总结 一个大概的总结 经过一段时间的学习,也对数 ...

  6. (转)Yale CAS + .net Client 实现 SSO(4)

    第一部分:安装配置 Tomcat 第二部分:安装配置 CAS 第三部分:实现 ASP.NET WebForm Client 第四部分:实现基于数据库的身份验证 1.下载 Microsoft JDBC ...

  7. 使用notepad++编辑器

    使用notepad++编辑器 在公司时经常要用到文本编辑器去写jsp文件,之前使用的是sublime text 3,但是觉得不太顺手,于是转用notepad++编辑器. 这个编辑器最吸引我的地方是层次 ...

  8. 走出 null 就是空值的误区,以及变量赋值原理

    先放一张图片作为引入: 这里我用了一个示意图作为讲解: 平时,我们写的变量为什么能在我们调用它的时候就能被我们拿到所用,跟存钱罐一样,你往里面存一元大洋,它里面就有一元大洋,那么我们的变量在被我们创建 ...

  9. Codevs 1231 最优布线问题

    题目描述 Description 学校需要将n台计算机连接起来,不同的2台计算机之间的连接费用可能是不同的.为了节省费用,我们考虑采用间接数据传输结束,就是一台计算机可以间接地通过其他计算机实现和另外 ...

  10. android-support-xxxx.jar NoClassDefFoundError

    当你的项目出现以下红色提示的时候,要小心了,因为很可能因为这个错误而导致解释不通的异常出现. Found 2 versions of android-support-v4.jar in the dep ...