在Windows服务器运维中,当你需要同时部署几十甚至上百个IIS站点时,手动在IIS管理器里一个一个点"添加网站"是极其低效的做法。用PowerShell脚本批量配置IIS站点,本质上就是通过命令行直接调用IIS的配置接口(WebAdministration模块),实现站点创建、绑定、应用程序池分配、目录权限设置等操作的自动化。这套方法不仅速度快、可重复执行,还能把配置写成脚本文件存进版本控制系统,方便团队协作和灾备恢复。
下面我会从环境准备、核心脚本编写、批量操作逻辑、常见问题处理这几个维度,把整套流程讲透。不管你是刚接触PowerShell的运维新人,还是想优化现有部署流程的老手,都能直接拿来用。
一、环境准备:确保服务器具备PowerShell操作IIS的能力在动手写脚本之前,你需要确认两件事:第一,服务器上已经安装了IIS角色;第二,PowerShell的WebAdministration模块可用。Windows Server 2012及以上版本默认自带这个模块,但如果是精简安装的系统,可能需要手动添加。
检查模块是否加载的方法很简单,打开PowerShell(以管理员身份运行),输入以下命令:
Get-Module -ListAvailable WebAdministration
如果返回了模块信息,说明可以直接用。如果没有,执行下面的命令安装IIS管理工具:
Install-WindowsFeature -Name Web-Scripting-Tools
另外,操作IIS配置需要管理员权限,所以所有脚本都要以"以管理员身份运行"的PowerShell窗口执行,否则会报权限不足的错误。这一点很多人踩坑,务必注意。
二、单个IIS站点的PowerShell创建脚本先从最基础的单站点创建讲起,理解了单个站点的参数,后面批量操作就水到渠成了。创建一个IIS站点,核心需要指定四样东西:站点名称、物理路径、绑定信息(IP、端口、域名)、应用程序池名称。
下面是一个完整的单站点创建脚本示例:
Import-Module WebAdministration
$siteName = "MyWebSite"
$physicalPath = "D:\WebSites\MyWebSite"
$bindingInfo = "*:80:www.example.com"
$appPoolName = "MyAppPool"
# 创建物理目录(如果不存在)
if (!(Test-Path $physicalPath)) {
New-Item -ItemType Directory -Path $physicalPath -Force
}
# 创建应用程序池(如果不存在)
if (!(Test-Path "IIS:\AppPools\$appPoolName")) {
New-WebAppPool -Name $appPoolName -Force
}
# 创建站点
New-Website -Name $siteName -PhysicalPath $physicalPath -BindingInformation $bindingInfo -ApplicationPool $appPoolName
Write-Host "站点 $siteName 创建成功" -ForegroundColor Green
这段脚本的逻辑很清晰:先检查目录和应用程序池是否存在,不存在就创建,最后调用New-Website命令完成站点注册。New-Website是WebAdministration模块提供的核心cmdlet,参数含义如下:Name是站点名,PhysicalPath是网站文件存放的文件夹,BindingInformation格式为"IP:端口:主机头",ApplicationPool指定站点运行在哪个应用程序池里。
三、批量创建IIS站点的核心脚本实际运维场景中,你通常会有一个站点清单,可能是Excel表格、CSV文件或者JSON文件。这里我推荐用CSV格式,因为PowerShell原生支持Import-Csv,处理起来最方便。
假设你有一个sites.csv文件,内容如下:
SiteName,PhysicalPath,Binding,AppPool SiteA,D:\Sites\SiteA,*:80:sitea.com,PoolA SiteB,D:\Sites\SiteB,*:80:siteb.com,PoolB SiteC,D:\Sites\SiteC,*:443:sitec.com,PoolC
对应的批量创建脚本如下:
Import-Module WebAdministration
$sites = Import-Csv -Path "C:\Scripts\sites.csv"
foreach ($site in $sites) {
$siteName = $site.SiteName
$physicalPath = $site.PhysicalPath
$binding = $site.Binding
$appPool = $site.AppPool
# 检查并创建物理目录
if (!(Test-Path $physicalPath)) {
New-Item -ItemType Directory -Path $physicalPath -Force
Write-Host "创建目录: $physicalPath" -ForegroundColor Yellow
}
# 检查并创建应用程序池
if (!(Test-Path "IIS:\AppPools\$appPool")) {
New-WebAppPool -Name $appPool -Force
Write-Host "创建应用程序池: $appPool" -ForegroundColor Yellow
}
# 检查站点是否已存在
if (Test-Path "IIS:\Sites\$siteName") {
Write-Host "站点 $siteName 已存在,跳过" -ForegroundColor Cyan
continue
}
# 创建站点
New-Website -Name $siteName -PhysicalPath $physicalPath -BindingInformation $binding -ApplicationPool $appPool
Write-Host "站点 $siteName 创建成功" -ForegroundColor Green
}
Write-Host "批量配置完成" -ForegroundColor Green
这段脚本加了几个实用的判断逻辑:目录不存在就建、应用程序池不存在就建、站点已存在就跳过。这些防御性编程在生产环境中非常重要,避免重复创建导致报错,也避免覆盖已有配置。
四、进阶操作:批量配置SSL证书绑定和目录权限光创建站点还不够,很多场景下你还需要给站点绑SSL证书、设置目录的NTFS权限。这两个操作在批量脚本里也能一并搞定。
绑定SSL证书需要先导入证书到本地证书存储,然后用New-WebBinding命令添加HTTPS绑定。示例代码:
# 假设证书已经导入到本地计算机的"My"存储中,通过thumbprint查找
$cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*example.com*" }
if ($cert) {
New-WebBinding -Name $siteName -Protocol "https" -Port 443 -IPAddress "*" -SslFlags 1
# 将证书绑定到站点(需要用netsh或通过binding的certificateHash属性)
$binding = Get-WebBinding -Name $siteName -Protocol "https"
$binding.AddSslCertificate($cert.Thumbprint, "My")
Write-Host "SSL证书绑定成功" -ForegroundColor Green
} else {
Write-Host "未找到匹配的证书" -ForegroundColor Red
}
设置目录权限方面,需要用到icacls命令或者PowerShell的ACL模块。给IIS_IUSRS用户赋予读取权限的写法:
$acl = Get-Acl $physicalPath
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl.SetAccessRule($rule)
Set-Acl -Path $physicalPath -AclObject $acl
Write-Host "已设置 $physicalPath 的IIS_IUSRS读取权限" -ForegroundColor Green
把这两段逻辑嵌进前面的批量循环里,就能实现"创建站点+绑SSL+设权限"的一条龙自动化部署。
五、批量修改和删除站点的脚本运维不只是创建,还有修改和清理。批量修改站点绑定信息、修改应用程序池的.NET版本、批量删除废弃站点,这些操作同样可以脚本化。
批量修改应用程序池的.NET CLR版本:
Import-Module WebAdministration
$pools = @("PoolA", "PoolB", "PoolC")
foreach ($pool in $pools) {
Set-ItemProperty "IIS:\AppPools\$pool" -Name managedRuntimeVersion -Value "v4.0"
Write-Host "已将 $pool 的.NET版本设为 v4.0" -ForegroundColor Green
}
批量删除站点:
Import-Module WebAdministration
$sitesToRemove = @("OldSite1", "OldSite2", "TestSite")
foreach ($site in $sitesToRemove) {
if (Test-Path "IIS:\Sites\$site") {
Remove-Website -Name $site -Confirm:$false
Write-Host "已删除站点: $site" -ForegroundColor Red
} else {
Write-Host "站点 $site 不存在,无需删除" -ForegroundColor Yellow
}
}
注意Remove-Website加了-Confirm:$false参数,否则每删一个都会弹出确认提示,批量操作时会非常烦人。
六、实际运维中的注意事项和最佳实践第一,脚本执行前一定要做备份。可以在脚本开头加一行导出当前IIS配置:
Export-IISConfiguration -Path "C:\Backup\IIS_Backup_$(Get-Date -Format 'yyyyMMdd').xml"
这样万一脚本跑出问题,可以用Import-IISConfiguration快速恢复。
第二,建议把脚本和配置文件(CSV/JSON)放在统一的目录下,比如C:\Deploy\IIS\,并纳入版本控制。每次修改配置只改CSV文件,脚本本身不动,降低出错概率。
第三,大批量操作时建议加日志记录。在每个关键步骤后面写一行日志到文件,方便事后排查问题:
$logFile = "C:\Deploy\IIS\deploy_log_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt" "$(Get-Date) - 创建站点: $siteName" | Out-File -FilePath $logFile -Append
第四,关于执行策略的问题。如果服务器默认禁止运行脚本,需要先执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser,否则脚本跑不起来。但生产环境中建议用组策略统一管理执行策略,不要每台服务器手动改。
第五,PowerShell脚本虽然强大,但不适合处理特别复杂的逻辑判断。如果你的站点配置涉及大量条件分支(比如根据域名自动选择证书、根据环境变量切换配置),可以考虑把PowerShell和JSON模板结合,或者用更专业的配置管理工具做补充。但对于大多数中小型企业的IIS批量部署需求,PowerShell脚本完全够用,而且学习成本低、上手快。
七、总结用PowerShell批量配置IIS站点,核心就是三步:准备好站点清单数据、写好包含创建/检查/权限设置的脚本逻辑、加上日志和备份机制。这套方案在几十台服务器的集群部署、新环境快速搭建、定期清理废弃站点等场景下效率极高。掌握了WebAdministration模块的常用cmdlet(New-Website、New-WebAppPool、New-WebBinding、Set-ItemProperty、Remove-Website),你就能应对绝大多数IIS自动化运维需求。把脚本写规范、存好版本、跑前备份,这是每个Windows运维都应该养成的习惯。
