시작, RDP 및 중지: 비용을 최적화하면서 Azure VM 자동화

22501 단어 powershellazure
나는 이미 이 글을 몇 주 동안 쓰고 싶었는데, 마침내 약간의 시간을 안배했다.다음은 매우 구체적인 목표를 달성하기 위해 여러 출처에서 모은 멋진 PowerShell 스크립트의 대략적인 요약입니다.

질문 1: 워크플로우


Azure에서 Windows 10 가상 머신을 설정하는 사람들은 Azure 포털에 가서 가상 머신을 분배하고 공공 IP를 가져오며 (정적 IP를 분배하지 않았다면) 원격 데스크톱 클라이언트에 삽입하는 데 시간을 들이는 것을 알게 될 것이다.간단한 임무에 대해 말하자면, 이 과정은 상당히 간단하다.비기술 사용자를 위해 가상 머신을 설정하는 경우 Azure 포털에 로그인해야 하는 경우도 없습니다.

질문 2: 비용 최적화


네이티브 Azure Portal VM 스케줄러(및 기타 여러 도구)를 사용하면 가능합니다modify the startup and shutdown schedules of your VMs.이것은 매우 좋은 기능이지만, 많은 Azure 애호가들이 알고 있는 바와 같이, VM을 정지하는 것은 분배를 취소하는 것과 다르다. 특히 계산서를 볼 때이다.너는 너의 가상 기기를 위해 시간표를 설정할 수 있지만, 신뢰할 수 있는 가상 기기의 사용 시간표가 없다면, 너는 너의 가상 기기를 운행하게 해서 비싼 계산서에 직면하게 될 것이다.설령 네가 그들을 막는다 하더라도, 너는 대가를 치르게 될 것이다.
Park My Cloud의 Chris Parlette가 나에게 말한 perfect description에 대한 답이 하나 있다.다음을 참조하겠습니다.

Azure의 중지 상태

When you are logged in to the operating system of an Azure VM, you can issue a command to shut down the server. This will kick you out of the OS and stop all processes, but will maintain the allocated hardware (including the IP addresses currently assigned). If you find the VM in the Azure console, you’ll see the state listed as “Stopped”. The biggest thing you need to know about this state is that you are still being charged by the hour for this instance.

Azure의 할당 해제 상태

The other way to stop your virtual machine is through Azure itself, whether that’s through the console, Powershell, or the Azure CLI. When you stop a VM through Azure, rather than through the OS, it goes into a “Stopped (deallocated)” state. This means that any non-static public IPs will be released, but you’ll also stop paying for the VM’s compute costs. This is a great way to save money on your Azure costs when you don’t need those VMs running, and is the state that ParkMyCloud puts your VMs in when they are parked.

어느 주를 선택합니까?

The only scenario in which you should ever choose the stopped state instead of the deallocated state for a VM in Azure is if you are only briefly stopping the server and would like to keep the dynamic IP address for your testing. If that doesn’t perfectly describe your use case, or you don’t have an opinion one way or the other, then you’ll want to deallocate instead so you aren’t being charged for the VM.


글에서 Park My Cloud에 대한 간결한 설명을 제외하고는 그들을 지원하지 않지만, 그들의 서비스는 확실히 매우 유용해 보인다. (특히 그들이 당신의 가상 기기를 비근무 시간의 비분배 모델에 주차하기 때문이다.)

빠른 솔루션:


나의 한 고객은 상술한 두 가지 문제를 가지고 있다.그들의 가상 기기는 사용이 매우 흩어져서 스케줄링 시스템이 정말 일을 할 수 없다.그들도 사용자가 Azure 포털에 로그인하고 가상 컴퓨터를 시작하며 IP를 얻고 원격 데스크톱을 설정하도록 훈련하고 싶지 않다.비기술 사용자에게는 많은 절차가 필요하다.Azure에서는 권한 부여 제어가 가능하지만 VM에 액세스하려는 목적으로만 포털에 로그인하지 않도록 하는 것이 좋습니다.
그래서 나는 이 힘든 일을 완성하기 위해 PowerShell 스크립트를 짜내기 시작했다.

이러한 요구 사항은 다음과 같습니다.


1) 포털에 액세스하지 않고 VM을 시작합니다.
2) VM 액세스 자격 증명을 사용하여 사용자(Microsoft Prompt)에게 프롬프트를 표시합니다.
3) RDP 클라이언트를 자동으로 시작하고 연결을 초기화합니다.
4) 사용자가 RDP 세션을 닫으면 VM이 자동으로 중지되고 할당이 취소됩니다.
이 가상 컴퓨터는 여러 사용자가 동시에 사용하지 않기 때문에 스크립트는 다른 사람이 로그인하고 있다는 것을 설명할 필요가 없다.즉, 하나의 솔루션like this은 Azure 측의 모든 RDP 연결을 감청하기 위해 아래의 PS 스크립트와 병합할 수 있다.연결이 없으면 VM 할당이 취소될 수 있습니다.그렇지 않으면 할당이 중지되거나 취소되지 않습니다.기본적으로 마지막 사용자가 VM을 종료하는 정책을 따를 수 있습니다.그럼에도 불구하고 다음 해결 방안은 한 번에 단독으로 사용하거나 가끔 VM을 사용하는 데 좋은 선택이라고 생각합니다.
내가 코드를 보여주기 전에, 나는 이것이 몇 시간 안에 완성된 것이라고 지적하고 싶었다.고객은 단지 신속하고 더러운 해결 방안을 원할 뿐이다.나는 이것이 가장 좋은 코드라고 생각하지 않지만, 그것은 틀림없이 자신이 스크립트라는 것을 인정할 것이다.

개요:


