Creating a new VM and VHD with HyperV

I have this script that creates a new VM, creates a VHD, points to an ISO and starts installing. This script works perfectly:

New-VM -Name “Server2012” -MemoryStartupBytes 512MB -path C:\HyperV
New-VHD -path C:\HyperVStorage\Server2012\Server2012dynamic.vhdx -SizeBytes 60GB -Dynamic
Add-VMHarddiskDrive -VMName Server2012 -path C:\HyperVStorage\Server2012\Server2012dynamic.vhdx
Set-VMdvddrive -VMname Server2012 -ControllerNumber 1 -path C:\users\dbrooks\desktop\en_windows_server_2012_x64_dvd_915478.iso
Add-VMNetworkAdapter -VMName Server2012 -SwitchName vSwitch1
Start-VM Server2012


I would like to be able to input the VM name, memory size, the harddrive size. I’m running into an error when trying to give it a specified amount of RAM and HDD. Any suggestions?

function New-Server2012r2VM
{
Param(
[int]$RAM,
[string]$Name,
[int]$HDD
)
$Name = Read-Host ‘Name your VM:’
$RAM = Read-Host ‘How much RAM?’
$HDD = Read-Host ‘How much storage?’
New-VM -Name $Name -MemoryStartupBytes ($RAM * 1gb) -path C:\HyperV$Name
New-VHD -path C:\HyperVStorage$Name.vhdx -SizeBytes ($HDD * 1gb) -Dynamic
Add-VMHarddiskDrive -VMName $Name -path C:\HyperVStorage$Name$Name.vhdx
Set-VMdvddrive -VMname $Name -ControllerNumber 1 -path C:\users\dbrooks\desktop\en_windows_server_2012_x64_dvd_915478.iso
Add-VMNetworkAdapter -VMName $Name -SwitchName vSwitch1
Start-VM $Name

Hi Daniel,

Not so certain I understand why you are reading values in your function via Read-Host when you are already passing these in as parameters to the function? It defeats the purpose.

Also, can you post the actual error message?

Good point, thanks. Got it working, thanks!

[string]$Name = Read-Host ‘Name your VM’
[int64]$RAM = Read-Host ‘How much RAM?’
[int64]$HDD = Read-Host ‘How much storage?’
New-VM -Name $Name -MemoryStartupBytes ($RAM * 1mb) -path C:\HyperV$Name
New-VHD -path C:\HyperVStorage$Name.vhdx -SizeBytes ($HDD * 1gb) -Dynamic
Add-VMHarddiskDrive -VMName $Name -path C:\HyperVStorage$Name.vhdx
Set-VMdvddrive -VMname $Name -ControllerNumber 1 -path C:\users\dbrooks\desktop\en_windows_server_2012_x64_dvd_915478.iso
Add-VMNetworkAdapter -VMName $Name -SwitchName vSwitch

No, you want to parametrize your function so you don’t have to prompt the user inside the function, using Read-Host. Instead, the information is passed in at the same time the function is called. In my example, the function is created, and then called including the required parameters (notice we made those mandatory).

Function New-Server2012r2VM {
    Param(
        [Parameter(Mandatory=$true)]
        [int]$RAM,

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

        [Parameter(Mandatory=$true)]
        [int]$HDD
    )
    
    Begin {
    } #End Begin

    Process {
        New-VM -Name $Name -MemoryStartupBytes ($RAM * 1gb) -path C:\HyperV\$Name
        New-VHD -path C:\HyperVStorage\$Name.vhdx -SizeBytes ($HDD * 1gb) -Dynamic
        Add-VMHarddiskDrive -VMName $Name -path C:\HyperVStorage\$Name\$Name.vhdx
        Set-VMdvddrive -VMname $Name -ControllerNumber 1 -path C:\users\dbrooks\desktop\en_windows_server_2012_x64_dvd_915478.iso
        Add-VMNetworkAdapter -VMName $Name -SwitchName vSwitch1
        Start-VM $Name
    } # End Process
} #End Function

New-Server2012r2VM -RAM 2 -Name DC01 -HDD 80