资讯中心

Windows Server 2022 搭建 Web 服务器:IIS 安装、站点配置与 DNS 解析实战

📅 2026/10/24 15:18:55
Windows Server 2022 搭建 Web 服务器:IIS 安装、站点配置与 DNS 解析实战
简介这份资源面向 IT 运维人员与 Windows 服务器初学者聚焦 Windows Server 2022 环境下 Web 服务器的搭建与配置帮助读者从零完成服务器安装、功能验证到站点上线的完整流程。内容围绕服务器安装、功能测试、网站挂载与域名解析四大环节展开涵盖安装介质准备、语言时区选择、磁盘分区、网络与硬件测试、网站目录创建与素材拷贝、端口与域名配置以及 DNS 服务器安装和记录配置等关键知识点适合作为实验操作参考或课程配套资料。资源包共 1 个 docx 文档约 1016KB以图文步骤形式组织便于按章节对照实践。目前已有 2767 人学习下载可作为搭建 Windows Web 服务环境的入门指引与操作备忘。1. 从一台裸机到能访问的站点Windows Server 2022 Web 服务器搭建到底在做什么手里只有一台刚装好系统的 Windows Server 2022没有 IIS没有站点目录没有域名连防火墙都还是默认状态——这是很多运维和开发第一次接手 Web 服务器时的真实起点。所谓“搭建 Web 服务器”拆开看就是四件事把 IIS 角色装起来、验证网络与系统功能正常、把站点素材挂到 IIS 站点上并配好端口、最后用 DNS 把域名和 IP 对上。这四步任何一步没走通浏览器里就是一片 404 或者连接超时。这篇笔记面向需要在一台 Windows 服务器上快速落地静态或轻量动态站点的人从角色安装一路写到 DNS 解析验证中间把端口冲突、权限、防火墙这些血泪坑都标出来。Windows 服务器这套东西不玄学但细节多照着走能少翻几次车。2. 装 IIS 与功能测试角色安装、网络自检和最小可用验证2.1 为什么选 IIS 而不是第三方 Web 服务在 Windows Server 2022 上搭 Web 服务常见做法有三条路IIS、Nginx for Windows、以及各种自带运行时的应用服务器。选 IIS 的理由很实际——它是系统原生角色和 Windows 的账户体系、防火墙、证书存储、事件日志是一套东西装完就能用Get-WindowsFeature查状态出问题能在事件查看器里顺着来源筛。Nginx 在 Windows 上跑静态资源没问题但作为服务注册、日志轮转、权限继承都要自己补对“一台服务器挂个站点”这种诉求属于过度工程。IIS 的短板是配置偏重、模块多但换来的是图形化和 PowerShell 双通道管理批量部署时WebAdministration模块能省很多事。所以这里的选型结论很直接单机、内网、轻量站点IIS 是默认答案只有当你有跨平台反向代理、高并发静态分发需求时才考虑把 Nginx 放到前面。2.2 用 PowerShell 安装 IIS 角色与常用子功能图形化“服务器管理器 → 添加角色和功能”能装但一线更常用 PowerShell因为可复现、可写进部署脚本。下面这段在管理员权限的 PowerShell 里执行装的是 Web 服务器核心加管理工具、静态内容、默认文档、HTTP 重定向、日志这几块。# 安装 IIS 核心角色及常用子功能 Install-WindowsFeature -Name Web-Server -IncludeManagementTools -IncludeAllSubFeature # 只装必要子功能时可用下面这种精确写法 Install-WindowsFeature -Name Web-Server, Web-WebServer, Web-Common-Http, Web-Default-Doc, Web-Static-Content, Web-Http-Redirect, Web-Http-Logging, Web-Filtering, Web-Mgmt-Console # 确认安装结果State 应为 Installed Get-WindowsFeature -Name Web-Server, Web-Mgmt-Console | Select-Object Name, InstallState-IncludeManagementTools会带上 IIS 管理器省得后面再补-IncludeAllSubFeature适合实验环境图省事生产环境建议用第二段那种精确列表少装一个模块就少一个攻击面。Web-Filtering是请求筛选后面配端口和 IP 限制会用到Web-Http-Logging不开的话排错时连访问记录都没有属于后悔药级别的功能别省。装完Get-WindowsFeature返回Installed才算数如果显示Available说明角色名写错或源文件缺失。装好后验证 IIS 是否真的在跑别只看管理器界面直接查服务和端口# 查看 W3SVC 服务状态 Get-Service W3SVC | Select-Object Name, Status, StartType # 确认 80 端口处于监听 Get-NetTCPConnection -LocalPort 80 -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess # 本机发起一次 HTTP 请求看默认页是否返回 200 Invoke-WebRequest -Uri http://localhost -UseBasicParsing | Select-Object StatusCodeW3SVC是 IIS 的万维网发布服务它没起来后面全白搭Get-NetTCPConnection比netstat -ano好在能直接拿到OwningProcess端口被谁占了一眼可见Invoke-WebRequest返回 200 说明默认站点已经能响应。默认站点根目录在C:\inetpub\wwwroot看到 IIS 欢迎页就代表角色层通了。2.3 网络与系统功能自检别把环境问题当成 IIS 问题角色装完不等于服务器可用。功能测试这一步很多人跳过结果后面站点打不开花了半天以为是 IIS 配置其实是网卡没配网关或者系统时间漂移导致证书校验失败。我一般按三层查网络层、系统层、服务层。网络层先确认 IP、网关、DNS 是否配全用ipconfig /all看重点看默认网关和 DNS 服务器两项。然后测连通性# 查看本机网络配置摘要 Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer # 测试到网关和外部地址的连通性 Test-NetConnection -ComputerName 192.168.1.1 -InformationLevel Quiet Test-NetConnection -ComputerName 8.8.8.8 -Port 53 -InformationLevel Quiet # 检查系统时间和时区证书与日志都依赖它 Get-Date Get-TimeZoneTest-NetConnection的-InformationLevel Quiet只回True/False适合写进脚本做判断测 53 端口是验证 DNS 出站是否被拦这一步能提前暴露防火墙策略问题。系统层还要看磁盘剩余空间和事件日志里有没有反复出现的硬件或驱动告警Get-EventLog -LogName System -EntryType Error -Newest 20扫一眼别等站点跑起来才发现磁盘满了写不进日志。服务层就是前面那组W3SVC和端口检查。三层都过了才算“服务器功能测试”完成。这里有个容易忽略的点Windows Server 2022 默认启用了 IE 增强安全配置服务器上用浏览器访问 localhost 可能弹拦截提示别被这个吓到用Invoke-WebRequest或curl.exe验证更干净。3. 挂载站点与端口配置目录、权限、绑定三件事3.1 站点目录规划与素材拷贝挂载网站第一步不是打开 IIS 管理器而是先把目录结构定下来。默认的C:\inetpub\wwwroot能用但多个站点混在一起后期很难维护。常见做法是按站点名建独立目录比如D:\Sites\demo把网站素材HTML、CSS、JS、图片整体拷进去。拷贝用Copy-Item或资源管理器都行关键是拷完检查两件事入口文件是否存在index.html或default.aspx以及目录里有没有残留的.git、备份压缩包这类不该对外暴露的东西。# 创建站点目录并拷贝素材 New-Item -ItemType Directory -Path D:\Sites\demo -Force Copy-Item -Path \\fileserver\assets\demo\* -Destination D:\Sites\demo -Recurse -Force # 确认入口文件存在 Test-Path D:\Sites\demo\index.html # 列出目录内容排查是否混入敏感文件 Get-ChildItem D:\Sites\demo -Force | Select-Object Name, Length, LastWriteTime-Recurse保证子目录一起拷-Force覆盖同名文件Test-Path返回False就说明素材路径写错或入口文件名不对这是后面 404 的头号原因。Get-ChildItem -Force会把隐藏文件也列出来.git目录如果被拷进站点根目录等于把源码历史公开了看到就删。3.2 用 PowerShell 新建站点并绑定端口IIS 里“站点”的本质是一个物理路径 一组绑定协议、IP、端口、主机名 一个应用程序池。图形化新建站点很快但端口和主机名这些参数用命令行更不容易点错。下面新建一个监听 8080 端口的站点物理路径指向刚才的目录。# 新建应用程序池指定 .NET CLR 版本静态站点用 No Managed Code 即可 New-WebAppPool -Name demoPool Set-ItemProperty -Path IIS:\AppPools\demoPool -Name managedRuntimeVersion -Value # 新建站点绑定 8080 端口 New-Website -Name demo -PhysicalPath D:\Sites\demo -ApplicationPool demoPool -Port 8080 -IPAddress * -Force # 查看站点状态与绑定信息 Get-Website -Name demo | Select-Object Name, State, PhysicalPath Get-WebBinding -Name demo | Select-Object protocol, bindingInformationmanagedRuntimeVersion设为空字符串对应“无托管代码”纯静态站点不需要加载 .NET 运行时设成 v4.0 反而多一层依赖。-IPAddress *表示监听所有网卡地址如果服务器有多块网卡、只想对内网提供服务就改成具体 IP。-Port 8080是这里的关键参数——端口不能和已有站点重复IIS 允许同一端口配不同主机名靠 HTTP Host 头区分但同一 IP 同一端口不能有两个站点同时监听否则后建的会启动失败事件日志里报“无法绑定”。端口选的时候避开系统常用段80/443 留给正式站点8080/8081 这类做测试或内部服务别用 135、139、445 这些系统服务端口。改端口后记得同步放行防火墙# 放行 8080 入站 New-NetFirewallRule -DisplayName IIS Demo 8080 -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow # 验证规则生效 Get-NetFirewallRule -DisplayName IIS Demo 8080 | Select-Object DisplayName, Enabled, Direction, Action防火墙没放行是“本机能访问、别的机器访问不了”的经典原因New-NetFirewallRule建完规则默认就是启用的Get-NetFirewallRule确认Enabled为True。到这一步用http://服务器IP:8080应该能看到站点内容。3.3 应用程序池身份与目录权限站点能起来但报 401 或 500.19八成是权限问题。IIS 的工作进程默认以应用程序池身份运行Windows Server 2022 上新建池的默认身份是ApplicationPoolIdentity它在文件系统里表现为虚拟账户IIS AppPool\demoPool。站点目录如果放在 D 盘且没给这个账户读权限就会出现“本机管理员能打开、IIS 返回 401.3”的现象。# 给应用程序池虚拟账户授予站点目录读取和执行权限 $acl Get-Acl D:\Sites\demo $rule New-Object System.Security.AccessControl.FileSystemAccessRule( IIS AppPool\demoPool, ReadAndExecute, ContainerInherit,ObjectInherit, None, Allow) $acl.SetAccessRule($rule) Set-Acl -Path D:\Sites\demo -AclObject $acl # 确认权限条目 (Get-Acl D:\Sites\demo).Access | Where-Object { $_.IdentityReference -like *demoPool* }ReadAndExecute对静态站点足够需要上传功能的站点才给Modify但范围要收窄到具体上传目录别整个站点根目录放开写权限。ContainerInherit,ObjectInherit让权限往下继承子目录和文件自动生效。如果站点还涉及匿名身份验证确认 IIS 里“匿名身份验证”用的是应用程序池身份而不是IUSR两者混用会导致权限判断对不上。4. DNS 解析落地把域名和 IP 对上别只改 hosts4.1 装 DNS 服务器角色与建正向区域站点用 IP 加端口能访问之后下一步是让域名指向这台服务器。内网环境常见做法是在 Windows Server 2022 上装 DNS 角色建正向查找区域把demo.internal这类内部域名解析到服务器 IP。装角色和建区域都可以用 PowerShell 完成# 安装 DNS 服务器角色 Install-WindowsFeature -Name DNS -IncludeManagementTools # 新建正向查找区域主区域 Add-DnsServerPrimaryZone -Name demo.internal -ZoneFile demo.internal.dns -DynamicUpdate None # 新建 A 记录把主机名指向服务器 IP Add-DnsServerResourceRecordA -Name www -ZoneName demo.internal -IPv4Address 192.168.1.50 # 查看区域内的记录 Get-DnsServerResourceRecord -ZoneName demo.internal -RRType A-DynamicUpdate None表示不允许客户端动态注册内网小环境这样更可控避免测试机乱注册记录污染区域。Add-DnsServerResourceRecordA的-Name www生成的是www.demo.internal如果要解析根域名本身-Name用。建完记录后用Resolve-DnsName验证# 指定本机 DNS 服务器解析确认返回正确 IP Resolve-DnsName -Name www.demo.internal -Server 127.0.0.1 -Type A # 清本机 DNS 缓存后再测一次 Clear-DnsClientCache Resolve-DnsName -Name www.demo.internal -Type A-Server 127.0.0.1强制走本机 DNS 服务排除客户端缓存干扰Clear-DnsClientCache是排错时的常规动作改完记录不生效先清缓存再看。如果解析返回的 IP 不对检查是不是区域里存在同名多条 A 记录或者服务器网卡上配了多个 IP 导致注册了错误地址。4.2 让 IIS 站点响应域名主机头绑定与解析联动DNS 只负责“域名 → IP”浏览器拿到 IP 后还要靠 HTTP 请求里的 Host 头让 IIS 找到对应站点。所以光有 A 记录不够站点绑定里要加主机名。给前面的 demo 站点补一个 80 端口、主机头为www.demo.internal的绑定# 为站点添加主机头绑定80 端口 New-WebBinding -Name demo -Protocol http -Port 80 -HostHeader www.demo.internal -IPAddress * # 查看该站点全部绑定 Get-WebBinding -Name demo | Format-Table protocol, bindingInformation -AutoSizebindingInformation会显示成*:80:www.demo.internal这种格式三段分别是 IP、端口、主机头。同一台服务器上多个站点共用 80 端口时就是靠主机头区分这也是为什么“端口不能重复使用”要补一句端口可以复用但同一 IP 端口下主机头不能重复否则后绑定的站点启动报错。配完后用域名访问验证# 通过域名访问确认返回 200 且内容正确 Invoke-WebRequest -Uri http://www.demo.internal -UseBasicParsing | Select-Object StatusCode, StatusDescription如果返回 404 而不是连接失败说明 DNS 和端口都通了问题在站点绑定或默认文档如果返回 400多半是 Host 头和绑定不匹配。这一步把“域名解析”和“站点挂载”真正串起来了也是整套流程里最容易只做一半的地方——很多人 A 记录建完就以为完事结果浏览器还是打到默认站点。5. 避坑与排查端口、权限、防火墙、DNS 缓存这四类翻车现场5.1 端口被占用导致站点启动失败现象新建站点后状态显示“已停止”手动启动报错事件日志里出现“无法绑定到端口”。原因同一 IP 同一端口已有其他站点或进程在监听IIS 不允许两个站点抢同一个 IP:端口组合。解决先用Get-NetTCPConnection -LocalPort 8080 -State Listen查占用进程Get-Process -Id PID看是谁如果是旧站点改端口或停掉旧站点如果是系统进程占用换端口最省事。改完端口记得同步改防火墙规则否则又变成“本机能开、外部打不开”。5.2 目录权限不足返回 401.3现象服务器上用管理员账户能直接打开站点文件浏览器访问却返回 401.3 或 500.19。原因应用程序池身份IIS AppPool\池名对站点目录没有读取权限尤其是站点放在非系统盘、由其他账户创建目录时。解决按 3.3 的脚本给池身份授ReadAndExecute并确认匿名身份验证用的是应用程序池身份。排查时看 IIS 日志里的sc-win32-status401.3 基本就是 ACL 问题别去翻 web.config。5.3 防火墙放行了端口但外部仍访问不了现象本机Invoke-WebRequest http://localhost:8080正常另一台机器访问超时。原因Windows 防火墙入站规则没放行该端口或者放行了但作用域限制在本机/特定网段。解决Get-NetFirewallRule查规则是否存在且Enabled再看Get-NetFirewallRule -DisplayName ... | Get-NetFirewallPortFilter确认端口和协议对得上。还有一种情况是服务器所在网络的上层设备做了策略限制这种就不在服务器层面解决了先确认同网段其他机器能否访问缩小范围。5.4 DNS 改完不生效客户端还在用旧地址现象A 记录已经改成新 IPResolve-DnsName -Server 127.0.0.1返回正确但客户端浏览器还是访问到旧地址。原因客户端 DNS 缓存、或者客户端网卡上配的 DNS 服务器不是这台走了别的解析源。解决客户端执行ipconfig /flushdns再用Resolve-DnsName -Name www.demo.internal -Server DNS服务器IP指定服务器验证。如果客户端配的是公共 DNS内部域名根本解析不到这种情况要么改客户端 DNS 指向要么在 hosts 里临时写死做验证——hosts 只用于排错别当长期方案。5.5 默认文档缺失导致目录列表或 404现象域名和端口都通了访问根路径返回 404 或者列出目录文件。原因站点目录里没有index.html/default.aspx这类默认文档或者 IIS 默认文档列表里没有对应文件名。解决确认入口文件名然后在 IIS 里把该文件名加到默认文档列表顶部或用Add-WebConfiguration追加。目录列表能关就关Web-Dir-Browsing不开避免把目录结构暴露出去。6. 进阶验证与批量落地用脚本把整套流程固化下来单台服务器手工点一遍没问题但一旦要重复部署或者交接给别人图形化操作就是黑匣子。我的习惯是把第 2 到第 4 章的动作收敛成一个幂等脚本装角色、建目录、建池、建站点、配绑定、放行防火墙、建 DNS 记录每步先判断再执行重复跑不报错。下面这段是核心骨架参数抽成变量换站点只改变量区。# 参数区换站点只改这里 $SiteName demo $SitePath D:\Sites\demo $Port 8080 $HostHeader www.demo.internal $ZoneName demo.internal $ServerIP 192.168.1.50 # 1. 角色已装则跳过 if (-not (Get-WindowsFeature -Name Web-Server).Installed) { Install-WindowsFeature -Name Web-Server -IncludeManagementTools } # 2. 目录与应用程序池 New-Item -ItemType Directory -Path $SitePath -Force | Out-Null if (-not (Get-WebAppPool -Name ${SiteName}Pool -ErrorAction SilentlyContinue)) { New-WebAppPool -Name ${SiteName}Pool Set-ItemProperty -Path IIS:\AppPools\${SiteName}Pool -Name managedRuntimeVersion -Value } # 3. 站点存在则只补绑定 if (-not (Get-Website -Name $SiteName -ErrorAction SilentlyContinue)) { New-Website -Name $SiteName -PhysicalPath $SitePath -ApplicationPool ${SiteName}Pool -Port $Port -IPAddress * } if (-not (Get-WebBinding -Name $SiteName | Where-Object { $_.bindingInformation -like *:$Port:$HostHeader })) { New-WebBinding -Name $SiteName -Protocol http -Port $Port -HostHeader $HostHeader -IPAddress * } # 4. 防火墙 if (-not (Get-NetFirewallRule -DisplayName IIS $SiteName $Port -ErrorAction SilentlyContinue)) { New-NetFirewallRule -DisplayName IIS $SiteName $Port -Direction Inbound -Protocol TCP -LocalPort $Port -Action Allow } # 5. DNS 记录 if (-not (Get-DnsServerResourceRecord -ZoneName $ZoneName -Name www -ErrorAction SilentlyContinue)) { Add-DnsServerResourceRecordA -Name www -ZoneName $ZoneName -IPv4Address $ServerIP }-ErrorAction SilentlyContinue配合if (-not ...)是幂等的关键存在就跳过、不存在才建脚本可以反复跑。bindingInformation的匹配串里端口和主机头之间是冒号写的时候注意转义。这套骨架跑完再用一组验证命令收尾Get-Website看状态、Invoke-WebRequest看状态码、Resolve-DnsName看解析结果三项全绿才算部署完成。验证方法上我一般分三层做比单看浏览器靠谱验证层命令通过标准服务层Get-Service W3SVCStatus 为 Running站点层Invoke-WebRequest http://IP:PortStatusCode 200解析层Resolve-DnsName www.zone -Server DNS IP返回预期 IP三层里任何一层失败排查顺序从下往上先确认 DNS 解析对不对再看端口和防火墙通不通最后才查 IIS 站点绑定和权限。反过来查容易在 IIS 配置里绕圈实际问题是解析没生效。有个细节值得单独说Windows Server 2022 的 IIS 日志默认在C:\inetpub\logs\LogFiles按站点 ID 分目录排错时Get-Content配合Select-String筛状态码比翻事件日志快得多。比如筛 404 和 500# 在最新日志里筛非 200 状态码的请求 Get-ChildItem C:\inetpub\logs\LogFiles -Recurse -Filter *.log | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | Get-Content | Select-String -Pattern (404|500|401) 日志字段是空格分隔的状态码在倒数几位Select-String用前后空格夹住数字能减少误匹配。这个习惯帮我省过不少时间——很多“站点时好时坏”的问题日志里一看就是某类请求稳定 500直接定位到具体页面而不是瞎猜。从那以后我每次搭完站点都强制走一遍“服务 → 端口 → 防火墙 → 解析 → 绑定”这条链路每步留一条验证命令的输出交接时把输出贴进文档比口头说“配好了”可靠得多。希望这套流程帮到你少在端口和权限上翻车。本文还有配套的精品资源点击获取

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案