1) 자기계발 시나리오
2) 의존성 검사를 하고,
3) Microsoft prompt를 통해 자격 증명을 수집합니다.
4) 가상 시스템을 수집하고 부트합니다.
5) Azure VM 시작
7) VM에 대한 RDP 세션 시작
8) 회의 추적
9) RDP 세션이 종료되면 할당이 취소됩니다.
Azure 리소스 그룹 이름과 VM 이름RESOURCEGROUPNAMEHEREVMNAMEHERE만 바꾸면 됩니다.나머지는 불가지론적일 것이다.
# Self-elevate the script if required
"`Self Elevating...`n"
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
        $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
        Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
        Exit
    }
}

"`nChecking/mitigating Powershell Execution Policy...`n"
if($(Get-ExecutionPolicy) -ne 'RemoteSigned')
{
`set-executionpolicy remotesigned
}

"`nInitiating settings and dependencies pre-check/installation`n"
"`nChecking/mitigating Remote Desktop...`n"
#Enable-PSRemoting -SkipNetworkProfileCheck -Force
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "UserAuthentication" -Value 1


"`nChecking/mitigating Azure Powershell module...`n"
if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-Module -Name AzureRM -ListAvailable)) {
   Write-Warning -Message ('Az module not installed. Having both the AzureRM and ' +
   'Az modules installed at the same time is not supported.')
} else {
     Install-Module -Name Az -AllowClobber -Scope CurrentUser
}

"`nGetting Azure Credentials and authenticating...`n"

Connect-AzAccount

"`nChecking Azure VM status...`n"

#$status =  Get-AzVM `
#   -ResourceGroupName "<RESOURCEGROUPNAMEHERE>" `
#   -Name "<VMNAMEHERE>" -Status

#Write-Output $status.Statuses.DisplayStatus

#if($($status.Statuses.DisplayStatus) -ne "VM deallocated")
#{
#    pause("Please try again later")
#    exit
#}

"`nStarting Azure VM <RESOURCEGROUPNAMEHERE> <VMNAMEHERE>...`n"

Start-AzVM `
   -ResourceGroupName "<RESOURCEGROUPNAMEHERE>" `
   -Name "<VMNAMEHERE>"

"`nGetting public IP of <VMNAMEHERE>...`n"


$ip = Get-AzPublicIpAddress `
   -ResourceGroupName "<RESOURCEGROUPNAMEHERE>"  | Select IpAddress

"`nStarting remote desktop session...`n"

mstsc /v:$($ip.{IpAddress})

Start-Sleep -s 60

$rdpsession = Get-Process mstsc -ErrorAction SilentlyContinue

Write-Output $rdpsession

"`nYour session is up and now being tracked. Listening for remote desktop closure...`n"

$hasd = "false"

for(;;)
{
   $rdpsession = Get-Process mstsc -ErrorAction SilentlyContinue
    if (!$rdpsession) {
        "`nRemote desktop session ended.`n"

        Stop-AzVM `
           -ResourceGroupName "<RESOURCEGROUPNAMEHERE>" `
           -Name "<VMNAMEHERE>"

         $hasd = "true"

        "`nStopping <VMNAMEHERE>...`n"

        break
    }
}

Register-EngineEvent PowerShell.Exiting Action { if($hasd -eq "false")
{
    Stop-AzVM `
           -ResourceGroupName "<RESOURCEGROUPNAMEHERE>" `
           -Name "<VMNAMEHERE>"

        "`nStopping <VMNAMEHERE>...`n"
}}


Function pause ($message)
{
    # Check if running Powershell ISE
    if ($psISE)
    {
        Add-Type -AssemblyName System.Windows.Forms
        [System.Windows.Forms.MessageBox]::Show("$message")
    }
    else
    {
        Write-Host "$message" -ForegroundColor Yellow
        $x = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
}
구현할 수 있는 주의 사항:
  • 패라메트릭 VMRESOURCENAME
  • 패라메트릭 VMNAME
  • 현재 전체 AZ 모듈이 설치되어 있습니다...시간이 좀 걸릴 것 같습니다.의지만 할 수 있을 정도로 줄어들다.
  • 마지막 할당 취소 정책의 기능을 추가합니다.
  • PowerShell 애호가라면 위의 수정, 코드 정리, 오류 처리 추가 또는 자신의 기능/수정을 원하시면 Github Gist에 방문하실 수 있습니다. 저는 거기에서 상술한 코드를 발표하고 개선을 위해 협업을 진행했습니다.(솔직히 말하면 저는 지금 대본을 분배하고 보완할 시간이 없기 때문에 지역 사회를 위해 대본을 개선하는 데 도움을 주셔서 감사합니다.)
    Here is the GH Gist
    읽어주셔서 감사합니다!만약 맞춤법 오류나 문법 문제가 있다면, 내가 그것들을 수정할 수 있도록 아래에서 평론해 주십시오.
    만약 당신이 이 문장을 좋아하고 더 많은 것을 보고 싶다면, 저에게 Dev.to, Github 또는 LinkedIn의 후속 문장을 한 편 주세요.만약 네가 원한다면, 너도 나에게 커피 한 잔을 사 줄 수 있다.당신의 지지에 대단히 감사합니다!
    > Connect with me
    

    > Support me
    

    > Support everybody
    
    자금을 이전하는 능력은 줄곧 인터넷 플랫폼의 장기적인 누락이다.이 때문에 인터넷은 대량의 광고와 부패한 상업 모델에 시달리고 있다.Web Monetization는 창설자를 보상하고 API 호출 비용을 지불하며 관건적인 웹 인프라를 지원하는 개방적이고 본체적이며 효율적이고 자동적인 방식을 제공했다.네트워크를 바꾸는 데 도움을 주는 방법에 관해.

    좋은 웹페이지 즐겨찾기