Automating the creation of virtual machines in Hyper-V

At some point in building our infrastructure, you need to automate the delivery of environments to complete new projects. It is good to create standards for creating virtual machines and prepare templates for creating virtual machines.

In this post, I will present a script that will allow you to quickly create a virtual machine based on a previously created machine by connecting its virtual disk.

Before running the script, I created a VM with Ubuntu Server 20.10 which I preconfigured:

  • created user with access to sudo command
  • installed hyperv-daemons package which can give as information about virtual machine IP address, needed to establish SSH session
[string] $VMName = Read-Host  "Enter VM name: "
[int32] $VMGeneration = Read-Host "VM generation: (enter 1 or 2)"
[int64] $VMMemory = Read-Host "Memory: (ex. 1024) "
$VMMemory = 1MB * $VMMemory
[int32] $VMCpu = Read-Host "Processor number: "
[string] $VMPath = Read-Host "VM Directory: (D:\Hyper-V)"

# Create new Hyper-V VM
New-VM -Name $VMName -Generation $VMGeneration -MemoryStartupBytes $VMMemory -Path $VMPath 
#Start-Sleep 5

# Connect virtual network card to virtual switch
$VMSwitch = Get-VMSwitch | Select-Object Name
Connect-VMNetworkAdapter -SwitchName $VMSwitch.Name -VMName $VMName

# Assign CPU cores to VM
Set-VMProcessor -VMName $VMName -count $VMCpu

# Create VM files directory 
$VMPath = $VMPath + [string]'\' + $VMName

# Create directory for VM hard disk
New-Item -Path $VMPath -Name 'Virtual Hard Disks' -ItemType "Directory"
$VMDiskPath = $VMPath  + [string]'\Virtual Hard Disks\'

# Copy disk VM template
Copy-Item 'D:\Export\ubuntu-server-20.10\Virtual Hard Disks\ubuntu-server-20.10.vhdx' -Destination $VMDiskPath
$VMDiskName = $VMName + [string]'.vhdx'

# Rename disk name
Rename-Item -NewName $VMDiskName -Path ($VMDiskPath + [string]'ubuntu-server-20.10.vhdx')

# Attach copied vhdx file to VM
Add-VMHardDiskDrive -VMName $VMName -Path ($VMDiskPath + $VMName + [string]'.vhdx') -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1

# Disable secure boot and set first boot device
Set-VMFirmware -VMName $VMName -EnableSecureBoot Off -FirstBootDevice $(Get-VMHardDiskDrive -VMName $VMName)

Start-VM $VMName

Example of running script DeployVM.ps1

PS C:\Script> .\DeployVM.ps1
 Enter VM name: : BNRS_test
 VM generation: (enter 1 or 2): 2
 Memory: (ex. 1024) : 2048
 Processor number: : 2
 VM Directory: (D:\Hyper-V): D:\Hyper-V
Newly created VM

Virtual machine was created and started up. Then we can run another script that will send a command to VM named BNRS_test and change its hostname for the same as created VM. Below script code RemoteCommand.ps1

$User = "bnrsadm"
$Password = "P@$$w0rd"

[string] $VMName = Read-Host  "Enter VM name: "

# Find VM IP Address
$VMIPAddresses =  Get-VMNetworkAdapter -VMName $VMName | Select-Object IPAddresses
$VMIPv4Address = $VMIPAddresses.IPAddresses[0]

# Credentials to connect SSH session
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)

# Create SSH session
New-SSHSession -ComputerName $VMIPv4Address -Credential $Credentials 

# Invoke command over SSH
$Command = 'sudo hostnamectl set-hostname ' + $VMName
Invoke-SSHCommand -ComputerName $VMIPv4Address -Command $Command 

# Disconnect SSH session
Remove-SshSession -ComputerName $VMIPv4Address

Example of running script RemoteCommand.ps1

PS C:\Script> .\RemoteCommand.ps1
 Enter VM name: : BNRS_test
 [192.168.2.111] 
 ComputerName  Result Error
 ------------  ------ -----
 192.168.2.111        False

Indeed script change hostname of BNRS_test. Below we can see that sign “_” have been missed but command changed hostname in virtual machine operating system.

Invoking the hostname command twice before and after the script RemoteCommand.ps1 is executed

The above method works, but in my opinion it should not be used as a target. Rather, it should be used as an initial system configuration that would prepare the machine for the use of configuration management software like e.g. Ansible.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments