Mass create VMs with script

This topic contains 4 replies, has 3 voices, and was last updated by  Istvan Szarka 3 years, 6 months ago.

  • Author
    Posts
  • #15041

    Istvan Szarka
    Participant

    Hello,

    I managed to write a script that creates a VM with all the memory, VHD, DVD drive and other settings.
    This arrangement works awesome if I create VMs one at a time, but how can I create several VMs with this one script?

    [CmdletBinding()]
    param(
    [Parameter(Mandatory=$true)]
    [string]$VMName,
    [Parameter(Mandatory=$true)]
    [string]$SwitchName,
    [Parameter(Mandatory=$true)]
    [string]$ISOPath
    )

    New-VM -Name $VMName -MemoryStartupBytes 512MB -Generation 2 -Path C:\VM -SwitchName $SwitchName
    New-VHD -Path C:\VHD\$VMName.vhdx -SizeBytes 40GB -Dynamic
    Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $true -MinimumBytes 512MB
    Add-VMHardDiskDrive -VMName $VMName -Path C:\VHD\$VMName.vhdx
    Add-VMDvdDrive -VMName $VMName -Path $ISOPath

    If I set the $VMName parameter to accept several values like [string[]]$VMName, I get the error "... Cannot convert 'System.String[]' to the type 'System.String' required by parameter 'Name'...".

    The idea is that I'd like to create several VMs by only feeding in a list of VM names, setting the same ISO path and virtual switch for all of them with one script.

  • #15047

    Dave Wyatt
    Moderator

    You can change your code like this, to accept multiple VM names (though they'll still be created one at a time, at least you only have to call your function once to do the whole batch):

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline = $true)]
        [string[]]
        $VMName,
    
        [Parameter(Mandatory=$true)]
        [string]
        $SwitchName,
    
        [Parameter(Mandatory=$true)]
        [string]
        $ISOPath
    )
    
    process
    {
        foreach ($name in $VMName)
        {
            New-VM -Name $name -MemoryStartupBytes 512MB -Generation 2 -Path C:\VM -SwitchName $SwitchName
            New-VHD -Path C:\VHD\$name.vhdx -SizeBytes 40GB -Dynamic
            Set-VMMemory -VMName $name -DynamicMemoryEnabled $true -MinimumBytes 512MB
            Add-VMHardDiskDrive -VMName $name -Path C:\VHD\$name.vhdx
            Add-VMDvdDrive -VMName $name -Path $ISOPath
        }
    }
    
  • #15048

    Istvan Szarka
    Participant

    Thank you very much Mr Wyatt, you helped me learn a lot! Exactly this is what I was trying to figure out!

  • #15050

    Dave Wyatt
    Moderator

    No problem, happy to help! 🙂

  • #15186

    Istvan Szarka
    Participant

    Foreach is AMAZING! It seems you can do just anything with it! I managed to automate changing the default boot order and included it in the script!
    Now it not only creates multiple VMs with all the desired settings, but also sets the boot order to boot from the ISO image right away!
    I'm so happy I can't tell you!
    I post it here, maybe it'll benefit other PowerShell learners too:

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline = $true)]
        [string[]]
        $VMName,
    
        [Parameter(Mandatory=$true)]
        [string]
        $SwitchName,
    
        [Parameter(Mandatory=$true)]
        [string]
        $ISOPath
    )
    
    process
    {
        foreach ($name in $VMName)
        {
            New-VM -Name $name -MemoryStartupBytes 512MB -Generation 2 -Path C:\Lab\VM -SwitchName $SwitchName
            New-VHD -Path C:\Lab\VHD\$name.vhdx -SizeBytes 40GB -Dynamic
            Set-VMMemory -VMName $name -DynamicMemoryEnabled $true -MinimumBytes 512MB
            Add-VMHardDiskDrive -VMName $name -Path C:\Lab\VHD\$name.vhdx
            Add-VMDvdDrive -VMName $name -Path $ISOPath
    
            $firmware = Get-VMFirmware -VMName $name
            $network = $firmware.bootorder[0]
            $vhd = $firmware.bootorder[1]
            $dvd = $firmware.bootorder[2]
    
            Set-VMFirmware -VMName $name -BootOrder $dvd,$network,$vhd
        }
    }
    

    Thanks a lot again!!!

You must be logged in to reply to this topic.