使用Start-Process启动多个进程,然后使用Stop-Process终止它们

时间:2016-09-16 00:19:09

标签: powershell

我们使用以下脚本启动五个进程。它们中的每一个都在命令提示符下运行。我们希望能够在之后停止所有流程。我们怎么做?

RunDemo.ps1

$global:p = @();

function global:kill-demo {
    $global:p | % {
        Write-Host "Killing $($_.ProcessName)"
        kill $_
        Write-Host "$($_.ProcessName) dead"
    }
}

# Authorization Server
Push-Location "./AuthorizationServer"
$global:p += Start-Process dotnet -ArgumentList "run" -PassThru
Pop-Location

# Aurelia Application
Push-Location "./AureliaApp"
$global:p += Start-Process npm -ArgumentList "run start" -PassThru
Pop-Location

# Oidc Client JS
Push-Location "./OidcClientJs"
$global:p += Start-Process npm -ArgumentList "run start" -PassThru
Pop-Location

# Resource Server 01
Push-Location "./ResourceServer01"
$global:p += Start-Process dotnet -ArgumentList "run" -PassThru
Pop-Location

# Resource Server 02
Push-Location "./ResourceServer02"
$global:p += Start-Process dotnet -ArgumentList "run" -PassThru
Pop-Location

理想情况下,我们希望能够打开PowerShell并执行以下操作。输出表明PowerShell正在查找进程并停止它们,尽管命令提示所有进程保持打开状态。

PS> .\RunDemo.ps1
PS> kill-demo
Killing dotnet
dotnet dead
Killing cmd
cmd dead
Killing cmd
cmd dead
Killing dotnet
dotnet dead
Killing dotnet
dotnet dead

当我们在不运行Web应用程序的情况下启动更简单的进程(如notepad.exe或node.exe)时,脚本可以正常工作。

2 个答案:

答案 0 :(得分:3)

您可以使用Get-Help来发​​现PowerShell命令的许多功能。在这种情况下, get-help start-process -full 将描述 -PassThru

  

-PassThru

     

返回cmdlet启动的每个进程的进程对象。默认情况下,此cmdlet不会生成任何输出。

您可以使用类似的东西,在您的情况下,将ID保存在数组或类似的东西中。

$x = Start-Process notepad.exe -PassThru
# wait some time, etc.
Stop-Process -Id $x.Id

答案 1 :(得分:1)

以下结果是杀死进程及其所有子进程。

$global:p = @();

function global:Find-ChildProcess {
    param($ID = $PID)

    $result = Get-CimInstance win32_process |
        Where-Object { $_.ParentProcessId -eq $ID }
    Select-Object -Property ProcessId

    $result |
        Where-Object { $null -ne $_.ProcessId } |
        ForEach-Object {
        Find-ChildProcess -id $_.ProcessId
    }
}

function global:Stop-Demo {
    $global:p |
        ForEach-Object { 
        Stop-Process -Id $_.Id;
        Find-ChildProcess -ID $_.Id;
    } |
        ForEach-Object { 
        Stop-Process -id 
        $_.ProcessId 
    }
}

Push-Location "./AuthorizationServer"
$global:p += Start-Process dotnet -ArgumentList "run" -PassThru
Pop-Location

Push-Location "./AureliaApp"
$global:p += Start-Process npm -ArgumentList "run start" -PassThru
Pop-Location

Push-Location "./OidcClientJs"
$global:p += Start-Process npm -ArgumentList "run start" -PassThru
Pop-Location

Push-Location "./ResourceServer01"
$global:p += Start-Process dotnet -ArgumentList "run" -PassThru
Pop-Location

Push-Location "./ResourceServer02"
$global:p += Start-Process dotnet -ArgumentList "run" -PassThru
Pop-Location