如何使用Powershell等待操作完成

时间:2018-07-13 19:26:32

标签: azure azure-virtual-machine azure-powershell

我有一个脚本来启动VM /在特定时间停止它们。问题是,我希望仅在启动/运行所有VM或释放/停止所有VM时退出脚本。我当前的问题是,当VM启动时,它一直等到启动后才移至下一个。

例如:vm1正在启动。     vm2正在启动。     vm3正在启动。.

vm1 is now running..
vm2 is still starting
vm3 is still starting

vm1 is now running..
vm2 is now running..
vm3 is now running..

然后脚本退出。

完整脚本在这里

$ ACTION =“开始”

Write-Output "Number of Virtual Machines: $($GetVMS.Name.Count)" `n
$GetVMS | Format-Table

$startstopvm = {

$ResourceGroupName = $args[0]
$Name =  $args[1]
$ACTION = $args[2]

# Get VM status
try {
    $VMs = Get-AzureRmVM -Name $Name -ResourceGroupName $ResourceGroupName -Status -WarningAction SilentlyContinue
} catch {
    Write-Output ("Cloud not get vm $Name in $ResourceGroupName")
    $Error[0]
    Exit 1 
}

if ($ACTION -eq "start")
{
    foreach ($VM in $VMs)
    {
        if ($VM.Statuses[1].Code -eq "PowerState/running")
        {
            Write-Output ($VM.Name + " in " + $VM.ResourceGroupName + " is already running")
        }
        else
        {
            # The VM needs to be started
            Write-Output ("Starting VM " + $VM.Name)
            $startVM += Start-AzureRmVM -Name $VM.Name -ResourceGroupName $VM.ResourceGroupName -AsJob -ErrorAction Continue

            $startTime = Get-Date

            $timeElapsed = $((Get-Date) - $startTime).TotalMinutes

            while ($timeElapsed -lt 2) 
            {
                $startVM = Get-AzureRmVM -Name $VM.Name -ResourceGroupName $VM.ResourceGroupName -Status -WarningAction SilentlyContinue

                if ($startVM.Statuses[1].Code -match "PowerState/(running|starting)")
                {
                    # The VM started, so send notice
                    Write-Output ($VM.Name + " in " + $VM.ResourceGroupName + " has been started`n")
                    break
                }
                Start-Sleep -s 30
            }

            if ($getStat.Statuses[1].Code -ne "PowerState/(running|starting)")
            {
                # The VM failed to start, so send notice
                Write-Output ($VM.Name + " failed to start`n")  
            }
        }
    }
}

注意:我正在从文件中读取VM名称和RG

try {
    $VMList = Get-Content C:\Users\local\Desktop\VMs.csv | ConvertFrom-Csv
} catch {
    Write-Output ("Cannot open file...")
    exit -1
}

$Result = @()

foreach ($vm in $VMList) {
    Invoke-Command -ArgumentList $vm.ResourceGroupName, $vm.Name, $ACTION -Verbose -ScriptBlock $startstopvm
}

1 个答案:

答案 0 :(得分:0)

我过去最简单的方法是在-Wait cmdlet上使用Start-Process参数。

您应该可以进行一些小的改动。

将当前代码块保存到单独的.ps1startstopvm.ps1

然后,您可以将Invoke-Commmand行更改为类似以下内容:
Invoke-Command -ArgumentList $vm.ResourceGroupName, $vm.Name, $ACTION -Verbose -ScriptBlock {Start-Process powershell.exe -Argument "C:\Scripts\Backup.ps1 TestBackup" -Wait}

肯定还有其他方法可以实现,但是像这样的方法一直对我有用