TFS 2018多服务器环境下合理规范的重启流程咨询
你的三步流程思路非常靠谱,已经精准覆盖了TFS 2018停机维护的核心环节!不过确实有一些可以简化、自动化的优化点,帮你梳理一下:
一、先确认:你的核心流程方向完全正确
你提到的「停机前准备→维护→启动后恢复」的逻辑是微软官方推荐的TFS维护流程框架,其中几个关键操作必须保留:
- 禁用构建代理并等待现有构建完成:避免中途中断构建导致工件损坏
TFSServiceControl quiesce:这是TFS进入维护模式的核心命令,会自动暂停所有作业队列、将集合设为只读状态,阻止新的写入操作- 暂停/恢复代码搜索索引:避免索引过程中服务器重启导致索引损坏
二、可简化的操作点
1. 用TFS PowerShell Cmdlet替代Rest API操作构建代理
手动调用Rest API批量管理代理太繁琐,TFS 2018自带的PowerShell模块可以更高效地完成批量禁用/启用操作:
# 加载TFS PowerShell模块(路径根据你的安装目录调整) Import-Module "C:\Program Files\Microsoft Team Foundation Server 2018\Tools\Microsoft.TeamFoundation.PowerShell.dll" # 连接到TFS应用服务器 $tfsCollectionUri = "http://你的TFS应用服务器地址:8080/tfs" Connect-TfsTeamProjectCollection -CollectionUri $tfsCollectionUri # 批量禁用指定代理池的所有代理 $targetPool = "Default" # 替换为你的代理池名称 $agents = Get-TfsAgent -PoolName $targetPool foreach ($agent in $agents) { Disable-TfsAgent -AgentId $agent.Id -PoolName $targetPool -Force } # 启动后批量启用代理的逻辑类似,把Disable换成Enable即可
2. 整合集合维护操作到TFSServiceControl quiesce
你提到的「停止所有集合」其实可以被TFSServiceControl quiesce覆盖——这个命令会自动将所有团队项目集合设置为只读状态,无需单独执行停止集合的操作。如果需要完全离线集合,也可以用Stop-TfsCollection Cmdlet批量处理,但通常quiesce已经足够满足维护需求。
3. 统一多服务器操作顺序
你的拓扑是4台独立服务器,要严格遵循停机顺序和启动顺序,避免依赖服务未就绪导致的异常:
- 停机顺序:构建服务器 → 代码搜索服务器 → TFS应用服务器 → SQL数据服务器
- 启动顺序:SQL数据服务器 → TFS应用服务器 → 代码搜索服务器 → 构建服务器
可以通过PowerShell的Invoke-Command远程执行命令,把多服务器的操作整合到同一个脚本里。
三、完全脚本化实现示例
你可以把整个停机+启动流程写成两个PowerShell脚本(以管理员身份运行):
停机脚本(Pre-Maintenance.ps1)
# 1. 处理构建服务器:禁用代理+等待现有构建完成 $buildServer = "你的构建服务器名称" Invoke-Command -ComputerName $buildServer -ScriptBlock { Import-Module "C:\Program Files\Microsoft Team Foundation Server 2018\Tools\Microsoft.TeamFoundation.PowerShell.dll" $tfsUri = "http://你的TFS应用服务器地址:8080/tfs" Connect-TfsTeamProjectCollection -CollectionUri $tfsUri # 禁用代理 $agents = Get-TfsAgent -PoolName "Default" foreach ($agent in $agents) { Disable-TfsAgent -AgentId $agent.Id -PoolName "Default" -Force } # 等待所有运行中构建完成 do { $runningBuilds = Get-TfsBuild -Status InProgress if ($runningBuilds.Count -gt 0) { Write-Host "等待 $($runningBuilds.Count) 个构建完成,1分钟后重试..." Start-Sleep -Seconds 60 } } while ($runningBuilds.Count -gt 0) } # 2. 处理代码搜索服务器:暂停索引 $searchServer = "你的搜索服务器名称" Invoke-Command -ComputerName $searchServer -ScriptBlock { # 这里替换为你存放PauseSearchIndexing.ps1的路径 & "C:\TFS-Maintenance\PauseSearchIndexing.ps1" } # 3. 处理TFS应用服务器:进入维护模式 $appServer = "你的应用服务器名称" Invoke-Command -ComputerName $appServer -ScriptBlock { & "C:\Program Files\Microsoft Team Foundation Server 2018\Tools\TFSServiceControl.exe" quiesce } # 4. 可选:处理SQL数据服务器(如果需要进入维护模式) $sqlServer = "你的数据服务器名称" Invoke-Command -ComputerName $sqlServer -ScriptBlock { # 这里可以添加SQL维护命令,比如设置数据库只读等 }
启动脚本(Post-Maintenance.ps1)
# 1. 启动SQL数据服务器服务(可选) $sqlServer = "你的数据服务器名称" Invoke-Command -ComputerName $sqlServer -ScriptBlock { Start-Service MSSQLSERVER } # 2. 处理TFS应用服务器:退出维护模式 $appServer = "你的应用服务器名称" Invoke-Command -ComputerName $appServer -ScriptBlock { & "C:\Program Files\Microsoft Team Foundation Server 2018\Tools\TFSServiceControl.exe" unquiesce } # 3. 处理代码搜索服务器:恢复索引 $searchServer = "你的搜索服务器名称" Invoke-Command -ComputerName $searchServer -ScriptBlock { & "C:\TFS-Maintenance\StartSearchIndexing.ps1" } # 4. 处理构建服务器:启用代理 $buildServer = "你的构建服务器名称" Invoke-Command -ComputerName $buildServer -ScriptBlock { Import-Module "C:\Program Files\Microsoft Team Foundation Server 2018\Tools\Microsoft.TeamFoundation.PowerShell.dll" $tfsUri = "http://你的TFS应用服务器地址:8080/tfs" Connect-TfsTeamProjectCollection -CollectionUri $tfsUri $agents = Get-TfsAgent -PoolName "Default" foreach ($agent in $agents) { Enable-TfsAgent -AgentId $agent.Id -PoolName "Default" -Force } }
四、无人值守更新的自动化触发
如果Windows更新是无人值守的,可以通过Windows任务计划程序实现脚本自动执行:
- 停机脚本:设置在「系统即将重启前」触发(可以通过事件日志ID 1074触发)
- 启动脚本:设置在「系统启动后」触发,延迟5-10分钟确保所有基础服务就绪
内容的提问来源于stack exchange,提问作者Morné Kruger
相关产品推荐
相关产品推荐

