top of page
Writer's pictureGeorge Lin

Create AAA Hybrid Worker Group On VMSS With PowerShell - Part 2

Updated: Nov 18, 2021


Step 8: Test importing an automation runbook

Create a PowerShell script named MytestRunbookScript.ps1 containing the following code:

$MachineName = $env:computername
$RGName = "MyTest-CUS-RG01"
Disable-AzContextAutosave –Scope Process

$ConnectionName = "AzureRunAsConnection"

try {
    # Get the connection "AzureRunAsConnection "
    $ServicePrincipalConnection = Get-AutomationConnection -Name $ConnectionName         

    "Logging in to Azure..."
    Add-AzAccount `
        -ServicePrincipal `
        -TenantId $ServicePrincipalConnection.TenantId `
        -ApplicationId $ServicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint 
}
catch {
    if (!$ServicePrincipalConnection) {
        $ErrorMessage = "Connection $ConnectionName not found."
        throw $ErrorMessage
    }
    else {
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}

Set-AzContext -SubscriptionId $ServicePrincipalConnection.SubscriptionID
Get-AzContext

$AutoAcctName = Get-AutomationVariable -Name AutoAcctName

$AAVariablePairs = Get-AzAutomationVariable -ResourceGroupName $RGName -AutomationAccountName $AutoAcctName

Write-output "The runbook worker name is '$MachineName'"

Write-output "The list of vairables/Value pairs in automation account '$AutoAcctName' in resource group '$RGName'"
$AAVariablePairs | ForEach-Object {
    $VName = $_.Name
    $VValue = Get-AutomationVariable -Name $_.Name
    Write-output "$VName = $VValue"
} 

Then run:

$MyTestRunbookName = "MyTest-Runbook02"
$MyTestRunbookScriptPath = ".\MytestRunbookScript01.ps1"
if (Get-AzAutomationRunbook -ResourceGroupName $RGName -AutomationAccountName $AutoAcctName -Name $MyTestRunbookName -ErrorAction SilentlyContinue) {
    Remove-AzAutomationRunbook -ResourceGroupName $RGName `
        -AutomationAccountName $AutoAcctName `
        -Name $MyTestRunbookName `
        -Force
}

