Azure-AutoAccount-实现通过Tag开关机虚拟机
AutoAccount自动化账号
1.前期配置
认证方式:使用automate的“标识” - “托管标识”,这样可以保证认证方式没有过期的风险。
授权:开启托管标识后,将该automate加入到订阅的“参与者”权限中即可
关于托管标识微软的官方描述:https://docs.microsoft.com/zh-cn/azure/automation/enable-managed-identity-for-automation
2.配置代码
上述认证方式配置好后,直接新建runbook运行以下代码即可,输入相关参数设置任务计划即可完成开关机
参数:
ACTION: 开机“Start”, 关机“Stop”
TAGNAME: 输入tag的名字
RAGVALUE:输入tag的值
3.添加计划
在Runbook中 - 计划 - 添加计划 - 设置开机或者关机的时间和执行频率。
设置参数和运行设置。
代码如下:
Workflow Start-Stop-VMs { param ( [Parameter(Mandatory=$true)] [String] $Action, [Parameter(Mandatory=$false)] [String] $TagName, [Parameter(Mandatory=$false)] [String] $TagValue ) ## Authentication Write-Output "" Write-Output "------------------------ Authentication ------------------------" Write-Output "Logging into Azure ..." # Ensures you do not inherit an AzContext in your runbook Disable-AzContextAutosave -Scope Process # Connect to Azure with system-assigned managed identity $AzureContext = (Connect-AzAccount -Identity).context # set and store context $AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext # try # { # # Ensures you do not inherit an AzContext in your runbook # $null = Disable-AzContextAutosave -Scope Process # $Conn = Get-AutomationConnection -Name AzureRunAsConnection # $null = Connect-AzAccount ` # -ServicePrincipal ` # -Tenant $Conn.TenantID ` # -ApplicationId $Conn.ApplicationID ` # -CertificateThumbprint $Conn.CertificateThumbprint # Write-Output "Successfully logged into Azure." # } # catch # { # if (!$Conn) # { # $ErrorMessage = "Service principal not found." # throw $ErrorMessage # } # else # { # Write-Error -Message $_.Exception # throw $_.Exception # } # } ## End of authentication ## Getting all virtual machines Write-Output "" Write-Output "" Write-Output "---------------------------- Status ----------------------------" Write-Output "Getting all virtual machines from all resource groups ..." try { if ($TagName) { $instances = Get-AzResource -TagName $TagName -TagValue $TagValue -ResourceType "Microsoft.Compute/virtualMachines" if ($instances) { $resourceGroupsContent = @() foreach -parallel ($instance in $instances) { $instancePowerState = (((Get-AzVM -ResourceGroupName $($instance.ResourceGroupName) -Name $($instance.Name) -DefaultProfile $AzureContext -Status).Statuses.Code[1]) -replace "PowerState/", "") sequence { $resourceGroupContent = New-Object -Type PSObject -Property @{ "Resource group name" = $($instance.ResourceGroupName) "Instance name" = $($instance.Name) "Instance type" = (($instance.ResourceType -split "/")[0].Substring(10)) "Instance state" = ([System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo.ToTitleCase($instancePowerState)) $TagName = $TagValue } $Workflow:resourceGroupsContent += $resourceGroupContent } } } else { #Do nothing } } else { $instances = Get-AzResource -ResourceType "Microsoft.Compute/virtualMachines" if ($instances) { $resourceGroupsContent = @() foreach -parallel ($instance in $instances) { $instancePowerState = (((Get-AzVM -ResourceGroupName $($instance.ResourceGroupName) -Name $($instance.Name) -DefaultProfile $AzureContext -Status).Statuses.Code[1]) -replace "PowerState/", "") sequence { $resourceGroupContent = New-Object -Type PSObject -Property @{ "Resource group name" = $($instance.ResourceGroupName) "Instance name" = $($instance.Name) "Instance type" = (($instance.ResourceType -split "/")[0].Substring(10)) "Instance state" = ([System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo.ToTitleCase($instancePowerState)) } $Workflow:resourceGroupsContent += $resourceGroupContent } } } else { #Do nothing } } InlineScript { $Using:resourceGroupsContent | Format-Table -AutoSize } } catch { Write-Error -Message $_.Exception throw $_.Exception } ## End of getting all virtual machines $runningInstances = ($resourceGroupsContent | Where-Object {$_.("Instance state") -eq "Running" -or $_.("Instance state") -eq "Starting"}) $deallocatedInstances = ($resourceGroupsContent | Where-Object {$_.("Instance state") -eq "Deallocated" -or $_.("Instance state") -eq "Deallocating"}) ## Updating virtual machines power state if (($runningInstances) -and ($Action -eq "Stop")) { Write-Output "--------------------------- Updating ---------------------------" Write-Output "Trying to stop virtual machines ..." try { $updateStatuses = @() foreach -parallel ($runningInstance in $runningInstances) { sequence { Write-Output "$($runningInstance.("Instance name")) is shutting down ..." $startTime = Get-Date -Format G $workflow:null = Stop-AzVM -ResourceGroupName $($runningInstance.("Resource group name")) -Name $($runningInstance.("Instance name")) -DefaultProfile $AzureContext -Force $endTime = Get-Date -Format G $updateStatus = New-Object -Type PSObject -Property @{ "Resource group name" = $($runningInstance.("Resource group name")) "Instance name" = $($runningInstance.("Instance name")) "Start time" = $startTime "End time" = $endTime } $Workflow:updateStatuses += $updateStatus } } InlineScript { $Using:updateStatuses | Format-Table -AutoSize } } catch { Write-Error -Message $_.Exception throw $_.Exception } } elseif (($deallocatedInstances) -and ($Action -eq "Start")) { Write-Output "--------------------------- Updating ---------------------------" Write-Output "Trying to start virtual machines ..." try { $updateStatuses = @() foreach -parallel ($deallocatedInstance in $deallocatedInstances) { sequence { Write-Output "$($deallocatedInstance.("Instance name")) is starting ..." $startTime = Get-Date -Format G $workflow:null = Start-AzVM -ResourceGroupName $($deallocatedInstance.("Resource group name")) -Name $($deallocatedInstance.("Instance name")) -DefaultProfile $AzureContext $endTime = Get-Date -Format G $updateStatus = New-Object -Type PSObject -Property @{ "Resource group name" = $($deallocatedInstance.("Resource group name")) "Instance name" = $($deallocatedInstance.("Instance name")) "Start time" = $startTime "End time" = $endTime } $Workflow:updateStatuses += $updateStatus } } InlineScript { $Using:updateStatuses | Format-Table -AutoSize } } catch { Write-Error -Message $_.Exception throw $_.Exception } } #### End of updating virtual machines power state }