简介这份离线安装包面向需要在无外网环境中为 Windows Server 2012 R2 部署或更新 IIS 的 IT 管理员与运维人员解决内网、隔离机房或严格网络安全策略下无法在线拉取系统组件的问题。压缩包共 1568 个文件约 99.04MB以 dll 动态库、resx 资源文件、exe 可执行程序为主辅以 aspx 页面、config 配置、sql 脚本、browser 浏览器定义及 tlb、targets 等组件描述文件完整覆盖 IIS 角色与 Side-by-Side 组件存储所需内容。已有 572 人学习下载说明其在离线部署场景中具备一定参考价值。资源保留了 Web 服务器、应用程序池、身份验证、FTP 服务与 Web 部署工具等模块的原始组件结构便于管理员借助 DISM 从本地源添加角色、补齐 .NET 相关依赖并在安装后用系统命令核验功能状态适合作为内网服务器搭建与运维的常备组件库。1. 内网机房里那台 IIS 装不上的服务器问题往往不在 IIS 本身一台跑着 Windows Server 2012 R2 的机器网卡灯亮着但就是连不上外网更别提从服务器管理器里点「添加角色和功能」在线拉 IIS 了。点下去转两圈弹一个「无法从 Windows 更新下载文件」或者干脆卡在「正在搜索功能」不动。这种场景在隔离网、生产前置机、测试沙箱里太常见了运维和开发都遇到过。这份 IIS 离线安装包要解决的就是这件事把 IIS 及其依赖的角色服务、管理工具、.NET 扩展组件以离线源的形式一次性备齐让没有外网、甚至没有域环境的机器也能把 IIS 完整装起来。适合谁负责内网服务器交付的运维、需要在隔离环境搭 Web 服务的后端、以及做安全测试靶场搭建的工程师。它不是什么黑科技本质是把 Windows 的按需功能Features on Demand源做成本地可挂载的目录但恰恰是这一步翻车的人最多。2. 离线源到底装了什么IIS 角色拆解与依赖关系2.1 IIS 不是一个角色是一组角色服务的集合很多人以为「装 IIS」就是勾一个 Internet Information Services 复选框实际上在 Windows Server 2012 R2 里IIS 是一个父角色底下挂着几十个角色服务Role Service比如 Web 服务器核心、静态内容、默认文档、目录浏览、HTTP 错误、ASP.NET 4.5、.NET 扩展性、ISAPI 扩展、ISAPI 筛选器、请求筛选、Windows 身份验证、管理控制台、管理服务、FTP 服务等等。离线安装包的价值不在于「有没有 IIS 这个角色」而在于它是否把你要勾的那些子服务对应的源文件都备齐了。缺一个 ASP.NET 4.5 的源安装就会在进度条 60% 的地方回滚日志里写「源文件找不到」。常见做法是先在一台能联网、系统版本完全一致的机器上用Install-WindowsFeature把目标角色装一遍然后从C:\Windows\WinSxS和C:\Windows\System32\ServerManager相关的按需功能目录里把源抽出来或者直接用Export-WindowsDriver那套思路做 Features on Demand 的 side-by-side 源。这份离线包如果结构规范根目录下应该能看到sources\sxs这样的目录里面按组件名分文件夹存放.cab和.mum文件。2.2 为什么不能直接拷 WinSxS 了事WinSxS 是组件存储里面有大量硬链接和版本化目录直接整目录拷贝到目标机再指过去十有八九会报「组件存储损坏」或者「源与目标版本不匹配」。正确的离线源必须是「按需功能源」格式也就是用DISM的/Source参数能识别的那种布局。判断方法很简单在目标机上跑一条DISM /Online /Get-FeatureInfo /FeatureName:IIS-WebServerRole看它输出的「源」路径指向哪里离线包就要能对上那个结构。我一般会先确认三件事再动手目标机的系统版本号winver看 6.3.9600、语言zh-CN 还是 en-US源必须同语言、以及补丁级别。2012 R2 的源在不同累积更新下会有细微差异跨补丁级别用源轻则警告重则失败。2.3 离线包目录结构对照表拿到包之后别急着装先按下面这张表核对目录缺哪个后面就会在哪一步卡住目录/文件作用缺失后的典型现象sources\sxs\按需功能源根目录DISM 报 0x800f0906 源文件无法下载sources\sxs\microsoft-windows-iis-*IIS 各角色服务组件安装到对应子服务时回滚sources\sxs\microsoft-windows-netfx*.NET Framework 3.5/4.5 相关ASP.NET 注册失败站点 500.19sources\sxs\microsoft-windows-was-*Windows 进程激活服务WAS 起不来应用池无法启动Tools\或根目录脚本安装辅助脚本需要手工敲 DISM容易漏参数这张表是我踩过坑之后自己整理的尤其是netfx那一行很多人装完 IIS 发现 ASP.NET 页面跑不起来回头查半天其实是 .NET 的按需功能源没跟着一起备。3. 用 DISM 挂源装 IIS命令、参数与验证3.1 先把离线包放到本地固定路径不要从 U 盘或网络共享直接指源安装过程中源路径断开是经典翻车点。先把整个包拷到目标机的本地盘比如D:\IIS_Offline并确认当前账户是本地管理员。然后以管理员身份开 PowerShell先做一次源可用性探测# 确认离线源目录存在且包含 sxs 子目录 $src D:\IIS_Offline\sources\sxs if (Test-Path $src) { Write-Host 源目录存在文件数 (Get-ChildItem $src -Recurse -File).Count } else { Write-Error 源目录不存在检查拷贝是否完整 } # 查看目标机上 IIS 父角色的当前状态与可用源 DISM /Online /Get-FeatureInfo /FeatureName:IIS-WebServerRole第一段是防呆确认拷贝没断在半路第二段Get-FeatureInfo会输出该功能的当前状态Enabled/Disabled以及系统认为可用的源路径。如果这里显示的源路径和你放的路径不一致说明系统还没认这个源后面/Source参数必须显式指定不能指望它自动找。3.2 用 Install-WindowsFeature 指定源安装比 DISM 更顺手的是 PowerShell 的Install-WindowsFeature它支持-Source和-Restart还能一次勾多个子服务。下面这条是我在隔离环境里最常用的组合覆盖 Web 核心、静态内容、ASP.NET 4.5、管理控制台和 IIS 管理服务# 指定离线源安装 IIS 及常用子服务 Install-WindowsFeature -Name Web-Server, Web-Static-Content, Web-Default-Doc, Web-Http-Errors, Web-Asp-Net45, Web-Net-Ext45, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Console, Web-Mgmt-Service -Source D:\IIS_Offline\sources\sxs -Restart:$false -Verbose参数逐个说清楚-Name后面跟的是角色服务的技术名不是显示名写错一个就整条失败-Source必须指到sxs这一层指到上一级sources会报源无效-Restart:$false表示先不自动重启方便你看日志如果装了 .NET 相关组件系统可能仍要求重启这时手动重启更可控-Verbose会打印每个子组件的安装进度卡住时能立刻定位是哪个组件在等源。装完立刻验证别等配站点时才发现问题# 验证 IIS 角色与关键子服务状态 Get-WindowsFeature -Name Web-Server, Web-Asp-Net45, Web-Mgmt-Console | Select-Object Name, InstallState # 确认 W3SVC 服务已注册并启动 Get-Service W3SVC | Select-Object Name, Status, StartTypeInstallState应该是InstalledW3SVC应该是Running。如果W3SVC是Stopped且启动报错多半是 WASWindows 进程激活服务没装全回到 2.3 的表里查was-*组件。3.3 用 DISM 兜底当 PowerShell 命令不认源时有些精简版或经过第三方封装的 2012 R2 镜像Install-WindowsFeature会报「源不可用」但 DISM 反而能过。这时用 DISM 的/Enable-Feature逐条来# 用 DISM 启用 IIS 核心与 ASP.NET 4.5指定本地源 DISM /Online /Enable-Feature /FeatureName:IIS-WebServerRole /Source:D:\IIS_Offline\sources\sxs /All DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET45 /Source:D:\IIS_Offline\sources\sxs /All DISM /Online /Enable-Feature /FeatureName:IIS-ManagementConsole /Source:D:\IIS_Offline\sources\sxs /All/All的作用是自动启用父功能比如你只点名IIS-ASPNET45它会顺带把依赖的IIS-WebServer拉起来省得手工排依赖顺序。代价是它可能多装一些你没打算要的组件隔离环境里问题不大生产机上建议还是显式列全。DISM 的日志在C:\Windows\Logs\DISM\dism.log失败时直接搜0x800f开头的错误码比看 PowerShell 的红字有用。4. 装完 IIS 之后的配置收尾应用池、绑定与权限4.1 应用池的 .NET 版本别配错IIS 装好只是有了壳站点能不能跑取决于应用池。2012 R2 默认应用池是DefaultAppPool托管管道模式是集成Integrated.NET CLR 版本默认 v4.0。如果你要跑的是老 ASP.NET 2.0 应用得新建一个应用池并把 CLR 版本改成 v2.0同时确认 .NET 3.5 的按需功能源也装了否则应用池一启动就报「无法加载 ISAPI 筛选器」。# 导入 WebAdministration 模块并新建应用池 Import-Module WebAdministration New-WebAppPool -Name AppPool_Demo Set-ItemProperty IIS:\AppPools\AppPool_Demo -Name managedRuntimeVersion -Value v4.0 Set-ItemProperty IIS:\AppPools\AppPool_Demo -Name managedPipelineMode -Value Integrated # 建站点并绑定到 8080 端口物理路径指向本地目录 New-Item -ItemType Directory -Path D:\www\demo -Force New-WebSite -Name DemoSite -Port 8080 -PhysicalPath D:\www\demo -ApplicationPool AppPool_DemomanagedRuntimeVersion写v4.0对应 .NET 4.x写v2.0对应 2.0/3.5managedPipelineMode选Integrated还是Classic取决于应用是否依赖老式 ISAPI 行为拿不准就先 Integrated跑不通再切 Classic 对比。New-WebSite的-Port别和已有站点冲突2012 R2 上默认站点占 80测试环境用 8080 更省事。4.2 权限与防火墙两个最容易被忽略的收尾站点建好、浏览器访问 403 或超时九成是这两件事。第一物理路径的 NTFS 权限要给IIS_IUSRS组读权限应用池标识如果是ApplicationPoolIdentity实际生效的是虚拟账户给组权限最稳。第二Windows 防火墙默认拦入站 8080得手动放行# 给站点目录授予 IIS_IUSRS 读权限 icacls D:\www\demo /grant IIS_IUSRS:(OI)(CI)(RX) /T # 放行 8080 入站仅测试环境生产按最小化原则收紧 New-NetFirewallRule -DisplayName IIS-Demo-8080 -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allowicacls里(OI)(CI)表示对象继承和容器继承(RX)是读加执行/T递归到子目录。防火墙规则只放行指定端口别图省事关整个防火墙隔离环境里也有横向风险。5. 避坑清单离线装 IIS 最常见的五个翻车点5.1 现象安装进度到一半回滚日志报 0x800f0906原因离线源里缺某个子组件的.cab或者源的语言与系统语言不一致。2012 R2 中文版必须用 zh-CN 的源拿 en-US 的源去装DISM 会认为「源中找不到适用组件」。解决先看C:\Windows\Logs\DISM\dism.log里最后失败的功能名回到离线包核对对应目录是否存在语言不一致就换同语言源别试图混用。5.2 现象Install-WindowsFeature报「源不可用」但目录明明在原因-Source指错了层级指到了sources而不是sources\sxs或者路径里有空格没加引号再或者当前 PowerShell 不是管理员会话。解决路径统一用引号包住确认指到sxs用whoami /groups确认在 Administrators 组且已提权。还不行就换 DISM 逐条启用DISM 对路径的容错稍好。5.3 现象IIS 装好了ASP.NET 页面报 500.19原因web.config里引用了未安装的模块典型是 URL 重写模块或 ASP.NET 4.5 的某个 handler 没装全。离线包如果只装了 Web 核心没装Web-Asp-Net45就会这样。解决Get-WindowsFeature Web-Asp-Net45看状态没装就补装补装时源路径照旧。500.19 的错误页会直接写出缺哪个模块名照着补即可。5.4 现象站点能访问静态页但应用池一启动就停原因应用池的标识账户没有权限访问站点目录或者 .NET CLR 版本与应用不匹配。前者报 503后者事件日志里会有「应用程序池被自动禁用」。解决先给IIS_IUSRS授目录读权限再看应用池的managedRuntimeVersion是否和应用目标框架一致事件查看器里「应用程序」日志会有具体原因。5.5 现象装完重启后 IIS 管理控制台打不开原因Web-Mgmt-Console装了但Web-Mgmt-Service没装或没启动管理控制台依赖管理服务做远程和本地连接。解决Get-Service WMSVC看状态没启动就Start-Service WMSVC并设为自动如果服务不存在说明管理服务组件没装回源补装Web-Mgmt-Service。6. 把离线源做成可复用基线一次准备多机交付单台机器装完就完事那是救火把离线源整理成可复用基线才是省事。我的习惯是在一台「基准机」上把常用 IIS 组合装全然后用Export-WindowsFeature的思路把源固化下来——2012 R2 没有直接的导出命令实际做法是把sources\sxs连同你验证过的组件清单一起打包清单里记下系统版本号、语言、补丁级别和每个组件的技术名。下次交付新机器先比对版本和语言一致就直接挂源装不一致就先补差异组件。验证基线是否可靠有个笨但有效的办法找一台干净的同版本虚拟机断网挂源跑一遍第 3 章的安装命令再跑第 4 章的建站命令浏览器能出默认页就算过。这一步别省我见过太多次「在我机器上是好的」结果换台机器就因为少一个netfx组件卡住。再补一个参数层面的技巧Install-WindowsFeature支持-WhatIf正式装之前先跑一遍看它会动哪些组件输出里如果出现你没预期的父功能说明依赖链比你想的长提前把源备齐。命令如下# 预演安装不实际改动系统 Install-WindowsFeature -Name Web-Server, Web-Asp-Net45 -Source D:\IIS_Offline\sources\sxs -WhatIf-WhatIf会列出将被启用的功能清单拿这份清单去核对离线包目录比装到一半回滚再查日志快得多。从那以后我每次交付隔离环境的 IIS都强制先跑一遍-WhatIf加目录核对再正式装省下的回滚时间够喝好几杯茶。希望帮到你。本文还有配套的精品资源点击获取