none
Azure Automation - Encendido y apagado automático de VM RRS feed

  • Pregunta

  • Hola a todos, 

    He creado una cuenta de Automation para mi suscripción de Azure y he configurado unos runbooks para apagar y encender unas máquinas virtuales. 

    Runbook:

    Workflow StartVmAzure_ERP
    {
    $cred=Get-AutomationPSCredential -Name "pwshellautomation"
    Add-AzureAccount -credential $cred
    Start-AzureVM -ServiceName ERP -Name ERP

    }

    En principio la prueba da resultado completado, lo he guardado, publicado y programado.

    He hecho la programación para ejecutarse a los 5 minutos (mínimo tiempo) para hacer la prueba y pasado

    este tiempo, veo que el runbook aparece como ejecutado, pero la VM sigue apagada.

    ¿qué he hecho mal?

    Muchas gracias por vuestra ayuda!!


    Nacho

    jueves, 30 de noviembre de 2017 13:14

Respuestas

  • Hola Nacho, 

    Te recomiendo utilizar checkpoints para revisar el estado de tu workflow (https://docs.microsoft.com/en-us/azure/automation/automation-powershell-workflow#checkpoints), te comparto un ejemplo de un runbook para iniciar tu(s) VM(s): 

    $currentTime = (Get-Date).ToUniversalTime()
    Write-Verbose "Runbook started"
    Write-Verbose "Current UTC time [$($currentTime.ToString("dddd, yyyy MMM dd HH:mm:ss"))]"
    
    $targetResourceGroups = Get-AutomationVariable -Name 'StartByResourceGroupV2-TargetResourceGroups-MS-Mgmt-VM'
    $targetSubscriptionId =	Get-AutomationVariable -Name 'StartByResourceGroupV2-TargetSubscriptionID-MS-Mgmt-VM'
    $vmExcludeList = Get-AutomationVariable -Name 'StartByResourceGroupV2-ExcludeList-MS-Mgmt-VM'
    Write-Verbose "Target ResourceGroups:  $targetResourceGroups"
    Write-Verbose "Target SubscriptionID:  $targetSubscriptionId"
    Write-Verbose "Exclude list:  $vmExcludeList"
    
    #
    # Initialize the Azure subscription we will be working against for AzureRM resources
    #
    Write-Verbose "Authenticating ARM RunAs account"
    $connectionName = "AzureRunAsConnection"
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName      
    
    # retry
    $retry = 6
    $syncOk = $false
    do
    { 
    	try
    	{  
    		Add-AzureRmAccount -ServicePrincipal -TenantId $servicePrincipalConnection.TenantId -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
    		$syncOk = $true
    	}
    	catch
    	{
    		$ErrorMessage = $_.Exception.Message
    		$StackTrace = $_.Exception.StackTrace
    		Write-Warning "Error during sync: $ErrorMessage, stack: $StackTrace. Retry attempts left: $retry"
    		$retry = $retry - 1       
    		Start-Sleep -s 60        
    	}
    } while (-not $syncOk -and $retry -ge 0)
    
    Select-AzureRMSubscription -SubscriptionId $targetSubscriptionId -TenantId $servicePrincipalConnection.TenantId
    $currentSubscription = Get-AzureRMSubscription -SubscriptionId $targetSubscriptionId -TenantId $servicePrincipalConnection.TenantId
    Write-Verbose "Found ARM subscription [$($currentSubscription.SubscriptionName)] ($($currentSubscription.SubscriptionId))"
    
    #
    # Initialize the Azure subscription we will be working against for Classic Azure resources
    #
    Write-Verbose "Authenticating Classic RunAs account"
    $ConnectionAssetName = "AzureClassicRunAsConnection"
    $connection = Get-AutomationConnection -Name $connectionAssetName        
    Write-Verbose "Get connection asset: $ConnectionAssetName" -Verbose
    $Conn = Get-AutomationConnection -Name $ConnectionAssetName
    if ($Conn -eq $null)
    {
        throw "Could not retrieve connection asset: $ConnectionAssetName. Assure that this asset exists in the Automation account."
    }
    $CertificateAssetName = $Conn.CertificateAssetName
    Write-Verbose "Getting the certificate: $CertificateAssetName" -Verbose
    $AzureCert = Get-AutomationCertificate -Name $CertificateAssetName
    if ($AzureCert -eq $null)
    {
        throw "Could not retrieve certificate asset: $CertificateAssetName. Assure that this asset exists in the Automation account."
    }
    Write-Verbose "Authenticating to Azure with certificate." -Verbose
    Set-AzureSubscription -SubscriptionName $Conn.SubscriptionName -SubscriptionId $Conn.SubscriptionID -Certificate $AzureCert 
    Select-AzureSubscription -SubscriptionId $Conn.SubscriptionID
    
    $rgList = $targetResourceGroups.split(";")
    foreach ($rg in $rgList)
    {
    	#Get all ARM resources from all resource groups
    	$ResourceGroups = Get-AzureRmResourceGroup | where ResourceGroupName -Like $rg
    	$targetVM = @()
    	foreach ($ResourceGroup in $ResourceGroups)
    	{    
    		# Get classic VM resources in group and record target state for each in table
    		$taggedClassicVMs = Find-AzureRMResource -ResourceGroupName $ResourceGroup.ResourceGroupName -ResourceType "Microsoft.ClassicCompute/virtualMachines"
    		foreach($vmResource in $taggedClassicVMs)
    		{
    			if ($vmResource.ResourceGroupName -Like $rg)
    			{
    			    $targetVM += @{Name = $vmResource.Name; ResourceGroupName = $vmResource.ResourceGroupName; Type = "Classic"}
    			}
    		}
    		
    		# Get resource manager VM resources in group and record target state for each in table
    		$taggedRMVMs = Find-AzureRMResource -ResourceGroupName $ResourceGroup.ResourceGroupName -ResourceType "Microsoft.Compute/virtualMachines"
    		foreach($vmResource in $taggedRMVMs)
    		{
    			if ($vmResource.ResourceGroupName -Like $rg)
    			{
    			    $targetVM += @{Name = $vmResource.Name; ResourceGroupName = $vmResource.ResourceGroupName; Type = "ResourceManager"}
    			}
    		}
    	}
    
        foreach ($vm in $targetVM)
        {
            #Check if VM is in the excluded list
            $isItemExcluded = $false
            $excludeList = $vmExcludeList.split(";")
            foreach ($excludeItem in $excludeList)
            {
                if ($vm.Name -Like $excludeItem)
                {
                    $isItemExcluded = $true					
                }
            }
            
            if ($isItemExcluded -eq $false)
            {			
                if ($vm.Type -eq "Classic")
                {
                    Write-Verbose "Starting VM $($vm.Name) using Classic"
                    $currentVM = Get-AzureVM | where Name -Like $vm.Name
                    if ($currentVM.Count -ge 1)
                    {
                        Start-AzureVM -Name $currentVM.Name -ServiceName $currentVM.ServiceName
                    }
                    else
                    {
                        Write-Error "Error: No VM instance with name $($vm.Name) found"
                    }
                } 
                elseif ($vm.Type -eq "ResourceManager")
                {
                    Write-Verbose "Starting VM $($vm.Name) using AzureRM"
                    Start-AzureRmVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName
                }
            }
            else
            {
                Write-Verbose "Skipping $($vm.Name) as this VM is in the exclude list ($vmExcludeList); No management operation applied"
            }
        }
    }
    
    Write-Verbose "Runbook completed"
    
    # End of runbook


    David Rendón @DaveRndn

    • Marcado como respuesta Nacho_ch miércoles, 24 de enero de 2018 7:48
    miércoles, 24 de enero de 2018 0:01

Todas las respuestas

  • Hola Nacho, 

    Te recomiendo utilizar checkpoints para revisar el estado de tu workflow (https://docs.microsoft.com/en-us/azure/automation/automation-powershell-workflow#checkpoints), te comparto un ejemplo de un runbook para iniciar tu(s) VM(s): 

    $currentTime = (Get-Date).ToUniversalTime()
    Write-Verbose "Runbook started"
    Write-Verbose "Current UTC time [$($currentTime.ToString("dddd, yyyy MMM dd HH:mm:ss"))]"
    
    $targetResourceGroups = Get-AutomationVariable -Name 'StartByResourceGroupV2-TargetResourceGroups-MS-Mgmt-VM'
    $targetSubscriptionId =	Get-AutomationVariable -Name 'StartByResourceGroupV2-TargetSubscriptionID-MS-Mgmt-VM'
    $vmExcludeList = Get-AutomationVariable -Name 'StartByResourceGroupV2-ExcludeList-MS-Mgmt-VM'
    Write-Verbose "Target ResourceGroups:  $targetResourceGroups"
    Write-Verbose "Target SubscriptionID:  $targetSubscriptionId"
    Write-Verbose "Exclude list:  $vmExcludeList"
    
    #
    # Initialize the Azure subscription we will be working against for AzureRM resources
    #
    Write-Verbose "Authenticating ARM RunAs account"
    $connectionName = "AzureRunAsConnection"
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName      
    
    # retry
    $retry = 6
    $syncOk = $false
    do
    { 
    	try
    	{  
    		Add-AzureRmAccount -ServicePrincipal -TenantId $servicePrincipalConnection.TenantId -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
    		$syncOk = $true
    	}
    	catch
    	{
    		$ErrorMessage = $_.Exception.Message
    		$StackTrace = $_.Exception.StackTrace
    		Write-Warning "Error during sync: $ErrorMessage, stack: $StackTrace. Retry attempts left: $retry"
    		$retry = $retry - 1       
    		Start-Sleep -s 60        
    	}
    } while (-not $syncOk -and $retry -ge 0)
    
    Select-AzureRMSubscription -SubscriptionId $targetSubscriptionId -TenantId $servicePrincipalConnection.TenantId
    $currentSubscription = Get-AzureRMSubscription -SubscriptionId $targetSubscriptionId -TenantId $servicePrincipalConnection.TenantId
    Write-Verbose "Found ARM subscription [$($currentSubscription.SubscriptionName)] ($($currentSubscription.SubscriptionId))"
    
    #
    # Initialize the Azure subscription we will be working against for Classic Azure resources
    #
    Write-Verbose "Authenticating Classic RunAs account"
    $ConnectionAssetName = "AzureClassicRunAsConnection"
    $connection = Get-AutomationConnection -Name $connectionAssetName        
    Write-Verbose "Get connection asset: $ConnectionAssetName" -Verbose
    $Conn = Get-AutomationConnection -Name $ConnectionAssetName
    if ($Conn -eq $null)
    {
        throw "Could not retrieve connection asset: $ConnectionAssetName. Assure that this asset exists in the Automation account."
    }
    $CertificateAssetName = $Conn.CertificateAssetName
    Write-Verbose "Getting the certificate: $CertificateAssetName" -Verbose
    $AzureCert = Get-AutomationCertificate -Name $CertificateAssetName
    if ($AzureCert -eq $null)
    {
        throw "Could not retrieve certificate asset: $CertificateAssetName. Assure that this asset exists in the Automation account."
    }
    Write-Verbose "Authenticating to Azure with certificate." -Verbose
    Set-AzureSubscription -SubscriptionName $Conn.SubscriptionName -SubscriptionId $Conn.SubscriptionID -Certificate $AzureCert 
    Select-AzureSubscription -SubscriptionId $Conn.SubscriptionID
    
    $rgList = $targetResourceGroups.split(";")
    foreach ($rg in $rgList)
    {
    	#Get all ARM resources from all resource groups
    	$ResourceGroups = Get-AzureRmResourceGroup | where ResourceGroupName -Like $rg
    	$targetVM = @()
    	foreach ($ResourceGroup in $ResourceGroups)
    	{    
    		# Get classic VM resources in group and record target state for each in table
    		$taggedClassicVMs = Find-AzureRMResource -ResourceGroupName $ResourceGroup.ResourceGroupName -ResourceType "Microsoft.ClassicCompute/virtualMachines"
    		foreach($vmResource in $taggedClassicVMs)
    		{
    			if ($vmResource.ResourceGroupName -Like $rg)
    			{
    			    $targetVM += @{Name = $vmResource.Name; ResourceGroupName = $vmResource.ResourceGroupName; Type = "Classic"}
    			}
    		}
    		
    		# Get resource manager VM resources in group and record target state for each in table
    		$taggedRMVMs = Find-AzureRMResource -ResourceGroupName $ResourceGroup.ResourceGroupName -ResourceType "Microsoft.Compute/virtualMachines"
    		foreach($vmResource in $taggedRMVMs)
    		{
    			if ($vmResource.ResourceGroupName -Like $rg)
    			{
    			    $targetVM += @{Name = $vmResource.Name; ResourceGroupName = $vmResource.ResourceGroupName; Type = "ResourceManager"}
    			}
    		}
    	}
    
        foreach ($vm in $targetVM)
        {
            #Check if VM is in the excluded list
            $isItemExcluded = $false
            $excludeList = $vmExcludeList.split(";")
            foreach ($excludeItem in $excludeList)
            {
                if ($vm.Name -Like $excludeItem)
                {
                    $isItemExcluded = $true					
                }
            }
            
            if ($isItemExcluded -eq $false)
            {			
                if ($vm.Type -eq "Classic")
                {
                    Write-Verbose "Starting VM $($vm.Name) using Classic"
                    $currentVM = Get-AzureVM | where Name -Like $vm.Name
                    if ($currentVM.Count -ge 1)
                    {
                        Start-AzureVM -Name $currentVM.Name -ServiceName $currentVM.ServiceName
                    }
                    else
                    {
                        Write-Error "Error: No VM instance with name $($vm.Name) found"
                    }
                } 
                elseif ($vm.Type -eq "ResourceManager")
                {
                    Write-Verbose "Starting VM $($vm.Name) using AzureRM"
                    Start-AzureRmVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName
                }
            }
            else
            {
                Write-Verbose "Skipping $($vm.Name) as this VM is in the exclude list ($vmExcludeList); No management operation applied"
            }
        }
    }
    
    Write-Verbose "Runbook completed"
    
    # End of runbook


    David Rendón @DaveRndn

    • Marcado como respuesta Nacho_ch miércoles, 24 de enero de 2018 7:48
    miércoles, 24 de enero de 2018 0:01
  • Gracias!

    Nacho

    miércoles, 24 de enero de 2018 7:48