服务公告

服务公告 > 综合新闻 > IIS 自动化-星耀云

IIS 自动化-星耀云

发布时间:2026-04-28 10:02
IIS自动化:PowerShell脚本实现Web服务器批量部署、配置、备份全流程实战。告别手动操作,一套脚本搞定日常运维80%的工作。

一、前言

干了10年运维,手动管理IIS站点简直是噩梦——环境部署要2小时,迁移10个网站要加班到半夜,每次重装系统从头配置更是崩溃。Windows Server的IIS其实自带强大的自动化能力,PowerShell+WebAdministration模块能完成几乎所有图形界面的操作。这篇聊透IIS自动化,从单站点到批量部署,手把手给出生产级脚本。

二、操作步骤

步骤1:确认IIS管理模块可用

开始之前先验证WebAdministration模块是否加载,这是所有IIS自动化操作的基础。

# 检查模块是否已导入 Get-Module -ListAvailable WebAdministration # 如果未加载,手动导入 Import-Module WebAdministration # 验证模块状态 Get-Module WebAdministration | Select-Object Name, Version

预期输出:

Name Version ---- ------- WebAdministration 1.0.0.0
这是核心步骤,仔细看

步骤2:创建Application Pool(应用池)

应用池是IIS的核心隔离单元,自动化脚本里先创建它,后续绑定网站时直接引用。

# 创建新的Application Pool New-WebAppPool -Name "ProductionApiPool" # 配置应用池参数(.NET CLR版本、管道模式、32位支持) Set-ItemProperty "IIS:\AppPools\ProductionApiPool" -Name "managedRuntimeVersion" -Value "v4.0" Set-ItemProperty "IIS:\AppPools\ProductionApiPool" -Name "managedPipelineMode" -Value "Integrated" Set-ItemProperty "IIS:\AppPools\ProductionApiPool" -Name "enable32BitAppOnWin64" -Value "False" # 设置回收策略(按时间周期回收) Set-ItemProperty "IIS:\AppPools\ProductionApiPool" -Name "recycling.periodicRestart.time" -Value "01:00:00" # 立即启动应用池 Start-WebAppPool -Name "ProductionApiPool" # 验证创建结果 Get-WebAppPoolState -Name "ProductionApiPool"

预期输出:

Started
搞定这步之后,继续往下看

步骤3:创建Website并绑定物理路径

网站创建时同步设置物理路径、绑定协议、应用池,一个命令搞定。

# 确保物理路径存在 $sitePath = "C:\inetpub\production_api" if (!(Test-Path $sitePath)) { New-Item -ItemType Directory -Path $sitePath -Force } # 创建网站并绑定到80端口 New-Website -Name "ProductionApi" -PhysicalPath $sitePath -ApplicationPool "ProductionApiPool" -Port 80 -HostHeader "api.example.com" # 查看已创建的绑定信息 Get-WebBinding -Name "ProductionApi" | Select-Object protocol, bindingInformation

预期输出:

protocol bindingInformation -------- ------------------ http *:80:api.example.com
这是核心步骤,仔细看

步骤4:配置HTTPS绑定(SSL证书)

生产环境必须走HTTPS,这步演示如何用已有证书创建443绑定。

⚠️ 注意:执行此操作需要服务器上已安装有效的SSL证书
# 获取本地计算机存储中的证书(按域名筛选) $certThumbprint = (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*api.example.com*" }).Thumbprint | Select-Object -First 1 # 添加HTTPS绑定到443端口 New-WebBinding -Name "ProductionApi" -Protocol "https" -Port 443 -HostHeader "api.example.com" # 将证书绑定到该站点 Get-WebBinding -Name "ProductionApi" -Protocol "https" | Set-SslCertificate -Thumbprint $certThumbprint # 验证绑定结果 Get-WebBinding -Name "ProductionApi"

预期输出:

