使用 Azure PowerShell 同时停止多个 Azure VM
Stop multiple Azure VMs at the same time using Azure PowerShell
Get-AzureRmVM -ResourceGroupName RG-VNETS |
ForEach-Object {
Get-AzureRmVM -ResourceGroupName RG-VNETS -Name $_.Name -Status
} |
ForEach-Object {
if (-Not ($_.Statuses[1].DisplayStatus -like "*deallocated*")) {
Stop-AzureRmVM -ResourceGroupName RG-VNETS -Name $_.Name -Force
}
}
我有这个脚本可以停止我所有的 Azure VM,这里的问题是这个脚本一次关闭一个 VM。
即如果我有三个虚拟机:VM1、VM2、VM3
在 VM1 完全关闭之前,脚本不会关闭 VM2,依此类推。我不知道是否有办法告诉 PowerShell 不要等待每个 VM 完全关闭才能继续执行以下操作。
GitHub 上已经有一个用于异步执行此类操作的 feature request,应该在不久的将来实现。
同时,您可以使用 PoshRSJob 模块执行如下解决方法 - 只需将 temp4so
替换为您的资源组名称
# Install PoshRSJob if necessary
#
# Install-Module PoshRSJob
Login-AzureRmAccount
$start = Get-Date
$jobs = Get-AzureRmVM -ResourceGroupName temp4so |
% {
Get-AzureRmVM -ResourceGroupName temp4so -Name $_.Name -Status
} |
% {
if (-Not ($_.Statuses[1].DisplayStatus -like "*deallocated*")) {
$vm = $_
Start-RSJob {
Stop-AzureRmVM -ResourceGroupName temp4so -Name ($using:vm).Name -Force
}
}
}
$jobs | Wait-RSJob | Receive-RSJob
$jobs | Remove-RSJob
$end = Get-Date
Write-Host ("Stopping took {0}" -f ($end - $start))
在我的 3 台 VM 测试用例中,输出类似于以下内容,表明操作是并行完成的
OperationId :
Status : Succeeded
StartTime : 24.09.2016 18:49:10
EndTime : 24.09.2016 18:51:32
Error :
OperationId :
Status : Succeeded
StartTime : 24.09.2016 18:49:11
EndTime : 24.09.2016 18:51:22
Error :
OperationId :
Status : Succeeded
StartTime : 24.09.2016 18:49:11
EndTime : 24.09.2016 18:51:22
Error :
Stopping took 00:02:32.9115538
注意:您不能简单地使用标准 Start-Job
来卸载同步。对后台作业的操作,因为在后台新创建的 PowerShell 实例不与您的初始会话共享上下文,因此需要您为每个会话再次进行身份验证。由于 PoshRSJob 在初始 PowerShell 实例中使用 PowerShell 运行空间,因此不需要再次进行身份验证。
他们根据 DAXaholic 链接的 GitHub 功能请求实施了 -AsJob。这是取自 GitHub 评论部分的示例。
$VMList = Get-AzureRmVM -ResourceGroupName $resourceGroupName
$JobList = @()
foreach ($vm in $VMList) {
$JobList += Stop-AzureRmVm -ResourceGroupName $resourceGroupName -Name $vm -Force -AsJob | Add-Member -MemberType NoteProperty -Name VMName -Value $vm.Name -PassThru
}
如果您想等待作业完成清理:
$JobList | Wait-Job | Receive-Job
$JobList | Remove-Job
Get-AzureRmVM -ResourceGroupName RG-VNETS |
ForEach-Object {
Get-AzureRmVM -ResourceGroupName RG-VNETS -Name $_.Name -Status
} |
ForEach-Object {
if (-Not ($_.Statuses[1].DisplayStatus -like "*deallocated*")) {
Stop-AzureRmVM -ResourceGroupName RG-VNETS -Name $_.Name -Force
}
}
我有这个脚本可以停止我所有的 Azure VM,这里的问题是这个脚本一次关闭一个 VM。
即如果我有三个虚拟机:VM1、VM2、VM3
在 VM1 完全关闭之前,脚本不会关闭 VM2,依此类推。我不知道是否有办法告诉 PowerShell 不要等待每个 VM 完全关闭才能继续执行以下操作。
GitHub 上已经有一个用于异步执行此类操作的 feature request,应该在不久的将来实现。
同时,您可以使用 PoshRSJob 模块执行如下解决方法 - 只需将 temp4so
替换为您的资源组名称
# Install PoshRSJob if necessary
#
# Install-Module PoshRSJob
Login-AzureRmAccount
$start = Get-Date
$jobs = Get-AzureRmVM -ResourceGroupName temp4so |
% {
Get-AzureRmVM -ResourceGroupName temp4so -Name $_.Name -Status
} |
% {
if (-Not ($_.Statuses[1].DisplayStatus -like "*deallocated*")) {
$vm = $_
Start-RSJob {
Stop-AzureRmVM -ResourceGroupName temp4so -Name ($using:vm).Name -Force
}
}
}
$jobs | Wait-RSJob | Receive-RSJob
$jobs | Remove-RSJob
$end = Get-Date
Write-Host ("Stopping took {0}" -f ($end - $start))
在我的 3 台 VM 测试用例中,输出类似于以下内容,表明操作是并行完成的
OperationId :
Status : Succeeded
StartTime : 24.09.2016 18:49:10
EndTime : 24.09.2016 18:51:32
Error :
OperationId :
Status : Succeeded
StartTime : 24.09.2016 18:49:11
EndTime : 24.09.2016 18:51:22
Error :
OperationId :
Status : Succeeded
StartTime : 24.09.2016 18:49:11
EndTime : 24.09.2016 18:51:22
Error :
Stopping took 00:02:32.9115538
注意:您不能简单地使用标准 Start-Job
来卸载同步。对后台作业的操作,因为在后台新创建的 PowerShell 实例不与您的初始会话共享上下文,因此需要您为每个会话再次进行身份验证。由于 PoshRSJob 在初始 PowerShell 实例中使用 PowerShell 运行空间,因此不需要再次进行身份验证。
他们根据 DAXaholic 链接的 GitHub 功能请求实施了 -AsJob。这是取自 GitHub 评论部分的示例。
$VMList = Get-AzureRmVM -ResourceGroupName $resourceGroupName
$JobList = @()
foreach ($vm in $VMList) {
$JobList += Stop-AzureRmVm -ResourceGroupName $resourceGroupName -Name $vm -Force -AsJob | Add-Member -MemberType NoteProperty -Name VMName -Value $vm.Name -PassThru
}
如果您想等待作业完成清理:
$JobList | Wait-Job | Receive-Job
$JobList | Remove-Job