我试图在将CodedUI测试部署到我的Azure虚拟机之前检查它们是否正在运行。这些都是在Azure DevOps管道中完成的。
在工作流程之外,脚本运行良好。我们想将ForEach循环转换为并行运行,因此我们决定尝试将其放入工作流中(我们同时对多个VM执行此操作)。
由于某种原因,在工作流程中完成此操作后,我似乎无法获得VM的状态列表。
我意识到我只能使用Test-Connection来查看VM是否正在运行,但是让我感到困扰的是该方法不起作用。
$context = Get-AzSubscription -SubscriptionId 'Subscription GUID'
Set-AzContext $context
workflow Check-VM-Status {
Param ([string[]]$VMNames)
if($VMNames.Count -eq 0)
{
Write-Output "You must provide one or more VM names."
}
else
{
#Start-Sleep -Seconds 120
$VMListJSON = Get-AzVM -Name MyVM* | ConvertTo-Json
$VMList = $VMListJSON | ConvertFrom-Json
ForEach -Parallel ($VMName in $VMNames)
{
Write-Output "Checking VM status for $VMName."
$VM = $VMList | where { $_.Name -eq $VMName }
$VM = Get-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Status
$attempts = 0
$statuses = $VM.Statuses
$code = $statuses[1].Code
if($code -ne 'PowerState/running')
{
do
{
Write-Output -InputObject "Check #$attempts. $($VM.Name) is not yet running. Re-checking in 120 seconds..."
Start-Sleep -Seconds 120
$VM = Get-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Status
$attempts++
}
while ($($VM.Statuses[1].Code) -ne 'PowerState/running' -and $attempts -lt 11)
if ($($VM.Statuses[1].Code) -eq 'PowerState/running')
{
Write-Output "$($VM.Name) is running. Allow VM to finish the start up process (120 seconds) before continuing."
Start-Sleep -Seconds 120
$Ping = Test-Connection -ComputerName $VMName -Delay 5 -Quiet
if ($Ping)
{
Write-Output "$($VM.Name) is started and running."
}
else
{
Write-Output "$($VM.Name) failed to respond."
}
}
else
{
Write-Error "$($VM.Name) is still not running after 10 attempts to check status (20 minutes). Status is $($VM.Statuses[1].Code)."
}
}
else
{
Write-Output "$($VM.Name) is already running. Allow VM to finish the start up process (120 seconds) before continuing."
Start-Sleep -Seconds 120
$Ping = Test-Connection -ComputerName $VMName -Delay 5 -Quiet
if ($Ping)
{
Write-Output "$($VM.Name) is started and running."
}
else
{
Write-Output "$($VM.Name) failed to respond."
}
}
}
}
}
Check-VM-Status ('MyVM01')
答案 0 :(得分:0)
根据我的测试,在工作流中并行运行时,以下命令无法正常工作:
$VM = Get-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Status
$VM.Statuses[1].Code # The value is always empty, so all the following scripts fails
我的解决方案是使用PowerShell运行空间:
function Get-VM-Status([string[]] $VMNames, [int] $ThrottleLimit){
$SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$Pool = [runspacefactory]::CreateRunspacePool(1, $ThrottleLimit, $SessionState, $Host)
$Pool.Open()
$ScriptBlock = {
param($Current_VMName,$All_VMs)
$Current_VM = $All_VMs | where { $_.Name -eq $Current_VMName }
$Current_VM = Get-AzVM -ResourceGroupName $Current_VM.ResourceGroupName -Name $Current_VM.Name -Status
Write-Output ("Checking VM status for $Current_VMName -> " + $Current_VM.Statuses[1].Code)
}
$threads = New-Object System.Collections.ArrayList
$VMs = Get-AzVM
$handles = foreach ($VMName in $VMNames) {
$powershell = [powershell]::Create().AddScript($ScriptBlock).AddArgument($VMName).AddArgument($VMs)
$powershell.RunspacePool = $Pool
$powershell.BeginInvoke()
$threads += $powershell
}
do {
$i = 0
$done = $true
foreach ($handle in $handles) {
if ($handle -ne $null) {
if ($handle.IsCompleted) {
$threads[$i].EndInvoke($handle)
$threads[$i].Dispose()
$handles[$i] = $null
} else {
$done = $false
}
}
$i++
}
if (-not $done) { Start-Sleep -Milliseconds 500 }
} until ($done)
$Pool.Close()
$Pool.Dispose()
}
$vms = Get-AzVM | %{$_.Name}
Get-VM-Status -VMNames $vms -ThrottleLimit 20
使用上述脚本,我可以在几秒钟内获得13个虚拟机的状态:
PS C:\WINDOWS\system32> Get-VM-Status -VMNames $vms -ThrottleLimit 20
Checking VM status for test-sql -> PowerState/running
Checking VM status for winsvr-2016 -> PowerState/running
Checking VM status for vs2019 -> PowerState/running
Checking VM status for dc-ericm -> PowerState/running
Checking VM status for ericmex13 -> PowerState/deallocated
Checking VM status for win2016-ericm -> PowerState/running
Checking VM status for testvm -> PowerState/running
Checking VM status for StanLinuxTest -> PowerState/running
Checking VM status for win2012 -> PowerState/running
Checking VM status for testvm2 -> PowerState/running
Checking VM status for CXPCMT -> PowerState/running
Checking VM status for win2019DC -> PowerState/running
Checking VM status for test -> PowerState/running