---
title: Automating VM Deployment in Azure with PowerShell
description: Learn how to automate the deployment of a Windows VM on Azure using PowerShell. This guide covers network setup, NSG rules, and IIS installation.
canonical: https://adamtheautomator.com/automating-azure-vm/
---

# Automating VM Deployment in Azure with PowerShell

> Learn how to automate the deployment of a Windows VM on Azure using PowerShell. This guide covers network setup, NSG rules, and IIS installation.

Source: https://adamtheautomator.com/automating-azure-vm/

---

- Automating VM Deployment in Azure with PowerShell Tap to hide Home

- Tutorials

- Guidebooks

- Instructors

- Get Paid to Write

- Advertising

- Recommended Resources

- About Adam

                Search for:

-

-

-

-

# Automating VM Deployment in Azure with PowerShell

        Published:18 October 2024 - 4 min. read

- Azure
- Azure PowerShell
- PowerShell

          [](https://adamtheautomator.com/author/adam-bertram/)

            [Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)

            Read [more tutorials](https://adamtheautomator.com/author/adam-bertram/) by Adam Bertram!

-

-

        [](https://specopssoft.com/product/specops-password-auditor/?utm_source=adamtheautomator&utm_medium=referral&utm_campaign=adamtheautomator_referral_na&utm_content=display)
        Audit Active Directory for stale users, weak passwords, and other security risks with [Specops Password Auditor](https://specopssoft.com/product/specops-password-auditor/?utm_source=adamtheautomator&utm_medium=referral&utm_campaign=adamtheautomator_referral_na&utm_content=text).

                XFacebookLinkedIn

Automating tasks in Azure can save significant time and effort, especially when deploying resources like virtual machines (VMs). In this blog post, we’ll walk through automating the deployment of a Windows VM in Azure using PowerShell. We'll configure networking, security, and install IIS for a web server all in one script.

#### Why Automate VM Deployment?

Automating tasks such as virtual machine deployment ensures consistency, reduces errors, and accelerates the setup process. With PowerShell, you can define all the necessary parameters and let the script handle the deployment, instead of manually creating each resource via the Azure Portal.

Here’s a step-by-step breakdown of the PowerShell script used to deploy an Azure VM, configure networking, set security rules, and install IIS.

Here's the script if you just want to download it.

[CmdletBinding()]
param(
    [Parameter(Mandatory)]
    [string]$ResourceGroupName = 'Admissions',

    [Parameter(Mandatory)]
    [string]$Location = 'East US',

    [Parameter(Mandatory)]
    [string]$VMName = 'ADMISSIONSWEB',

    [Parameter(Mandatory)]
    [string]$VMSize = 'Standard_DS3_v2',

    [Parameter(Mandatory)]
    [string]$PublicIPName = 'Admissions-PubIp',

    [Parameter(Mandatory)]
    [string]$NICName = 'Admissions-vNIC',

    [Parameter(Mandatory)]
    [string]$OSDiskName = 'Admissions-OSDisk',

    [Parameter(Mandatory)]
    [string]$NSGName = 'ADMISSIONSWEB-NSG',

    [Parameter(Mandatory)]
    [string]$AdminUsername = 'adam',

    [Parameter(Mandatory)]
    [SecureString]$AdminPassword = (ConvertTo-SecureString 'P@$$w0rd12' -AsPlainText -Force)
)

$ErrorActionPreference = 'Stop'

function CreateAzResource {
    param(
        [Parameter(Mandatory)]
        [string]$ResourceType,

        [Parameter(Mandatory)]
        [string]$Name,

        [Parameter(Mandatory)]
        [hashtable]$NewParameter
    )

    try {
        $resource = & "Get-Az$ResourceType" -Name $Name -ResourceGroupName $NewParameter.ResourceGroupName
    } catch {
        if ($_.Exception.Message -match "under resource group '.*' was not found") {
            $resource = & "New-Az$ResourceType" @NewParameter
        } else {
            throw $_
        }
    } finally {
        $resource
    }
}

#region VM Configuration
$vmconfig = New-AzVMConfig -VMName $VMName -VMSize $VMSize
#endregion

#region Public IP Creation
$newPublicIpParams = @{
    Name              = $PublicIPName
    ResourceGroupName = $ResourceGroupName
    AllocationMethod  = 'Static'
    Location          = $Location
}
$publicIp = CreateAzResource -ResourceType PublicIpAddress -Name $PublicIPName -NewParameter $newPublicIpParams
#endregion

#region Network Interface Configuration
$vNet = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName
$subnetId = $vNet.Subnets[0].Id

$newVNicParams = @{
    Name              = $NICName
    ResourceGroupName = $ResourceGroupName
    Location          = $Location
    SubnetId          = $subnetId
    PublicIpAddressId = $publicIp.Id
}
$vNic = CreateAzResource -ResourceType NetworkInterface -Name $NICName -NewParameter $newVNicParams
#endregion

#region OS Configuration
$cred = New-Object System.Management.Automation.PSCredential ($AdminUsername, $AdminPassword)
$newVmOsParams = @{
    Windows          = $true
    ComputerName     = $VMName
    Credential       = $cred
    EnableAutoUpdate = $true
    VM               = $vmconfig
}
$vm = Set-AzVMOperatingSystem @newVmOsParams
#endregion

#region Image Configuration
$newSourceImageParams = @{
    PublisherName = 'MicrosoftWindowsServer'
    Offer         = 'WindowsServer'
    Skus          = '2019-Datacenter'
    Version       = 'latest'
    VM            = $vm
}
$vm = Set-AzVMSourceImage @newSourceImageParams
#endregion

#region Disk Configuration
$vm = Set-AzVMOSDisk -VM $vm -Name $OSDiskName -CreateOption FromImage
#endregion

#region Network Interface Attachment
$vm = Add-AzVMNetworkInterface -VM $vm -Id $vNic.Id
#endregion

#region NSG Configuration
$newNsgParams = @{
    ResourceGroupName = $ResourceGroupName
    Location          = $Location
    Name              = $NSGName
}
$nsg = CreateAzResource -ResourceType NetworkSecurityGroup -Name $NSGName -NewParameter $newNsgParams

$ruleExists = $nsg.SecurityRules.Name -contains "Allow-RDP"
if (-not $ruleExists) {
    $ip = Invoke-RestMethod -Uri "https://api.ipify.org"
    $rdpRule = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP" -Description "Allow RDP" -Access Allow -Protocol Tcp -Direction Inbound -Priority 1000 -SourceAddressPrefix $ip -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 3389
    $nsg.SecurityRules.Add($rdpRule)
    $nsg | Set-AzNetworkSecurityGroup
}
#endregion

#region Web Traffic Rule Configuration
$webRuleExists = $nsg.SecurityRules.Name -contains "Allow-Web"
if (-not $webRuleExists) {
    $webRule = New-AzNetworkSecurityRuleConfig -Name "Allow-Web" -Description "Allow HTTP" -Access Allow -Protocol Tcp -Direction Inbound -Priority 200 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 80
    $nsg.SecurityRules.Add($webRule)
    $nsg | Set-AzNetworkSecurityGroup
}
#endregion

$vNic.NetworkSecurityGroup = $nsg
$vNic | Set-AzNetworkInterface

#region VM Creation
$newVmParams = @{
    ResourceGroupName = $ResourceGroupName
    VM                = $vm
    Location          = $Location
}
CreateAzResource -ResourceType VM -Name $VMName -NewParameter $newVmParams
#endregion

#region IIS Installation
$installIIS = {
    Install-WindowsFeature -Name Web-Server -IncludeManagementTools
}
$installScript = [scriptblock]::create($installIIS)
Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VMName -CommandId 'RunPowerShellScript' -ScriptString $installScript
#endregion

#region Output Public IP
$publicIp.IpAddress

Define Parameters

The script starts by defining parameters that will be used throughout the deployment. These include basic information such as resource group, VM name, location, and admin credentials. Using parameters ensures the script is flexible and can be reused for different environments.

param(
    [Parameter(Mandatory)]
    [string]$ResourceGroupName = 'Admissions',
    [Parameter(Mandatory)]
    [string]$Location = 'East US',
    [Parameter(Mandatory)]
    [string]$VMName = 'ADMISSIONSWEB',
    [Parameter(Mandatory)]
    [string]$VMSize = 'Standard_DS3_v2',
    [Parameter(Mandatory)]
    [string]$PublicIPName = 'Admissions-PubIp',
    [Parameter(Mandatory)]
    [string]$NICName = 'Admissions-vNIC',
    [Parameter(Mandatory)]
    [string]$OSDiskName = 'Admissions-OSDisk',
    [Parameter(Mandatory)]
    [string]$NSGName = 'ADMISSIONSWEB-NSG',
    [Parameter(Mandatory)]
    [string]$AdminUsername = 'adam',
    [Parameter(Mandatory)]
    [SecureString]$AdminPassword = (ConvertTo-SecureString 'P@$$w0rd12' -AsPlainText -Force)
)

Creating Azure Resources

The `CreateAzResource` function helps create various Azure resources like public IPs, network interfaces, and network security groups (NSGs). It attempts to get a resource and creates it if it doesn't exist, making the process more efficient.

function CreateAzResource {
    param(
        [Parameter(Mandatory)]
        [string]$ResourceType,
        [Parameter(Mandatory)]
        [string]$Name,
        [Parameter(Mandatory)]
        [hashtable]$NewParameter
    )

    try {
        $resource = & "Get-Az$ResourceType" -Name $Name -ResourceGroupName $NewParameter.ResourceGroupName
    } catch {
        if ($_.Exception.Message -match "not found") {
            $resource = & "New-Az$ResourceType" @NewParameter
        } else {
            throw $_
        }
    } finally {
        $resource
    }
}

VM Configuration and Networking Setup

Once resources like public IP and virtual networks are created, the script configures a virtual machine (VM) using `New-AzVMConfig`, attaches a network interface, and sets up the operating system and disk.

$vmconfig = New-AzVMConfig -VMName $VMName -VMSize $VMSize

$vNic = CreateAzResource -ResourceType NetworkInterface -Name $NICName -NewParameter $newVNicParams
$vm = Set-AzVMOperatingSystem @newVmOsParams
$vm = Set-AzVMSourceImage @newSourceImageParams
$vm = Set-AzVMOSDisk -VM $vm -Name $OSDiskName -CreateOption FromImage

Configuring Network Security Rules

The script adds security rules to the NSG to allow inbound RDP (Remote Desktop) and web traffic on port 80 (HTTP). This is critical for managing the VM and hosting web applications.

$ruleExists = $nsg.SecurityRules.Name -contains "Allow-RDP"
if (-not $ruleExists) {
    $ip = Invoke-RestMethod -Uri "https://api.ipify.org"
    $rdpRule = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP" -Access Allow -Protocol Tcp -SourceAddressPrefix $ip -DestinationPortRange 3389
    $nsg.SecurityRules.Add($rdpRule)
    $nsg | Set-AzNetworkSecurityGroup
}

Installing IIS

After the VM is created, the script installs IIS (Internet Information Services), which will allow the VM to act as a web server. This is done by executing a PowerShell command on the VM.

$installIIS = {
    Install-WindowsFeature -Name Web-Server -IncludeManagementTools
}
Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VMName -CommandId 'RunPowerShellScript' -ScriptString $installIIS

Output the Public IP

Finally, the public IP of the VM is outputted for easy access to the web server.

$publicIp.IpAddress

#### Conclusion

With this PowerShell script, deploying a Windows VM on Azure with configured networking, security, and IIS setup becomes seamless. This level of automation is invaluable for repetitive tasks and ensures that your infrastructure is set up consistently.

By following this guide, you can deploy VMs quickly and focus more on configuring applications rather than spending time manually setting up resources.

  Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

  [Explore ATA Guidebooks](https://adamtheautomator.com/ata-guidebooks/)

## More from ATA Learning and Partners

- ### Recommended Resources! Recommended Resources for Training, Information Security, Automation, and more!

- ### Get Paid to Write! ATA Learning is always seeking instructors of all experience levels. Regardless if you’re a junior admin or system architect, you have something to share. Why not write on a platform with an existing audience and share your knowledge with the world?

- ### ATA Learning Guidebooks ATA Learning is known for its high-quality written tutorials in the form of blog posts. Support ATA Learning with ATA Guidebook PDF eBooks available offline and with no ads!

## Categories

- IT Ops

- Cloud

- DevOps

- Home Ops

- Information Security

- Software Development

## Site

- Home

- Tutorials

- Guidebooks

- Instructors

- Get Paid to Write

- Advertising

- Recommended Resources

- About Adam

        Copyright 2026&copy; ATA Learning | [Privacy Policy](https://adamtheautomator.com/privacy/)

                                                        Don't be left behind with the ATA Learning Newsletter!

Looks like you're offline!
