Auto Deploy Multiple vmware Virtual Machines

Haven’t posted for a while… here goes.

Here is my PowerShell script to deploy multiple vmware virtual machines using a template and a custom specification file. You can use this script to create an unlimited number of VM’s, all with unique computer names and static IP addresses.

The following attributes need to be configured for your individual environment.

$server_address = Change this to your vCenter Server address
$username = Change this to the user with permission to create new VM’s using the desired template
$password = The user’s password
$destination_host = Change this to any host in your vmware cluster
$template_name = Change this to the required template
$customization = Change this to the required customization file
$location = Use this to deploy the VM to a specific folder
-SubnetMask = Change this to the netmask for you new servers
-DefaultGateway = Change this to the default gateway for your VM’s
-Dns = Add your DNS servers in order separated with a comma (,)

$array = This is the list of the servers you wish to create. The values here are the NETBIOS names for the servers, so chose them wisely. Remember to wrap each server name in quotation marks (“) and separate each server with a comma (,)
$iparray = This is the list of IP’s you want to allocate the VM’s. Each IP is assigned to a machine in the $array

Save the following to a text file and rename it to .PS1

# Virtual Center Details
$server_address = "vCenterServer"
$username = "Administrator"
$password = "password"
# Vm Details
$destination_host = "AnyVMHost.network.LOCAL"
$template_name = "Template1"
$datastore_name = "DataStore1"
$customization = "Customization1"
$location = "vCenter folder location"
# Name the VMs in this array
$array = "Server1", "Server1"
$iparray = "10.1.1.10", "10.1.1.11"
$a= 0

Connect-VIServer -Server $server_address -Protocol https
-User $username -Password $password
foreach ($vm in $array)
{
Get-OSCustomizationSpec $customization | Get-OSCustomizationNicMapping |
Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $IParray[$a]
-SubnetMask 255.255.255.0 -DefaultGateway 10.1.1.1 -Dns 10.1.1.2,10.1.1.3
$vm=New-VM -Name $vm -Location $location -Template $template_name
-Host $destination_host -Datastore $datastore_name -OSCustomizationSpec
$customization -Confirm:$false $a = $a + 1
}

Or just download the file from http://mattlog.net/wp-content/uploads/2010/07/AutoDeployVMwareVirtualMachineTemplate.txt (NOTE: you need to rename the file to .PS1)

You need to download the vmware vSphere PowerCLI application and install it on the machine you would like to build the VM’s from. You can download the PowerCLI extension from www.vmware.com/go/powercli (you need a free vmware accou nt to download)

Run the PS1 file created earlier from the PowerCLI command line and the script will cycle through your array and create the virtual machines.

Enjoy.

Posted by Matt Shadbolt
http://mattlog.net
Please comment or click an ad to support this site
42 Responses
Filed under:Uncategorized

