如何连续安装IIS Server与Hosting Bundle不报错?或等待IIS完全安装?
问题背景
在全新Windows 10 Server上按以下脚本连续安装IIS和.NET Core Hosting Bundle:
Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature -IncludeManagementTools # 目前的临时解决方案,忽略这行 Start-Sleep -Seconds 120 Write-Host "-- Installing Dotnet Hosting Bundle" $ErrorActionPreference = "Stop"; $tempDir = [System.IO.Path]::GetTempPath() $downloadPath = "$tempdir\netCoreHostingBundle.exe"; $DefaultProxy = [System.Net.WebRequest]::DefaultWebProxy; $securityProtocol = @(); $securityProtocol += [Net.ServicePointManager]::SecurityProtocol; $securityProtocol += [Net.SecurityProtocolType]::Tls12; [Net.ServicePointManager]::SecurityProtocol = $securityProtocol; $WebClient = New-Object Net.WebClient; $Uri = 'https://download.visualstudio.microsoft.com/download/pr/0d000d1b-89a4-4593-9708-eb5177777c64/cfb3d74447ac78defb1b66fd9b3f38e0/dotnet-hosting-6.0.6-win.exe'; if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) { $WebClient.Proxy = New-Object Net.WebProxy($DefaultProxy.GetProxy($Uri).OriginalString, $True); }; $WebClient.DownloadFile($Uri, $downloadPath); $arguments = New-Object -TypeName System.Collections.Generic.List[System.String] $arguments.Add("/quiet") $arguments.Add("/norestart") Start-Process -FilePath $downloadPath -ArgumentList $arguments -NoNewWindow -Wait -PassThru -WorkingDirectory $tempDir Write-Host "-- Restarting IIS" Stop-Service W3SVC Start-Service W3SVC Get-Service W3SVC
安装过程无报错,但运行.NET Core应用时出现HTTP Error 500.19 - HRESULT code 0x8007000d错误,原因是Hosting Bundle安装时IIS尚未完全就绪,导致模块注册失败,修复Bundle可解决,但需要更根本的方案。
问题
- 如何从根本上避免该情况发生?
- 如何等待IIS真正安装完成后,再安全安装Hosting Bundle?
解决方案
问题1:根本避免方案
有两种核心思路:
- 先确保IIS完全就绪再安装Hosting Bundle:这是最直接的方式,也是问题2要解决的核心,通过脚本检测IIS安装后的关键状态,而非依赖固定时长的睡眠。
- 添加修复步骤作为兜底:即使安装顺序出现问题,在脚本末尾执行Hosting Bundle的修复命令,强制完成模块注册。命令如下:
# 修复Hosting Bundle Start-Process -FilePath $downloadPath -ArgumentList "/repair /quiet /norestart" -NoNewWindow -Wait -PassThru
问题2:等待IIS完全就绪的方法
不要用固定的Start-Sleep,而是通过检测IIS的核心状态,确保所有组件注册完成后再执行后续步骤:
方法1:检测IIS服务与WMI可用性
IIS安装完成后,W3SVC服务会就绪,同时WMI的IIS命名空间能正常访问。用循环检测实现:
Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature -IncludeManagementTools Write-Host "等待IIS完全就绪..." $iisReady = $false $timeout = 300 # 超时时间,单位秒 $startTime = Get-Date while (-not $iisReady -and ((Get-Date) - $startTime).TotalSeconds -lt $timeout) { # 检测W3SVC服务是否存在且运行 $w3svc = Get-Service -Name W3SVC -ErrorAction SilentlyContinue if ($w3svc -and $w3svc.Status -eq 'Running') { # 检测IIS WMI命名空间是否就绪 try { $null = Get-WmiObject -Namespace "root\WebAdministration" -Class Site -ErrorAction Stop $iisReady = $true } catch { Start-Sleep -Seconds 10 } } else { Start-Sleep -Seconds 10 # 尝试启动服务(如果已安装但未启动) if ($w3svc) { Start-Service W3SVC -ErrorAction SilentlyContinue } } } if (-not $iisReady) { throw "IIS安装超时,未能在$timeout秒内就绪" } # 后续安装Hosting Bundle的代码...
方法2:检测IIS核心配置文件
通过检查IIS的applicationHost.config配置文件是否存在且可正常读取,确认IIS配置系统就绪:
$applicationHostPath = "C:\Windows\System32\inetsrv\config\applicationHost.config" $iisReady = $false $timeout = 300 $startTime = Get-Date while (-not $iisReady -and ((Get-Date) - $startTime).TotalSeconds -lt $timeout) { if (Test-Path $applicationHostPath) { # 尝试读取配置文件,确认IIS服务可处理配置 try { $null = [Microsoft.Web.Administration.ServerManager]::OpenRemote((hostname)) $iisReady = $true } catch { Start-Sleep -Seconds 10 } } else { Start-Sleep -Seconds 10 } } if (-not $iisReady) { throw "IIS配置文件未就绪,超时" }
额外建议
安装Hosting Bundle后,除了重启W3SVC,还可以重启WAS服务(Windows Process Activation Service),确保所有IIS相关组件刷新配置:
Write-Host "-- 重启IIS相关服务" Stop-Service WAS -Force Start-Service WAS Start-Service W3SVC Get-Service WAS, W3SVC
内容的提问来源于stack exchange,提问作者Daniel Habenicht
相关产品推荐
相关产品推荐

