本文介紹了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權限設定
-
版權聲明:本文為CSDN部落客「paulfzm」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/paulfzm/article/details/83524045