How Do You Create a Linux Server in Azure with PowerShell When You Keep Getting an Error “Status Code: 400…Bad Request”?

Problem scenario
You are trying to create a Linux server in Azure with the Azure Tools for PowerShell.  You receive this message:

"Destination path for SSH public keys is currently limited to its default value due to a known issue in Linux provisioning agent."

You see  "StatusCode: 400 ... ReasonPhrase: Bad Request."

What do you do to create an Ubuntu 16.x server and not get this error?

Solution
Assuming you were using a .pub file with SSH when you received the error above, this solution below will work.  Create a VM without using a .pub file.  You have to enter the username and password interactively to get around the need for a .pub file being in a .ssh folder.

Here is a script that will create an Ubuntu 16.x Linux machine with 4 GB of RAM.  Just save the script then run it and answer the prompts.  You will need to manually enter your Azure credentials when prompted with a pop up after the script starts.

# Usage instructions
# Do five things before running this script:
# 1.  Change the password "ch@ngePassword" below
# 2.  Change the $resourceGroup name from "contIntGroup" to the one you want.  
# 3.  Change the location "eastus" unless that is what you want.
# 4.  Change the vmName variable from "contIntVM" to the name you want.
# 5.  Save the script locally.  It cannot run as an untitled draft.
# 6.  Optional: Change the IP addresses associated with the subnet mask and separately virtual network to something you want.
# 7.  Optional: You may want to change the names of the virtual network and subnet too.

# This script was modified from a copy taken
# from https://docs.microsoft.com/en-us/azure/virtual-machines/scripts/virtual-machines-windows-powershell-sample-create-vm

# This script creates a new resource group, a subnet mask and a NIC for the Linux server too.

write-host "*****************************"
write-host " "
write-host "ALERT: This script will require interaction.  It was designed that way."
write-host 'First you will be prompted to enter your Azure credentials to interactively login with a GUI.  This script therefore launches a web browser.'
write-host " "
write-host 'The subsequent GUI prompt will have the header "cmdlet Get-Credential at command pipeline..."'
write-host 'For this prompt, enter the credentials you want your Linux server to have.'
write-host "*****************************"
# Variables for common values
Login-AzureRmAccount
$resourceGroup = "contIntGroup"
$location = "eastus"
$vmName = "contIntVM"

# Definer user name and blank password
#$securePassword = ConvertTo-SecureString 'ch@ngePassword' -AsPlainText -Force
#$cred = New-Object System.Management.Automation.PSCredential ("contintuser", $securePassword)

$creda = Get-Credential

# Create a resource group
New-AzureRmResourceGroup -Name $resourceGroup -Location $location

# Create a subnet configuration
$subnetConfig = New-AzureRmVirtualNetworkSubnetConfig -Name contIntSubnet -AddressPrefix 192.168.1.0/24

# Create a virtual network
$vnet = New-AzureRmVirtualNetwork -ResourceGroupName $resourceGroup -Location $location `
  -Name ContIntNET -AddressPrefix 192.168.0.0/16 -Subnet $subnetConfig

# Create a public IP address and specify a DNS name
$pip = New-AzureRmPublicIpAddress -ResourceGroupName $resourceGroup -Location $location `
  -Name "mypublicdns$(Get-Random)" -AllocationMethod Static -IdleTimeoutInMinutes 4

# Create an inbound network security group rule for port 22
$nsgRuleSSH = New-AzureRmNetworkSecurityRuleConfig -Name ContIntNetworkSecurityGroupRuleSSH  -Protocol Tcp `
  -Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
  -DestinationPortRange 22 -Access Allow

# Create a network security group
$nsg = New-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroup -Location $location `
  -Name myNetworkSecurityGroup -SecurityRules $nsgRuleSSH

# Create a virtual network card and associate with public IP address and NSG
$nic = New-AzureRmNetworkInterface -Name contIntNic -ResourceGroupName $resourceGroup -Location $location `
  -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id

# Create a virtual machine configuration
$vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize Standard_D1 | `
Set-AzureRmVMOperatingSystem -Linux -ComputerName $vmName -Credential $creda | ` #-EnablePasswordAuthentication
Set-AzureRmVMSourceImage -PublisherName Canonical -Offer UbuntuServer -Skus 16.04-LTS -Version latest | `
Add-AzureRmVMNetworkInterface -Id $nic.Id

# Create a virtual machine
New-AzureRmVM -ResourceGroupName $resourceGroup -Location $location -VM $vmConfig

In the future we want to re-write these directions to use write-verbose instead of write-host. We want to warn people that write-verbose is recommended instead of write-host (according to this posting).

Leave a comment

Your email address will not be published. Required fields are marked *