IIS 7.0 引入全新組態系統 (applicationHost.config + web.config) 與管理 API Microsoft.Web.Administration (MWA),取代舊版 System.DirectoryServices (ADSI) 與 WMI。MWA 提供強型別、交易式提交 (CommitChanges())、遠端管理支援,是 ASP.NET Core 應用程式管理 IIS (建立站點、應用程式、應用程式集區、虛擬目錄、SSL 憑證、URL Rewrite 規則) 的標準方式。
dotnet add package Microsoft.Web.Administration (版本對應 IIS 版本,10.0.0.0 通用於 IIS 7~10)<RuntimeIdentifier>win-x64</RuntimeIdentifier> (MWA 需原生 DLL)Impersonation / 執行身分為特定服務帳號並授予 IIS 管理權限
ServerManager (進入點)
└─ Sites (SiteCollection)
└─ Site
├─ Bindings (BindingCollection) : IP:Port:HostHeader, Protocol, Certificate
├─ Applications (ApplicationCollection)
│ └─ Application
│ ├─ Path (虛擬路徑 "/app")
│ ├─ ApplicationPoolName
│ ├─ VirtualDirectories (VirtualDirectoryCollection)
│ │ └─ VirtualDirectory : Path, PhysicalPath
│ └─ ...
└─ ApplicationDefaults : ApplicationPoolName, EnabledProtocols
└─ ApplicationPools (ApplicationPoolCollection)
└─ ApplicationPool
├─ Name, ManagedRuntimeVersion (v4.0 / ""), ManagedPipelineMode (Integrated/Classic)
├─ ProcessModel : IdentityType, UserName, Password, LoadUserProfile, IdleTimeout
├─ Recycling : PeriodicRestart (Time, Requests, Memory, Schedule)
├─ Failure : RapidFailProtection, AutoShutdownExe, OrphanActionExe
└─ CPU : Limit, Action, ResetInterval
└─ WorkerProcesses (即時進程資訊)
└─ GetApplicationHostConfiguration() → Configuration (applicationHost.config 完整編輯)
public void CreateWebsite(string siteName, string physicalPath, string hostHeader, int port = 80, string ip = "*", string appPoolName = null) {
using var server = new ServerManager();
// 1. 確保/建立應用程式集區
string poolName = appPoolName ?? $"{siteName}_AppPool";
if (server.ApplicationPools[poolName] == null) {
var pool = server.ApplicationPools.Add(poolName);
pool.ManagedRuntimeVersion = "v4.0";
pool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
pool.ProcessModel.IdentityType = ProcessModelIdentityType.ApplicationPoolIdentity;
pool.Recycling.PeriodicRestart.Time = TimeSpan.FromHours(24);
}
// 2. 建立站點
var site = server.Sites.Add(siteName, "http", $"{ip}:{port}:{hostHeader}", physicalPath);
site.ApplicationDefaults.ApplicationPoolName = poolName;
site.ServerAutoStart = true;
// 3. 可選:新增 HTTPS 綁定 (需憑證指紋)
// site.Bindings.Add($"{ip}:443:{hostHeader}", certificateHash, "My", SslFlags.Sni);
server.CommitChanges();
}
public void CreateVirtualDirectory(string siteName, string virtualPath, string physicalPath, string appPoolName = null) {
using var server = new ServerManager();
var site = server.Sites[siteName];
if (site == null) throw new InvalidOperationException($"站點 {siteName} 不存在");
var app = site.Applications["/"]; // 根應用程式
// 或建立子應用程式:site.Applications.Add("/subapp", physicalPath);
var vdir = app.VirtualDirectories.Add(virtualPath, physicalPath);
if (!string.IsNullOrEmpty(appPoolName)) app.ApplicationPoolName = appPoolName;
server.CommitChanges();
}
public void ConfigureAppPool(string poolName, Actionconfigure) { using var server = new ServerManager(); var pool = server.ApplicationPools[poolName] ?? throw new ArgumentException("應用程式集區不存在"); configure(pool); server.CommitChanges(); } // 使用範例 ConfigureAppPool("MyAppPool", pool => { pool.ManagedPipelineMode = ManagedPipelineMode.Integrated; pool.ProcessModel.IdleTimeout = TimeSpan.Zero; // 關閉閒置關閉 pool.ProcessModel.LoadUserProfile = true; // 載入用戶設定檔 (需註冊表/憑證存取) pool.Recycling.PeriodicRestart.Memory = 1024 * 1024; // 1GB 重啟 pool.Recycling.PeriodicRestart.Requests = 50000; pool.CPU.Limit = 80000; // 80% CPU 限制 (1/100000) pool.CPU.Action = ProcessorAction.KillW3wp; });
public void AddSslBinding(string siteName, string hostHeader, string certThumbprint, string ip = "*", int port = 443) {
using var server = new ServerManager();
var site = server.Sites[siteName];
var binding = site.Bindings.Add($"{ip}:{port}:{hostHeader}",
Convert.FromHexString(certThumbprint.Replace(" ", "")), "My", SslFlags.Sni);
binding.Protocol = "https";
server.CommitChanges();
}
public void AddRewriteRule(string siteName, string ruleName, string pattern, string actionType, string actionValue, bool stopProcessing = true) {
using var server = new ServerManager();
var config = server.GetApplicationHostConfiguration();
var section = config.GetSection("system.webServer/rewrite/globalRules", siteName); // 或站點層級
var rules = section.GetCollection();
var rule = rules.CreateElement("rule");
rule["name"] = ruleName;
rule["stopProcessing"] = stopProcessing;
var match = rule.GetChildElement("match");
match["url"] = pattern;
var action = rule.GetChildElement("action");
action["type"] = actionType; // Redirect, Rewrite, CustomResponse, AbortRequest
action["url"] = actionValue;
rules.Add(rule);
server.CommitChanges();
}
public void DeleteSiteCompletely(string siteName) {
using var server = new ServerManager();
var site = server.Sites[siteName];
if (site == null) return;
// 1. 停止站點
site.Stop();
// 2. 移除站點 (會自動移除其應用程式與虛擬目錄)
server.Sites.Remove(site);
// 3. 可選:移除專用應用程式集區 (若無其他站點使用)
string poolName = site.ApplicationDefaults.ApplicationPoolName;
if (server.Sites.All(s => s.ApplicationDefaults.ApplicationPoolName != poolName)) {
var pool = server.ApplicationPools[poolName];
if (pool != null) server.ApplicationPools.Remove(pool);
}
server.CommitChanges();
}
system.web/httpModules、httpHandlers),不支援 ASP.NET CoreApplicationPoolIdentity (虛擬帳號 IIS AppPool\{Name}):最安全、無密碼管理、自動建立/清理ProcessModel.IdentityType = SpecificUserServerManager 實例內的所有異動會在 CommitChanges() 時以單一交易寫入 applicationHost.configServerManager 實例的異動非交易性,可能導致組態不一致using 區塊確保釋放// 連接遠端 IIS (需管理服務啟用、防火牆開放 8172、管理使用者授權)
using var server = ServerManager.OpenRemote("server01.contoso.com");
// 或指定認證
var creds = new NetworkCredential("domain\\admin", "password");
using var server = ServerManager.OpenRemote("server01", creds);
aspNetCore 模組 (ANCM) 代管ManagedPipelineMode 必為 Integratedweb.config、*.dll、*.runtimeconfig.json)public interface IServerManagerFacade : IDisposable {
SiteCollection Sites { get; }
ApplicationPoolCollection ApplicationPools { get; }
void CommitChanges();
// ... 其他必要成員
}
// 實作包裝真實 ServerManager
public class RealServerManagerFacade : IServerManagerFacade {
private readonly ServerManager _server = new();
public SiteCollection Sites => _server.Sites;
public ApplicationPoolCollection ApplicationPools => _server.ApplicationPools;
public void CommitChanges() => _server.CommitChanges();
public void Dispose() => _server.Dispose();
}
// 測試用 In-Memory Fake
public class FakeServerManagerFacade : IServerManagerFacade {
public SiteCollection Sites { get; } = new FakeSiteCollection();
public ApplicationPoolCollection ApplicationPools { get; } = new FakeAppPoolCollection();
public void CommitChanges() { /* 驗證狀態 */ }
public void Dispose() { }
}
Microsoft.Web.Administration 是 IIS 程式化管理的基石,掌握其物件階層、交易模型、管線模式差異、憑證綁定、遠端管理,能讓部署自動化、藍綠發布、多租戶隔離、基礎設施即代碼 等進階場景落地。建議將常用操作封裝為 冪等的領域服務 (如 IisProvisioningService),配合單元測試與 CI/CD 管線,實現「基礎設施即代碼」的可靠交付。