Otimizando Recursos: Estratégias Inteligentes para Desligar o AVD Quando Não Está em Uso

março 26, 2024 4 mins to read
Share

Neste guia, vamos demonstrar como configurar uma automação para desligar as máquinas virtuais que não estão sendo utilizadas no ambiente do Azure Virtual Desktop (AVD)

Definição da GPO

Essa automação é responsável por desligar as máquinas virtuais que não têm usuários conectados. No entanto, para garantir o seu funcionamento correto, é necessário configurar o tempo de logoff da sessão do usuário em caso de inatividade antes de executar a automação.

Computer Configuration > Administrative Templets >
Windows Components > Remote Desktop Services > Remote Desktop Session
Host > Session Time limits

Acessando a politica de GPO acima é possivel definir o tempo de logoff da sessão do usuario

Criando o aplicativo de funçao

Através do Portal do Azure, faça uma busca pelo function app e clique em create

Preencha as informações solicitadas de acordo com o seu ambiente, mantendo as configurações específicas da sua subscription, e as demais informações conforme as orientações fornecidas

Neste caso, forneceremos apenas as informações básicas, mantendo as configurações padrão e, em seguida, clicaremos em “create”

Configurando o aplicativo

Com aplicativo criado vamos clicar em “App files”


E agora, na linha 7, devemos manter conforme abaixo:

Após concluir essa etapa, salve as alterações e retorne para a visão geral (Overview), em seguida, reinicie o aplicativo conforme demonstrado abaixo:

Configurando Permissões no Aplicativo

Agora, vamos conceder permissões ao aplicativo. Siga os passos abaixo: vá para ‘Identity’, ative o status e, em seguida, clique em ‘Atribuições de Função do Azure’

Clique em Add role assignment

Atribua as permissoes Desktop Virtualization Reader e Virtual Machine Contributor

Criando a função

Retorne à tela inicial ‘Overview’ e clique em ‘Criar Função

Selecione Timer trigger para definir o tempo de checagem do script

No nosso caso, configuraremos o script para rodar a cada 5 minutos, visando desligar as VMs sem uso. No entanto, a frequência pode variar de acordo com as necessidades específicas de cada ambiente

Agora clique em code + Test

E depois, insira o seguinte script em seu ambiente. Isso permitirá que o script liste todos os pools e VMs disponíveis e desligue apenas as máquinas que não têm usuários conectados, ignorando aquelas que estão em uso.

# Input bindings are passed in via param block.
# For the Function App
param($Timer)

########## Script Execution ##########
try {
    # Obtém todos os pools de host na assinatura
    $allHostPools = Get-AzWvdHostPool

    foreach ($hostPool in $allHostPools) {
        $pool = $hostPool.Name
        $poolRg = (Get-AzResource -ResourceId $hostPool.Id).ResourceGroupName
        Write-Output "This is the key (pool) $pool"
        write-output "this is the value (rg) $poolRg"
        
        # Get the active Session hosts
        try {
            $activeShs = (Get-AzWvdUserSession -ErrorAction Stop -HostPoolName $pool -ResourceGroupName $poolRg).name
        }
        catch {
            $ErrorMessage = $_.Exception.message
            Write-Error ("Error getting a list of user sessions: " + $ErrorMessage)
            Continue
        }
        
        $allActive = @()
        foreach ($activeSh in $activeShs) {
            $activeSh = ($activeSh -split { $_ -eq '.' -or $_ -eq '/' })[1]
            if ($activeSh -notin $allActive) {
                $allActive += $activeSh
            }
        }
        
        # Get the Session Hosts
        # Exclude servers in drain mode and do not allow new connections
        try {
            $runningSessionHosts = (Get-AzWvdSessionHost -ErrorAction Stop -HostPoolName $Pool -ResourceGroupName $poolRg | Where-Object { $_.AllowNewSession -eq $true })
        }
        catch {
            $ErrorMessage = $_.Exception.message
            Write-Error ("Error getting a list of running session hosts: " + $ErrorMessage)
            Continue
        }
        
        $availableSessionHosts = ($runningSessionHosts | Where-Object { $_.Status -eq "Available" })
        
        # Evaluate the list of running session hosts against 
        foreach ($sessionHost in $availableSessionHosts) {
            $sessionHostName = (($sessionHost).name -split { $_ -eq '.' -or $_ -eq '/' })[1]
            if ($sessionHostName -notin $allActive) {
                Write-Host "Server $sessionHostName is not active, shut down"
                try {
                    # Stop the VM
                    Write-Output "Stopping Session Host $sessionHostName"
                    Get-azvm -ErrorAction Stop -Name $sessionHostName -ResourceGroupName $poolRg | Stop-AzVM -ErrorAction Stop -Force -NoWait
                }
                catch {
                    $ErrorMessage = $_.Exception.message
                    Write-Error ("Error stopping the VM: " + $ErrorMessage)
                    Continue
                }
            }
            else {
                write-host "Server $sessionHostName has an active session, won't shut down"
            }
        }
    }
}
catch {
    $ErrorMessage = $_.Exception.Message
    Write-Error ("Error getting a list of host pools: " + $ErrorMessage)
}

Segue um exemplo do meu laboratorio:

Após concluir essas etapas, clique em Test/Run. Nos logs exibidos abaixo, você poderá verificar que o script desligou apenas a máquina que não estava em uso, enquanto a outra foi ignorada.

Validação

O log da VM confirma que ela foi desligada pelo aplicativo que configuramos, como podemos ver

Conclusão

Nesta publicação, exploramos como otimizar os custos do ambiente de forma inteligente, evitando gastos desnecessários e pagando apenas pelo que realmente estamos utilizando. Essa estratégia permite uma alocação mais eficiente dos recursos, garantindo uma gestão financeira mais assertiva

AVD

Deixe um comentário

Seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *