管理 IIS 主要有兩種方式:ADSI (Active Directory Service Interfaces) 和 WMI (Windows Management Instrumentation)。受系統限制 (早期 IIS 版本),本文採用 ADSI 實現。注意:ADSI 操作建議在本地或同網段執行,遠程調用佔用較大帶寬。IIS 6+ 推薦使用 WMI (System.Management) 或 Microsoft.Web.Administration (IIS 7+) 獲得更好體驗。
靜態類封裝 IIS 基礎操作:創建/刪除網站、啟動/停止、綁定檢查、ID 分配。使用 System.DirectoryServices.DirectoryEntry 訪問 IIS 配置庫 (IIS://localhost/w3svc)。
public static string HostName { get; set; } = "localhost";
public static string UserName { get; set; }
public static string PassWord { get; set; }
public static void RemoteConfig(string host, string user, string pwd)
{
HostName = host; UserName = user; PassWord = pwd;
}
public static DirectoryEntry GetDirectoryEntry(string path)
{
if (string.IsNullOrEmpty(UserName))
return new DirectoryEntry(path); // 本地集成認證
else
// 遠程認證:用戶名格式建議 "domain\\user" 或 "user@domain"
return new DirectoryEntry(path, UserName, PassWord, AuthenticationTypes.Secure);
}
public static void CreateNewWebSite(NewWebSiteInfo siteInfo)
{
// 1. 檢查綁定衝突
if (!EnsureNewSiteEnavaible(siteInfo.BindString))
throw new DuplicatedWebSiteException($"綁定衝突: {siteInfo.BindString}");
// 2. 獲取根節點並分配新站點 ID
string rootPath = $"IIS://{HostName}/w3svc";
using (DirectoryEntry root = GetDirectoryEntry(rootPath))
{
string newSiteId = GetNewWebSiteID(); // 獲取最小可用正整數 ID
using (DirectoryEntry site = root.Children.Add(newSiteId, "IISWebServer"))
{
site.CommitChanges(); // 必須先提交創建節點
// 3. 設置核心屬性
site.Properties["ServerBindings"].Value = siteInfo.BindString; // "IP:Port:HostHeader"
site.Properties["ServerComment"].Value = siteInfo.CommentOfWebSite; // 站點描述
site.CommitChanges();
// 4. 創建根虛擬目錄
using (DirectoryEntry vdir = site.Children.Add("root", "IISWebVirtualDir"))
{
vdir.CommitChanges();
vdir.Properties["Path"].Value = siteInfo.WebPath; // 物理路徑
vdir.CommitChanges();
}
}
}
}
public static void DeleteWebSiteByName(string siteName)
{
string siteId = GetWebSiteNum(siteName); // 通過綁定或描述匹配
string sitePath = $"IIS://{HostName}/w3svc/{siteId}";
using (DirectoryEntry site = GetDirectoryEntry(sitePath))
using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
{
root.Children.Remove(site);
root.CommitChanges();
}
}
public static void StartWebSite(string siteName)
{
string siteId = GetWebSiteNum(siteName);
using (DirectoryEntry site = GetDirectoryEntry($"IIS://{HostName}/w3svc/{siteId}"))
site.Invoke("Start", null);
}
public static void StopWebSite(string siteName)
{
string siteId = GetWebSiteNum(siteName);
using (DirectoryEntry site = GetDirectoryEntry($"IIS://{HostName}/w3svc/{siteId}"))
site.Invoke("Stop", null);
}
public static bool EnsureNewSiteEnavaible(string bindStr)
{
using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
{
foreach (DirectoryEntry child in root.Children)
{
if (child.SchemaClassName == "IISWebServer"
&& child.Properties["ServerBindings"].Value?.ToString() == bindStr)
return false;
}
}
return true;
}
public static string GetWebSiteNum(string siteName)
{
Regex regex = new Regex(siteName); // 支持正則匹配
using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
{
foreach (DirectoryEntry child in root.Children)
{
if (child.SchemaClassName != "IISWebServer") continue;
string binding = child.Properties["ServerBindings"].Value?.ToString();
if (!string.IsNullOrEmpty(binding) && regex.IsMatch(binding))
return child.Name;
string comment = child.Properties["ServerComment"].Value?.ToString();
if (!string.IsNullOrEmpty(comment) && regex.IsMatch(comment))
return child.Name;
}
}
throw new NotFoundWebSiteException($"未找到站點: {siteName}");
}
public static string GetNewWebSiteID()
{
var ids = new List();
using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
{
foreach (DirectoryEntry child in root.Children)
{
if (child.SchemaClassName == "IISWebServer"
&& int.TryParse(child.Name, out int id))
ids.Add(id);
}
}
ids.Sort();
int nextId = 1;
foreach (int id in ids)
{
if (id == nextId) nextId++;
else break;
}
return nextId.ToString();
}
public struct NewWebSiteInfo
{
public string HostIP; // 綁定 IP (如 "192.168.1.100" 或 "All Unassigned" 用 "")
public string PortNum; // 端口 (通常 "80")
public string DescOfWebSite; // 主機頭 (如 "www.example.com")
public string CommentOfWebSite; // 站點描述/名稱
public string WebPath; // 物理路徑 (如 "E:\\WebSites\\MySite")
public NewWebSiteInfo(string ip, string port, string desc, string comment, string path)
{
HostIP = ip; PortNum = port; DescOfWebSite = desc;
CommentOfWebSite = comment; WebPath = path;
}
// IIS ServerBindings 格式: "IP:Port:HostHeader"
public string BindString => $"{HostIP}:{PortNum}:{DescOfWebSite}";
public string Comment => CommentOfWebSite;
public string Path => WebPath;
}
// 本地管理
IISAdminLib.CreateNewWebSite(new NewWebSiteInfo("", "8080", "test.local", "測試站點", @"E:\Sites\Test"));
IISAdminLib.StartWebSite("測試站點");
// 遠程管理 (需管理員權限)
IISAdminLib.RemoteConfig("192.168.1.50", "admin", "password");
IISAdminLib.StopWebSite("OldSite");
| IIS 版本 | 推薦技術 | 命名空間/套件 |
|---|---|---|
| IIS 6.0 (WS2003) | WMI / ADSI | System.Management / System.DirectoryServices |
| IIS 7.0+ (WS2008+) | Microsoft.Web.Administration | Microsoft.Web.Administration.dll (GAC/IIS 安裝目錄) |
| ASP.NET Core | IWebHost / Kestrel / IIS Integration | Microsoft.AspNetCore.Hosting |
Microsoft.Web.Administration 物件模型更豐富、類型安全、性能更好,是 IIS 7+ 管理的首選。示例:
using Microsoft.Web.Administration;
using (ServerManager sm = new ServerManager())
{
Site site = sm.Sites.Add("NewSite", "http", "*:8080:", @"E:\Sites\NewSite");
sm.CommitChanges();
}
本文提供了基於 ADSI 的 IIS 管理完整類庫,覆蓋站點增刪啟停、綁定檢查、ID 分配等核心功能。理解 DirectoryEntry 操作 IIS 配置庫 (Metabase) 的模式,對維護舊系統、自動化部署腳本極有價值。新項目強烈建議遷移至 Microsoft.Web.Administration 或容器化部署模式。