Name ID State PhysicalPath bindings ---- -- ----- ------------ -------- ProductionApi 4 Started C:\inetpub\production_api {http/*:80:api.example.com, https/*:443:api.example.com}
搞定这步之后,继续往下看

步骤5:批量配置站点参数(默认文档、认证、压缩)

站点创建后需要统一配置安全策略和性能参数,用批量脚本一次性设置到位。

# 配置默认文档优先级 Set-WebConfigurationProperty -Filter "/system.webServer/defaultDocument" -Name "files" -Value @('index.html', 'default.aspx', 'index.htm') -PSPath "IIS:\Sites\ProductionApi" # 启用匿名认证(生产环境根据需要调整) Set-WebConfigurationProperty -Filter "/system.webServer/security/authentication/anonymousAuthentication" -Name "enabled" -Value "True" -PSPath "IIS:\Sites\ProductionApi" # 启用静态内容压缩(提升访问速度) Set-WebConfigurationProperty -Filter "/system.webServer/urlCompression" -Name "doStaticCompression" -Value "True" -PSPath "IIS:\Sites\ProductionApi" # 设置请求过滤(禁止访问敏感目录) Add-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering" -Name "denyUrlSequences" -PSPath "IIS:\Sites\ProductionApi" -Value @{sequence=".."} Add-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering" -Name "denyUrlSequences" -PSPath "IIS:\Sites\ProductionApi" -Value @{sequence="./"} # 验证配置结果 Get-WebConfigurationProperty -Filter "/system.webServer/defaultDocument" -Name files -PSPath "IIS:\Sites\ProductionApi"

预期输出:

PSPath : IIS:\Sites\ProductionApi PSParentPath : IIS:\Sites\ProductionApi PSChildName : defaultDocument PSProvider : IIS Value : {index.html, default.aspx, index.htm} IsProtected : False
这一步搞定了,我们继续

步骤6:IIS配置备份与导出

⚠️ 重要:生产环境变更前务必执行备份,防止配置错误导致服务中断

# 使用appcmd备份配置(IIS自带工具) & "C:\Windows\System32\inetsrv\appcmd" add backup "PreDeployment_Backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')" # 查看所有备份列表 & "C:\Windows\System32\inetsrv\appcmd" list backup # 导出所有站点配置为XML(方便版本管理) $backupPath = "C:\IIS_Backups\Sites_$(Get-Date -Format 'yyyyMMdd').xml" & "C:\Windows\System32\inetsrv\appcmd" list site /xml | Out-File $backupPath # 备份应用池配置单独存放 $poolBackupPath = "C:\IIS_Backups\AppPools_$(Get-Date -Format 'yyyyMMdd').xml" & "C:\Windows\System32\inetsrv\appcmd" list apppool /xml | Out-File $poolBackupPath Write-Host "备份完成,文件位置:$backupPath"

预期输出:

BACKUP "PreDeployment_Backup_20250120_143052" BACKUP "PreDeployment_Backup_20250120_110000" 备份完成,文件位置:C:\IIS_Backups\Sites_20250120.xml
搞定这步之后,继续往下看

步骤7:批量部署脚本封装(生产级模板)

把前面的操作封装成函数,实现一行命令部署整套站点,包含异常处理和日志记录。

function Deploy-IISSite { param( [Parameter(Mandatory=$true)] [string]$SiteName, [Parameter(Mandatory=$true)] [string]$PhysicalPath, [Parameter(Mandatory=$true)] [string]$AppPoolName, [string]$HostHeader = "", [string]$DotNetVersion = "v4.0", [int]$Port = 80 ) # 创建物理路径 if (!(Test-Path $PhysicalPath)) { New-Item -ItemType Directory -Path $PhysicalPath -Force | Out-Null Write-Host "[INFO] 创建目录: $PhysicalPath" } # 创建或获取应用池 if (!(Test-Path "IIS:\AppPools\$AppPoolName")) { New-WebAppPool -Name $AppPoolName Set-ItemProperty "IIS:\AppPools\$AppPoolName" -Name "managedRuntimeVersion" -Value $DotNetVersion Write-Host "[INFO] 创建应用池: $AppPoolName" } # 创建网站 if (Get-Website -Name $SiteName -ErrorAction SilentlyContinue) { Write-Host "[WARN] 网站已存在,跳过创建" } else { $bindingInfo = "*`:$Port`:$HostHeader" if ($HostHeader) { New-Website -Name $SiteName -PhysicalPath $PhysicalPath -ApplicationPool $AppPoolName -BindingInformation $bindingInfo } else { New-Website -Name $SiteName -PhysicalPath $PhysicalPath -ApplicationPool $AppPoolName -Port $Port } Write-Host "[INFO] 创建网站: $SiteName" } Write-Host "[SUCCESS] 部署完成: $SiteName" } # 使用示例(生产环境请替换实际值) Deploy-IISSite -SiteName "MyNewSite" -PhysicalPath "C:\inetpub\MyNewSite" -AppPoolName "MyNewSitePool" -HostHeader "newsite.example.com"

预期输出:

[INFO] 创建目录: C:\inetpub\MyNewSite [INFO] 创建应用池: MyNewSitePool [INFO] 创建网站: MyNewSite [SUCCESS] 部署完成: MyNewSite
搞定这步之后,继续往下看

步骤8:多服务器远程批量操作

管理多台IIS服务器时,用PowerShell Remoting实现一台控全局,适合中大型运维场景。

⚠️ 注意:远程操作需要WinRM服务运行,且执行账号有目标服务器管理员权限
# 定义IIS服务器列表 $iisServers = @("web01.example.com", "web02.example.com", "web03.example.com") # 在所有服务器上安装WebAdministration模块并执行站点部署 Invoke-Command -ComputerName $iisServers -Credential (Get-Credential) -ScriptBlock { param($SiteName, $PhysicalPath, $AppPoolName) Import-Module WebAdministration if (!(Test-Path "IIS:\AppPools\$AppPoolName")) { New-WebAppPool -Name $AppPoolName } if (!(Get-Website -Name $SiteName -ErrorAction SilentlyContinue)) { New-Website -Name $SiteName -PhysicalPath $PhysicalPath -ApplicationPool $AppPoolName -Port 80 } } -ArgumentList "CentralizedSite", "D:\WebApps\CentralizedSite", "CentralizedPool" # 查看所有服务器上的站点状态 Invoke-Command -ComputerName $iisServers -Credential (Get-Credential) -ScriptBlock { Get-Website | Select-Object Name, State, PhysicalPath }

预期输出:

ComputerName Name State PhysicalPath ------------ ---- ----- ------------ web01 CentralizedSite Started D:\WebApps\CentralizedSite web02 CentralizedSite Started D:\WebApps\CentralizedSite web03 CentralizedSite Started D:\WebApps\CentralizedSite

三、常见问题FAQ

Q1: 报错"Import-Module WebAdministration"失败,模块找不到怎么办?

这是因为IIS管理脚本工具没装。Windows Server上跑这个命令没反应的直接去服务器管理器→添加角色→Web服务器(IIS)→勾选"IIS管理脚本和工具"。别问我怎么知道这个坑的,有次线上服务器换了镜像,部署脚本跑不通,查了半天才发现是这玩意儿没装。装完记得重开PowerShell再试。

Q2: 用PowerShell创建的网站能直接在IIS管理器里看到吗?会不会有兼容性问题?

完全兼容,图形界面和命令行操作的是同一个配置数据库(applicationHost.config),没有任何区别。IIS管理器里看到的和你用Get-Website查出来的永远是一致的。有个需要注意的地方:图形界面改了配置后,PowerShell这边要重新Import-Module才能读到最新状态,别以为卡了。另外如果你用PowerShell远程操作,某些服务器需要设置TrustedHosts才能连上。

Q3: appcmd备份和PowerShell备份哪个更靠谱?

老实说,都用上更保险。appcmd备份的是iisconfig格式,恢复的时候直接appcmd restore backup就行,适合紧急回滚场景。PowerShell导出XML的好处是可以放进Git做版本管理,diff能看到每次改了什么。我现在的做法是:自动化脚本里同时执行两种备份,appcmd做快速恢复用,XML文件提交到配置仓库做审计追踪。两种备份策略配合才是生产级做法。

Q4: 批量部署的时候,怎么判断是新建还是更新已有站点?

上面示例脚本里用了-ErrorAction SilentlyContinue配合Get-Website判断,这种方式有个问题:站点不存在时会抛异常被静默捕获。更稳的做法是用Test-Path "IIS:\Sites\$SiteName",不抛异常直接返回布尔值。更新已有站点时建议先检查配置差异,别直接覆盖,要不会把运行中的配置改乱了。我一般会在脚本里加个-WhatIf参数预览要改的内容,确认无误再加-Confirm才真正执行。

Q5: 能不能用这些脚本管理Azure App Service或AWS的Windows实例?

本地IIS和云上的管理接口完全不同。Azure App Service用的是Kudu和REST API,PowerShell里用Invoke-RestMethod调Azure PowerShell或者Az模块。AWS的Windows EC2还是原生IIS,但得先解决远程连接问题——Session Manager或者Direct Connect之类的。核心思路不变:拿到管理凭证,找对API端点,剩下的就是脚本逻辑的事。

四、总结

核心要点回顾:

  • PowerShell的WebAdministration模块是IIS自动化的基石,掌握Import-Module、Get-Website、New-WebAppPool这几个核心Cmdlet就能应对80%场景
  • 生产环境必须先备份再操作,appcmd备份+XML导出双重机制缺一不可
  • 批量部署脚本要封装成函数并加入异常处理和日志,-WhatIf参数是防止手滑的保命符
  • 多服务器管理用Invoke-Command实现远程执行,配合WinRM和TrustedHosts配置
  • SSL证书绑定用Thumbprint定位,Get-ChildItem的筛选条件要写精确,避免绑定到错误证书

延伸阅读:

  • Microsoft官方文档:WebAdministration模块Cmdlet完整参考
  • Microsoft IIS Team Blog:生产环境IIS配置最佳实践
  • PowerShell Gallery:IIS相关的community模块(如IISDeployment这个包)