使用msdeploy在后台运行安装程序

时间:2014-05-14 12:28:41

标签: powershell msdeploy

我们将构建直接从TFS构建部署到使用msdeploy的服务器。有许多组件,其中一些需要设置(多个nservicebus服务,每个启动/安装/停止大约需要1分钟)。这个"网关"服务器运行msdeploy本身到"扇出"将二进制文件部署到其他服务器,这些服务器根据其角色运行类似的设置任务。

构建服务器长时间挂在这个任务上是没有意义的,所以我们需要一些方法让这个设置运行在"后台" /从构建服务器角度分离

我们使用PowerShell作为部署脚本引擎。 以下是我们尝试的内容:

  • 一旦原始msdeploy -started powershell退出,start-job启动的作业就会被终止。
  • start-process开始的作业挂起msdeploy连接,直到完成
  • 我们无法使用invoke-command -ComputerName localhost -InDisconnectedSession循环(这可以在同一台机器上运行,但不能通过msdeploy运行;我不在乎传递凭据,因为我们没有DA信誉并且已部署的计算机位于多个网络中)

我在下面发布我的解决方案,最后我使用了立即启动的计划任务。但我希望有人知道更清洁的解决方案。

1 个答案:

答案 0 :(得分:0)

该程序将安排自己立即运行,这可以被触发"使用msdeploy runCommand而不是阻止输出。

这是我们使用触发器脚本的msdeploy:

param([string]$dest = "fully.qualified.example.com",
      [string]$serviceMachine = "windowsmachine",
      [string]$deployUser = "webdeploy",
      [string]$deployPass = "***",
      [string]$localPath = "c:/temp/source",
      [string]$remotePath = "c:/temp"
);
$deployCommand = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe"

$depArgs = @('-verb:sync'
        "-source:dirpath=$localPath"
        "-dest:computerName=https://${dest}/msdeploy.axd,userName=$servicemachine\$deployUser,password=$deployPass,authType=basic,dirPath=$remotePath"
        "-postSync:runCommand='powershell -inputformat none $remotePath/starter.ps1',waitInterval=30000"
        "-enableRule:DoNotDeleteRule"
        "-allowUntrusted")

$command = "& '$deployCommand' --% $depArgs"

& $ExecutionContext.InvokeCommand.NewScriptBlock($command)

这是上面触发的starter.ps1

param([switch] $fg)
$scheduledJobName = "starter_v1"
$localPath = (Get-Location).Path
$logfile = "c:\temp\starterlog.txt"
function startBGJob() { 
    try {
        Get-ScheduledJob -Name $scheduledJobName -ErrorAction Stop
        "[BGJ] Found job $scheduledJobName, starting."
                # no way in PS to start the job as actual scheduled task
        schtasks /run /tn "\Microsoft\Windows\PowerShell\ScheduledJobs\$scheduledJobName"

    } catch {
        "[BGJ] Job not found, creating and starting new"    

        $jobsb = { 
            param($lp, $logfile); 
            & "$lp\starter.ps1" -fg | out-file $logfile
        }

        $option = New-ScheduledJobOption -RunElevated
        Register-ScheduledJob -name $scheduledJobName -ScriptBlock $jobsb -ArgumentList ($localPath, $logfile) -ScheduledJobOption $option -RunNow
    }
}

function Main() {
    if ($fg -eq $true) {
        # actual work done here
    } else {
        startBGJob
    }
}
Main

我不得不从那些中提取一些东西,所以错别字可能就在其中。