[Azure][PowerShell]透過 PowerShell 快速大量的建立 VM (2/2)

接續前一篇,此篇主要介紹怎麼將整批的指令封裝起來一次執行

在 Cloud Shell 裡面,其實最方便的不只是可以直接用 PowerShell 來做維護,我個人覺得最方便的是他提供一個便利的編輯器,讓你可以很方便的維護檔案和執行,因為當指令少的時候雖然很方便容易,但指令多的時候就比較繁瑣了。因為在 Cloud Shell 他其實是一個 ubuntu 的環境,並且加掛上許多的便捷工具,您可以直接用 「code . 」的方式進入線上編輯器 ( 就像地端使用 VSCode 一般 ) 

執行之後,就會看到類似下圖一般的一個簡潔的線上編輯器( 藍色區域 ),讓您可以很方便地來維護放在 Cloud Shell 內的檔案。另外右上角 (紅色區域) 也可以讓您來進行存檔和關閉的選項。

我想使用比較沒有問題,比較大的困擾的是檔案放在哪裡和如何來執行這個 Schell 的檔案。因為我們在使用 Cloud Shell 的時候,他所在的位置是在 Azure 下面,而線上編輯器預設是抓 Home 目錄下,因此如果我們要切換到 Home 的目錄之下,可以利用 「cd ~ 」就可以來做切換了。切換之後我們在線上編輯器存的檔案,在這裡就可以找到了。假如您使用之後又要切回原本的預設目錄,也可以直接使用「cd Azure:」,也就可以順利切回來了。

但如果檔案建立好之後,我們要怎麼來執行呢 ? 這裡跟在 Windows 下執行 PowerShell 的方式有點不同,您把檔案當成 Linux 的 Shell Script 去執行就可以了,因此只要使用「./createvm.ps1」就可以了

基本上這樣就可以順利執行了。而我在測試的時候,原本都沒有甚麼問題,後來把整個腳本寫好之後,一值會有失敗,原本以為是自己腳本哪裡寫錯了,後來查看一下原來是虛擬核心數的限制,一般來說 Azure 預設訂閱下的虛擬核心數是 20 ,因此如果您會需要超過這個限制的話,那麼就要先開一個 Ticker ( https://portal.azure.com/#create/Microsoft.Support ),請微軟的技術窗口協助您將限制給放大。

在我的範例中,會將這些建立的過程放在背景執行,這樣你就不用一值在那慢慢等 VM 建立了,可以一次把所有要建立的都放下去跑,這一點來說用腳本建立實在太方便了。

所有 VM 都建立好了

透過 Azure Portal 也可以看到我們用腳本建立的相關 VM 都被建立起來了

接下來如果要讓他們都啟動起來囉,同樣的也是使用腳本來執行 Start-AzVM

相對的如果要關閉,也可以同樣的方式來呼叫 Stop-AzVM 來進行,但要注意的是不要忘記加入 -Force 的參數,否則你放到背景去執行,他會一值等你確認是否要關閉,就會卡在那裏了

此次測試的腳本如下,有需要的朋友可以按照您所想要的去調整一下,因為有一段是會建立公用 IP 的時候,會使用 DomainNameLabel  的參數,這個會要唯一值,因此可能要稍微按照您所想要的去調整一下囉。

$resourceGroup = "TEST"     # 資源群組
$location = "EastAsia"      # 區域
$name = "TEST"              # VM 名稱
$vmcount = 5                # VM 數量  
$vmadmin = "vmadmin"        # Admin 帳號
$pwd='1qaz@WSX3edc'| ConvertTo-SecureString -Force -AsPlainText # Admin 密碼

$cred=New-Object PSCredential($vmadmin,$pwd)

# 建立資源群組
New-AzResourceGroup -ResourceGroupName $resourceGroup -Location $location

# 建立可允許連線規格
$rdpRule = New-AzNetworkSecurityRuleConfig -Name rdp-rule -Description "Allow RDP" `
   -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 `
   -SourceAddressPrefix Internet -SourcePortRange * `
   -DestinationAddressPrefix * -DestinationPortRange 3389

# 建立網路安全群組
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroup  `
  -Location $location -Name $resourceGroup"-nsg" -SecurityRules $rdpRule

# 建立子網路
$subnet = New-AzVirtualNetworkSubnetConfig -Name $resourceGroup"-vmSubnet" `
    -AddressPrefix "10.0.1.0/25" -NetworkSecurityGroup $nsg -WarningAction SilentlyContinue

# 建立虛擬網路網路
$vnet = New-AzVirtualNetwork -Name $resourceGroup"-vnet" -ResourceGroupName $resourceGroup `
    -Location $location -AddressPrefix "10.0.1.0/24" -Subnet $subnet `
    -WarningAction SilentlyContinue


for($i = 1; $i -le $vmcount ; $i++)  
{
  
  $vmname = $name + ([string]$i).PadLeft(2,'0')

  # 產生公用 IP , 網域名稱要用小寫
  $pip = New-AzPublicIpAddress -ResourceGroupName $resourceGroup -Location $location `
    -Name $vmname"-ip" -AllocationMethod Static -DomainNameLabel $vmname.toLower()

  # 產生虛擬網卡
  $nic = New-AzNetworkInterface -ResourceGroupName $resourceGroup -Location $location `
    -Name $vmname"-nic" -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id

  # 建立虛擬機器的相關設定
  $vmConfig = New-AzVMConfig -VMName $vmname"-vm" -VMSize Standard_DS2_V2 
  $vmConfig | Set-AzVMOperatingSystem -Windows -ComputerName $vmname -Credential $cred -TimeZone "Taipei Standard Time" 
  $vmConfig | Set-AzVMSourceImage -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2016-Datacenter -Version latest
  $vmConfig | Add-AzVMNetworkInterface -Id $nic.Id 
  $vmConfig | Set-AzVMBootDiagnostic -Disable 
  $vmConfig | Set-AzVMOSDisk -Name $vmname"-osdisk" -Caching ReadWrite -StorageAccountType "Standard_LRS" -CreateOption FromImage 

  # 建立虛擬機器並放置到背景執行
  New-AzVM -ResourceGroupName $resourceGroup -Location $location -VM $vmConfig -AsJob
}
Get-Job