42 Responses to “Auto Deploy Multiple vmware Virtual Machines”

  • Scott Says:

    Hi

    When I run the script I get the following error.

    New-VM : 06/02/2011 15:09:36 New-VM The operation for the entity VirtualMachine-vm-357358 failed with t
    he following message: “A specified parameter was not correct.
    hostname”
    At C:\Users\sboyd008\Downloads\vmware\scripts\AutoDeployVMwareVirtualMachineTemplate.PS1:22 char:17
    + $vm=new-vm <<<< -Name $vm -Location $location -Template $template_name -Host $destination_host -Datastor
    e $datastore_name -OSCustomizationSpec $customization -Confirm:$false
    + CategoryInfo : NotSpecified: (:) [New-VM], InvalidArgument
    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.VimAuto
    mation.ViCore.Cmdlets.Commands.NewVM

  • Matt Shadbolt Says:

    Hi Scott.
    Can you post your script? The ‘pararmeter was not correct’ suggests you’ve misspelt something. If you give me the script your running I’ll check it for you.
    Matt

  • Scott Boyde Says:

    I downloaded the script from here. But this is what I have

    # Virtual Center Details
    $server_address = “vcenter.XXX.net”
    $username = “”
    $password = “”

    # Vm Details
    $destination_host = “bchh1u28esx2.vm.XXX.net”
    $template_name = “base-w2k8-dc-64″
    $datastore_name = “BCH_8_sat_app2″
    $customization = “Windows 2008″
    $location = “Technical-Support”

    # Name the VMs in this array
    $array = “Server1″, “Server1″
    $iparray = “10.210.64.210″, “10.210.64.210″
    $a= 0
    Connect-VIServer -Server $server_address -Protocol https -User $username -Password $password
    foreach ($vm in $array)
    {
    Get-OSCustomizationSpec $customization | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $IParray[$a] -SubnetMask 255.255.255.0 -DefaultGateway 10.1.1.1 -Dns 10.1.1.2,10.1.1.3
    $vm=New-VM -Name $vm -Location $location -Template $template_name -Host $destination_host -Datastore $datastore_name -OSCustomizationSpec $customization -Confirm:$false
    $a = $a + 1
    }

  • Matt Shadbolt Says:

    Hi Scott,
    Quick one – make sure you sanitize your info before posting online. You had your domain name plain to see :(

    So the problem you’re having is with the arrays.

    $array = “Server1″, “Server1″
    $iparray = “10.210.64.210″, “10.210.64.210″

    You shouldn’t have the same hostname and IP for each machine. It will cause problems. Make it Server2 & .211 and it should work.

    Matt Shadbolt

  • Scott Boyde Says:

    Matt

    Realised that as soon as I hit submit.

    I actually have the hostname and IP changed but it gives the same error.

  • Matt Shadbolt Says:

    OK, well can you please paste in the EXACT script that you are using??

    You’re getting a hostname error and the hostname is set by the $array variable

  • Scott Says:

    Matt, its the exact script with different servers and ips

    # Virtual Center Details
    $server_address = “vcenter”
    $username = “”
    $password = “”

    # Vm Details
    $destination_host = “bchh1u28”
    $template_name = “base-w2k8-dc-64″
    $datastore_name = “BCH_8_sat_app2″
    $customization = “Windows 2008″
    $location = “Technical-Support”

    # Name the VMs in this array
    $array = “Server1″, “Server2″
    $iparray = “I92.168.1.1″, “192.168.1.2″
    $a= 0
    Connect-VIServer -Server $server_address -Protocol https -User $username -Password $password
    foreach ($vm in $array)
    {
    Get-OSCustomizationSpec $customization | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $IParray[$a] -SubnetMask 255.255.255.0 -DefaultGateway 10.1.1.1 -Dns 10.1.1.2,10.1.1.3
    $vm=New-VM -Name $vm -Location $location -Template $template_name -Host $destination_host -Datastore $datastore_name -OSCustomizationSpec $customization -Confirm:$false
    $a = $a + 1
    }

  • Scott Says:

    Looking at the script before I pasted it and I thought it might be the quotes but they are fine in the script window.

  • Steve A Says:

    It may not be the script itself,
    in the customization specification , do you name the VM via the deploy wizard ?
    I had this settings and found the same error. Parameter incorrect.Hostname”

    It was easy to fix, go to your customization specification and in the computer name section, choose ‘Use virtual machine name’ and save
    re-run the script and it should run flawlessly

  • Matt Shadbolt Says:

    Thanks Steve.
    I did speak with Scott via email and we did work out that it was in fact his customization file that was set to request for a hostname.
    Obviously that will cause the script to fail! For the record, your customization file needs to be ‘use virtual machine name’ as the hostname.
    Matt

  • Lars Skjønberg Says:

    Hi, looks like a useful script, but i need to deploy about 30 machines from one image and later on several hundred.

    Then it would be useful to be able to reference to a file containing the ip adresses and machine names.

    Also it’s important to me that the servername and ip address is matched. Like Machine1 = 10.0.0.1 and Machine2 = 10.0.0.2. Will this script acomplish that ?

  • Matt Shadbolt Says:

    Hi Lars,
    As this is PowerShell you can use any function that you would normally use to reference a text or csv file containing the IP’s and server names (Import-CSV or the like).
    It’s also important for me to put the correct addresses on the correct machine. As this script uses two arrays ($array and $iparray), as long as you have your server name and IP addresses in the correct order they will be applied to the correct machines. To answer your question specifically – yes, Machine1 will equal 10.0.0.1 and Machine2 will equal 10.0.0.2 if you set the arrays as follows:
    $array = “Machine1″, “Machine2″
    $iparray = “10.0.0.1″, “10.0.0.2″

    Matt

  • Lars Skjønberg Says:

    Thnx, have deployed 30 machines using your script now and it works great.

    Good work :-)

  • VM-mark Says:

    Hi,

    Could any one please paste the $customization file here? I have figured out everything except what should be the content in this file and where it should be placed.

    Thank you very much!

  • VM-mark Says:

    Also I am running this script from my local machine, and it’s giving multiple errors stating Could not find any of the objects mentioned.

  • Matt Shadbolt Says:

    Hi VM-mark,
    Have you installed the VMware PowerCLI PowerShell extensions on your local machine?
    Matt

  • VM-mark Says:

    Hi Matt,

    Thanks for the reply. So here is my whole scenario:

    I have 2 VMs on one of my server x.x.x.x.
    1. Autodeploy-1 – The VM on which I am running your script through vSphere PowerCLI
    2. AutoDeployVM – Template I am using for creating other VMs.

    I want create more VMs on the same server with different unique IP address and NetBIOS computer name. Following is the script I am using to create VMs:

    # Virtual Center Details
    $server_address = “x.x.x.x”
    $username = “xxx”
    $password = “xxxxxx”

    # Vm Details
    $destination_host = “x.x.x.x”
    $template_name = “AutodeployVM”
    $datastore_name = “dataStore1 (9)”

    # Name the VMs in this array
    $array = “VPS-Test1″,”VPS-Test2″
    $iparray = “x.x.x.1″, “x.x.x.2″
    $a= 0

    Connect-VIServer -Server $server_address -Protocol https -User $username -Password $password

    foreach ($vm in $array)
    {
    Get-OSCustomizationNicMapping | Set- OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $IParray[$a] -SubnetMask z.z.0.0 -DefaultGateway y.y.y.y -Dns x.x.x.35,x.x.x.36

    $vm=New-VM -Name $vm -Template $template_name -Host $destination_host -Datastore $datastore_name -Confirm:$false $a = $a + 1

    }

    I am getting following errors:
    The term ‘Set-’ is not recognized as the name of a cmdlet
    New-VM : A positional parameter cannot be found that accepts argument ’0′.

    I am sure I am missing couple of things here as I am very new to this. Please advise. Thank you so much for your help.

  • VM-mark Says:

    Also, do I need to install VMware PowerCLI PowerShell extensions on that VM ( Autodeploy-1) on which I am running the script? If yes, which extension do I need to install?

  • Matt Shadbolt Says:

    Hi Vm-mark,
    As I said in the post – you must have the PowerCLI extensions installed on the machine you are running the script from. Commands such as Set-OSCustomizationNicMapping are NOT native PowerShell commands and will only run if you have PowerCLI installed. You don’t need PowerCLI installed anywhere else (ie, the target guest, etc) – just the machine you’re running the script from.
    Matt

  • VM-mark Says:

    Hi Matt,

    Thanks for the reply. I have the VMware vSphere PowerCLI already installed on the machine. And through PowerCLI command prompt I am trying to execute the script. I’m still getting those errors. Is there anything else I need to install?

  • VM-mark Says:

    Hi Matt,

    We updated the the script and still it gives the following error:

    Get-OSCustomizationNicMapping : 3/16/2011 3:58:42 PM Get-OSCustomizationNicMapping Value cannot be found for the mandatory parameter OSCustomization
    Spec

    New-VM : A parameter cannot be found that matches parameter name ’0′.

  • Yogini Says:

    How long did it take to create 30 VMs?

  • Yogini Says:

    I have deployed just 3 Vms but its taking really long time. Is there any quick way of deploying multiple VMs?

  • Matt Shadbolt Says:

    Depends where you have your template stored, Yogini. Make sure the template is stored on the same LUN as the machines your attempting to create and it should run quickly. If it runs across two storage systems or a LAN it will obviously be slow.

  • yogini Says:

    Template and the new VMs they are on same datastore. I was wondering if thats the reason its getting slowed as reading and writing to same disk. I am trying moving template to NTFS and then cretaing VMs to datastore.not sure how its going to take.

  • George Nedwick Says:

    so the script works great for me, made 30 VMs, but the problem is when you boot the vm, it sysprep’s them, reboots, and then all the custom settings from the SCRIPT are gone and it reasks for NAME, IP, etc. What am i doing wrong? I can’t REMOVE the SYSPREP from the CUSTOMIZATION file.

  • Matt Shadbolt Says:

    So it sounds like your vm template is the problem. When your creating your template are you manually adding a sysprep to the process? If you use the convert to template option in vCenter, you just need to turn a VM off and select convert to template. Don’t sysprep the machine before you turn it off.

  • George Nedwick Says:

    Matt, Thanks for your reply. No, i am not sysprep’ing the VM. It was a windows 7 ultimate VM, that had an IP, pc name, joined to a domain, etc. I shut it down, converted it to a template. Even if I do NOT use your script, and i manually right click and create a VM from template, whenever i use the CUSTOMIZATION file (wizard), this occurs. But in hte customization wizard, the LAST option is SYSPREP, which is checked. If you UNCHECK it, you receive an error when you try and create a VM from the template. Everywhere i read online, customization file sysprep’s a machine. The propblem is the customization info isnt going in AFTER the sysprep. Thoughts? I am able to reproduce this on various VCENTER setups. What am i missing?

  • Lars Says:

    To Yogini:

    With my setup it takes about 30 seconds to create a machine based on a Server 2003 template and with a 30 GB system disk. This is of course excluding the sysprep stuff after the machine is created … so say that takes about 2-3 minutes more and 3 to 3.5 minutes from nothing to finished.

  • Abby Says:

    Hi Matt

    Tried using your script got some errors and rectified them but finally this one last error am unable to resolve.
    ==============================================
    PS C:\> C:\template.ps1
    You must provide a value expression on the right-hand side of the ‘-’ operator.
    At C:\template.ps1:24 char:21
    + $customization – <<<< Confirm:$false $a = $a + 1
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedValueExpression
    ====================================================

    And this is the line number 24 of my file

    $customization -Confirm:$false $a = $a + 1

    Can you help please

    Thanks
    Abby

  • Spencer Says:

    Yo Matt,

    I am new to the shell thing but keep getting thius error with your script

    You must provide a value expression on the right-hand side of the ‘-’ operator.
    At C:\Documents and Settings\Spencer\My Documents\Template2.ps1:37 char:18
    + $customization – <<<< Confirm:$false
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedValueExpression

    HERE IS THE SCRIPT BELOW , ANY IDEAS ….APPRECIATED !

    … edited for brevity

  • Matt Shadbolt Says:

    Hi Spencer,

    Can you please make sure the -OSCustomizationSpec $customization doesn’t have a carrige return after it? If that doesn’t work please email me your full script in a text file and I’ll take a look.

    Matt

  • Jayaram Says:

    Hi Matt,
    I have a requirement to create a 1000 vm’s. Can anyone suggest the process to create quickly and also scripts to run.

  • Mike Says:

    Matt;

    Great script, saved me a bunch of time. I do have a question however. I declared my Destination Host, and the VM did in fact build there, but it would come to rest on a different host in the cluster when it was all said and done. Any idea why?

    Thanks

  • Matt Shadbolt Says:

    Hi Mike. Not 100% sure as I don’t really touch vmware stuff anymore, but could it be your systems load balancing?

    Not sure if you have that automated but it would make sense.

  • Jason Says:

    Love the script and works like magic; however is there a way to get the VM’s to turn on after they get created? Like the option that says power on this VM after it’s created. I thought I could add this to the script, but it does not work.

    $pwron = New-Object Vmware.Vim.VirtualMachineCloneSpec
    $pwron.powerOn = $true

    Any ideas would be greatly appreciated

  • Jason Harris Says:

    Matt answered my questions…add

    “start-vm -vm $vm -confirm:$false” to the end of the script right before the array counter. See below.

    Get-OSCustomizationSpec $customization | Get-OSCustomizationNicMapping |
    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $IParray[$a]
    -SubnetMask 255.255.255.0 -DefaultGateway 10.1.1.1 -Dns 10.1.1.2,10.1.1.3
    $vm=New-VM -Name $vm -Location $location -Template $template_name
    -Host $destination_host -Datastore $datastore_name -OSCustomizationSpec
    $customization -Confirm:$false
    start-vm -vm $vm -confirm:$false
    $a = $a + 1
    }
    Thank you again Matt for your contribution!

  • Seth Says:

    Matt-

    I am getting the error: “A positional parameter cannot be found that accepts argument “Server1=New-VM”.”

    Any help would be much appreciated.

    R,
    Seth

  • Matt Shadbolt Says:

    Looks like you’ve got too much in the quotes.

  • Andras H Says:

    Hello Matt,

    first of all thank you for this very good script, and your work.
    I need to deploy 100 winxp clients from a template on vSphere 4 hosts. So i am tring to use you script, but i got the following error msg in PowerCLI:

    Missing expression after unary operator ‘-’.
    At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\2VMs.ps1:19
    char:6
    + – <<<< User $username -Password $password
    + CategoryInfo : ParserError: (-:String) [], ParseException
    + FullyQualifiedErrorId : MissingExpressionAfterOperator

    what could be the problem, can you please take a short look on it? I would appreciate it. Thanks.

  • Matt Shadbolt Says:

    can you email me your 2VMs.ps1 script (matt.shadbolt@gmail.com) and I’ll take a look.

    Matt

  • Andras H Says:

    Thanks, i have sent an email to you!

Leave a Reply