Import-AzAutomationRunbook -ResourceGroupName $RGName `
    -AutomationAccountName $AutoAcctName `
    -Name $MyTestRunbookName `
    -Path $MyTestRunbookScriptPath `
    -Type PowerShell `
    -Published

Step 9: Testing running an Automation runbook

if (Get-AzAutomationRunbook -ResourceGroupName $RGName -AutomationAccountName $AutoAcctName -Name $MyTestRunbookName -ErrorAction SilentlyContinue) {
    Start-AzAutomationRunbook -ResourceGroupName $RGName `
        -AutomationAccountName $AutoAcctName `
        -Name $MyTestRunbookName
}

Step 10: Check Automation runbook job status

$MyTestRunbookJob = Get-AzAutomationJob -ResourceGroupName $RGName `
    -AutomationAccountName $AutoAcctName `
    -RunbookName $MyTestRunbookName

$MyTestRunbookJobOutput = $MyTestRunbookJob | Select-Object ResourceGroupName, AutomationAccountName, @{N = "Id"; E = "JobId" } | Get-AzAutomationJobOutput

$MyTestRunbookJobOutput | Get-AzAutomationJobOutputRecord | Select-Object -Property type -ExpandProperty Value | Format-Table -Wrap -AutoSize

$MyTestRunbookJobOutput | Get-AzAutomationJobOutputRecord | Select-Object -ExpandProperty Value

Step 11: Prepare an Azure Virtual Network for VMSS

Here is the steps required to create and configure an Azure VNet with PowerShell

  1. Define a virtual network with name, address prefix in specified location

  2. Define a subnet configuration with name and address prefix

  3. Create the subnet in the virtual network

  4. Define a Network Security Group (NSG) rule

  5. Create a NSG with the NSG rule created in the last step

  6. Assign the NSG to the subnet

Below is the script

# Create a virtual network

$VNetName = "MyTest-CUS-VNet01"
$VNetAddressPrefix = "172.18.0.0/16"

if (!(Get-AzVirtualNetwork -Name $VNetName -ErrorAction SilentlyContinue)) {
    $MyTestVNet = New-AzVirtualNetwork -ResourceGroupName $RGName -Location $Location -Name $VNetName -AddressPrefix $VNetAddressPrefix
}

$SubnetName = "Default"
$SubnetAddressPrefix = "172.18.0.0/24"

if (!(Get-AzVirtualNetworkSubnetConfig -VirtualNetwork $MyTestVNet -Name $SubnetName -ErrorAction SilentlyContinue)) {
    $SubnetConfig = Add-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix -VirtualNetwork $MyTestVNet
    $MyTestVNet | Set-AzVirtualNetwork
}

# Create NSG security rules
$MGMTRule = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP-SSH-From-IPRange" `
    -Access Allow `
    -Protocol Tcp `
    -Direction Inbound `
    -Priority 110 `
    -SourceAddressPrefix "99.245.13.136,72.28.70.238 " `
    -SourcePortRange * `
    -DestinationAddressPrefix VirtualNetwork `
    -DestinationPortRange 22, 3389, 5985

# Create an NSG
$NSGName = "MyTest-CUS-NSG01"
if (!(Get-AzNetworkSecurityGroup -ResourceGroupName $RGName -Name $NSGName -ErrorAction SilentlyContinue)) {
    $MyTestNSG = New-AzNetworkSecurityGroup -ResourceGroupName $RGName -Name $NSGName -Location $Location -SecurityRules $MGMTRule
}

# Assign the NSG to the Subnet
$MyTestSubnet = Get-AzVirtualNetworkSubnetConfig -VirtualNetwork $MyTestVNet -Name Default
$MyTestSubnet.NetworkSecurityGroup = $MyTestNSG
Set-AzVirtualNetwork -VirtualNetwork $MyTestVNet

Step 12: Create a storage account

A blob container and a file share are also need to be created in the storage account.


$StorageAcctname = "mytestcussa01"

$SKUName = "Standard_LRS"

if (!(Get-AzStorageAccount -ResourceGroupName $RGName -Name $StorageAcctname -ErrorAction SilentlyContinue)) {
    $MyStorageAcct = New-AzStorageAccount -ResourceGroupName $RGName -Name $StorageAcctname -SkuName $SKUName -Location $Location
}

$MySAContext = (Get-AzStorageAccount -ResourceGroupName $RGName -Name $StorageAcctname).Context

$SAContainerName = "scripts"

if (!(Get-AzStorageContainer -Name $SAContainerName -Context $MySAContext -ErrorAction SilentlyContinue)) {
    $MySAContainer = New-AzStorageContainer -Name $SAContainerName -Context $MySAContext -Permission Off
}

$SAFileShareName = "azautomationfiles"

if (!(Get-AzStorageShare -Name $SAFileShareName -Context $MySAContext -ErrorAction SilentlyContinue)) {
    $MySAFileShare = New-AzStorageShare -Name $SAFileShareName -Context $MySAContext
    $MySAFileShare | Set-AzStorageShareQuota -Quota 1
}

$MySAFileShare = Get-AzStorageShare  -Name $SAFileShareName -Context $MySAContext
$MySAFileShare | New-AzStorageDirectory -Path "Log"

Step 13: Test uploading and manage files to the Blob container

Set-AzStorageBlobContent -File .\MytestRunbookScript01.ps1 -Container $SAContainerName -Blob "MyTestRunbookScript01.ps1" -Context $MySAContext

Copy-Item .\MytestRunbookScript01.ps1 .\MytestRunbookScript01Copy.ps1

Set-AzStorageBlobContent -File .\MytestRunbookScript01Copy.ps1 -Container $SAContainerName -Blob "MyTestRunbookScript01Copy.ps1" -Context $MySAContext -StandardBlobTier Cool

# List the blobs in a container
Get-AzStorageBlob -Container $SAContainerName -Context $MySAContext

# Download the blobs in a container
Get-AzStorageBlobContent -Context $MySAContext -Container $SAContainerName -Blob "MyTestRunbookScript01.ps1" -Destination "C:\users\ling\Downloads" -Verbose

Get-AzStorageBlobContent -Context $MySAContext -Container $SAContainerName -Blob "MyTestRunbookScript01Copy.ps1" -Destination "C:\users\ling\Downloads" -Verbose

# Remove the blobs in a container
Get-AzStorageBlob -Container $SAContainerName -Context $MySAContext -Blob MyTestRun* | Remove-AzStorageBlob -Force

Step 14: Deploy and configure an Azure VMSS

First, create a new Azure Network Security Group ang associate it with the VMSS.

# Create a NSG for VMSS so that the instances can be connected through RDP

$MGMTRuleWinVM = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP-From-IPRange" `
    -Access Allow `
    -Protocol Tcp `
    -Direction Inbound `
    -Priority 110 `
    -SourceAddressPrefix "99.245.13.136,72.28.70.238" `
    -SourcePortRange * `
    -DestinationAddressPrefix VirtualNetwork `
    -DestinationPortRange 3389, 5985

# Create an NSG

$NSGName = "MyTest-CUS-NIC-NSG01"

if (!(Get-AzNetworkSecurityGroup -ResourceGroupName $RGName -Name $NSGName -ErrorAction SilentlyContinue)) {
    $MyTestNICNSG = New-AzNetworkSecurityGroup -ResourceGroupName $RGName -Name $NSGName -Location $Location -SecurityRules $MGMTRuleWinVM
}

Second, retrieve a list of all the available VM images in Azure then select one suitable for creating VMSS instances

$PublisherName = "MicrosoftWindowsServer"
Get-AzVMImageOffer -Location $Location -PublisherName $PublisherName | Select-Object Offer
$OfferName = "WindowsServer"
Get-AzVMImageSku -Location $Location -PublisherName $PublisherName -Offer OfferName | Select-Object Skus
$SKUName = "2019-Datacenter"
$VMImages = Get-AzVMImage -Location $Location -PublisherName $PublisherName -Offer OfferName -Skus $SKUName
$VMImages | Select-Object * | Format-List

Then deploy an Azure Virtual Machine Scale set as showed below:


#First, set an administrator username and password for the VM instances
$VMSSInstanceCred = Get-Credential

$VMSSName = "MyTest-CUS-VMSS01"
$PubIPAddressName = "MyTest-CUS-PubIP01"
# load balancer is not required if the vmss is only intended for running 
# instances as automation hybrid workers
$LBName = "MyTest-CUS-LB01"  
$ImageName = "MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest"
$InstanceCount = 1
$VMSize = "Standard_DS1_v2"

# Remove the load balance if it already exists otherwise the creating 
# VMSS statement fails
if($nll -ne ($LB = Get-AzLoaDPAlancer -ResourceGroupName $RGName -Name $LBName -ErrorAction SilentlyContinue)){
    $LB | Remove-AzLoaDPAlancer -Force
}

if (!(Get-AzVmss -ResourceGroupName $RGName -VMScaleSetName $VMSSName -ErrorAction SilentlyContinue)) {
    $MyTestVMSS = New-AzVmss -ResourceGroupName $RGName `
        -VMScaleSetName $VMSSName `
        -Location $Location `
        -VirtualNetworkName $VNetName `
        -SubnetName $SubnetName `
        -PublicIpAddressName $PubIPAddressName `
        -LoaDPAlancerName $LBName `
        -InstanceCount $InstanceCount `
        -ImageName $ImageName `
        -VmSize $VMSize `
        -SecurityGroupName $NSGName `
        -Credential $VMSSInstanceCred
}






Recent Posts

See All

Comments


bottom of page