VMware Cloud Community
Kiala
Contributor
Contributor
Jump to solution

Auto Deploy Multiple VMs Script Error

Hi Guys,

I am trying to create multiple VMs with unique IP address and NetBIOS name for each VMs thrugh a Powershell script. Here is my scenario:

I have 2 VMs on one of my server x.x.x.x


1. Autodeploy-1 – The VM on which I am running the script through vSphere PowerCLI
2. AutoDeployVM – Template I am using for creating other VMs.

#Script

# 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)”

$customization = "customfile"

# 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-OSCustomizationSpec $customization | 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 -OSCustomizationSpec $customization

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

}

I have placed the customization file (customfile) in the same folder where the script is. Below is the content of my customfile:

New-OSCustomizationSpec -Name Spec -OSType Windows -FullName Administrator -AdminPassword ****** -Domain abcd.com -DomainUsername abc -DomainPassword ********

I am getting following errors:

1. Set-OSCustomizationSpec : A parameter cannot be found that matches parameter name 'IpMode'.

2. New-VM        Could not find Template with name 'AutodeployVM'.

3. New-VM        Template parameter: Could not find any of the objects specified by name.

Can you guys help me with this. Am I missing anything. I am very new to this thing. Appreciate your help.

Thanks,

Kiala

0 Kudos
63 Replies
LucD
Leadership
Leadership
Jump to solution

Yes, that is what I mean.

You can automate this with the New-OSCustomizationSpec and New-OSCustomizationNicMapping cmdlets.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

I tried to get this working before without any luck.  LucD you attempted to help me out before but I never got anywhere.  It looks like  now we are making some progress with this?

I dont want to sysprep the machines, just clone and set the IP/hostname.

When I attempt to run this:

[vSphere PowerCLI] C:\Users\helloworld\Desktop\powerCLI> Get-OSCustomizationSpec q
a | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseSta
ticIP -IpAddress $IParray[$a] -SubnetMask 255.255.254.0 -DefaultGateway 10.102.3
0.1 -Dns 10.0.2.35,10.0.2.60

Cannot index into a null array.
At line:1 char:132
+ Get-OSCustomizationSpec qa | Get-OSCustomizationNicMapping | Set-OSCustomizat
ionNicMapping -IpMode UseStaticIP -IpAddress $IParray[ <<<< $a] -SubnetMask 255
.255.254.0 -DefaultGateway 10.102.30.1 -Dns 10.0.2.35,10.0.2.60
     + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
     + FullyQualifiedErrorId : NullArray

I get that error. Any ideas?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It looks like $IParray is empty.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

LucD wrote:

It looks like $IParray is empty.

Ok, how do I fix that?  I used the commands you posted on the first page.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you defined the $IParray similar to something like this

$iparray = “x.x.x.1″, “x.x.x.2″
$a= 0

You should be able to use the expression

$iparray[$a]

Are you running this in a debugger ?

If yes, place a breakpoint and check the contants of $ipaddr and $a just before the statement with the Get-OSCustomization cmdlet.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

Figured that issue out, now I have another one.

vCenter is running on 2k8R2 but I am trying deploy win2003 image, does that matter?  FYI The option is grayed out for customization when deploying through vCenter but it thought sysprep tools were built-in to 2008?? Not even sure thats the issue.

Gets to 93% then fails with the following error message:


New-VM : 3/30/2011 11:01:33 AM    New-VM        The operation for the entity Vi
rtualMachine-vm-877 failed with the following message: "Cannot complete customi
zation."
At C:\Users\dp_admin\Desktop\powerCLI\CK_script.ps1:25 char:11
+ $vm=New-VM <<<<  -Name $vm -Template $template_name -Host $destination_host -
Datastore $datastore_name -OSCustomizationSpec $customization -Confirm:$false
    + CategoryInfo          : NotSpecified: (:) [New-VM], CustomizationFault
    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpda
   tes_OperationFailed,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVM

From Vcenter logs:

[2011-03-30 08:01:25.088 01308 error 'App' opID=bfa9c039] [clone] (Template_w2k3r2s32qa) Unexpected exception (vim.fault.CustomizationFault) during clone. Aborting.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The OS of your vCenter doesn't matter, but you need to have the sysprep files, for the OS you are deploying, installed on the vCenter.

See KB1005593.

I have seen that message before, most of the time it indicates missing sysprep files.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

Thanks man. But there is no place that I can see to put the win2003 sysprep files on the 2008R2 vcenter server. Any idea?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sorry, didn't get that it was for W2K8 R2.

As the KB says, for those you don't need sysprep files, the tools are build in.

Anything in the logs (vpdx) on the vCenter ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

Yeah I posted it up before, the only thing referencing the template is this:

2376 error 'App' opID=399ccac6] Error occured while creating deploy package. Msg: C:\ProgramData\VMware\VMware VirtualCenter\sysprep\svr2003 doesn't contain known sysprep files.

Successfully deleted file/directory C:\Windows\TEMP\imcE4E1.tmp

(Template_w2k3r2s32qa) Unexpected exception (vim.fault.CustomizationFault) during clone. Aborting.

So now that I see its looking for the sysprep files in C:\ProgramData\VMware\VMware VirtualCenter\sysprep\svr2003 I extracted the deploy.cab from the win2003R2 sysprep and place them in there.

Will run it again to see if it works. I never knew there was a sysprep folder located there.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Forget my previous reply, you are trying to deploy a W2K3 guest and your vCenter runs on a W2K8 R2 server.

That means you need to have the W2K3 sysprep files.

On a W2K8 R2 server they need to go to C:\ProgramData\VMware\VMware VirtualCenter\Sysprep if I'm not mistaken.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

OK I got it working then changed a couple things and I cant figure out what I changed to get it working again.  Can you look over my shit real quick?  Getting the Nullarray error when trying to do this:

[vSphere PowerCLI] C:\Users\helloworld\Desktop\powerCLI> Get-OSCustomizationSpec q
a | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseSta
ticIP -IpAddress $IParray[$a] -SubnetMask 255.255.254.0 -DefaultGateway 10.120.3
0.1 -Dns 10.0.2.35,10.0.2.60
Cannot index into a null array.
At line:1 char:132
+ Get-OSCustomizationSpec qa | Get-OSCustomizationNicMapping | Set-OSCustomizat
ionNicMapping -IpMode UseStaticIP -IpAddress $IParray[ <<<< $a] -SubnetMask 255
.255.254.0 -DefaultGateway 10.120.30.1 -Dns 10.0.2.35,10.0.2.60
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray


Relevent part of the script:

# Name the VMs in this array
$array = “w2k3r2s32q21-vm"
$iparray = "10.102.30.146"
$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.254.0 -DefaultGateway 10.102.30.1 -Dns 10.0.2.35,10.0.2.60
$vm=New-VM -Name $vm -Template $template_name -Host $destination_host -Datastore $datastore_name -OSCustomizationSpec $customization -Confirm:$false -RunAsync

$a = $a + 1
}

Please tell me its something simple.  lol Pulling my hair out now that it worked once but not working anymore.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

When you assign a single value to $IPaddr, the variable will not be an array and hence you can't index it like $IPaddr[$a]

The trick is force an array even if you only assign one value. Like this

$IPaddr = @("1.2.3.4")


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
max08
Contributor
Contributor
Jump to solution

Ok.

So I got single deployment static IP working with the script below,  however $IPaddr wouldnt work, I had to leave it as $IParray.

Thanks a lot LucD! 

# Name the VMs in this array
$array = “w2k3r2s32qa33-vm"
$IParray = @("10.102.30.158")
$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.254.0 -DefaultGateway 10.102.30.1 -Dns 10.0.2.35,10.0.2.60
$vm=New-VM -Name $vm -Template $template_name -Host $destination_host -Datastore $datastore_name -OSCustomizationSpec $customization -Confirm:$false -RunAsync

$a = $a + 1
}

0 Kudos
gudhillo
Contributor
Contributor
Jump to solution

Hi LucD and Everyone,

I have below script to deploy multiple VM's, got from some blogs and merged it as per my requirement. When I run it, I am able to deploy VM's as I want to, but there are some errors on the console, not sure what the errors are, can some one help me to resolve this, errors are mention in red below.

I have one more question, I am able to deploy the VM's, how much I want, for example 10. but scripts starts deploying 10 VM's at the same time, where I dont want this to happen, Can the scipt be configured in such a way that, only 3 concurrent VM's should be deployed and others should be queued, once the earlier vm or vm's deployment is completed , the queue one will start.

Here is the script

======================================================================

Connect-VIServer "vcenter server" -User "abc" -Password "xyz"


# Define Variables


$NameVM ="vmtest000"
$strTemplate = "vPC template Win7 BNL 3.0.b5"
$strDestinationHost = "vmnlutr01-host02.capgemini.nl"
$strCustomSpec = "vPC Vista-Win7 customization"
$strDatastore = "UTR-VPC-pool09"
$strLocation = "vPCs BPO"
$strPool = "vPCs UTR"


# Mention number of VM to create
$HOW_MANY_TO_CREATE=1



$Date=get-date -uformat “%Y%m%d”
$NumArray = (1..$HOW_MANY_TO_CREATE)



for ([int]$seq=1;$seq -le $HOW_MANY_TO_CREATE;$seq++)


{$string = $NameVM + ($seq.tostring(“0##”)) #original


“Creating $string”


New-VM -Name $string -Template $(get-template $strTemplate) -location (get-folder $strLocation) -pool (get-resourcepool $strPool) -VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec)  | Start-VM
}


DisConnect-VIServer "vcenter server" -Confirm:$false

======================================================================

Error after deployment

======================================================================

Creating vmtest000001
New-VM : 11/2/2011 12:26:26 PM    New-VM        Operation is not valid due to the current state of the object.   
At C:\Software\Powershell script\deploy multiple vm 3.ps1:28 char:7
+ New-VM <<<<  -Name $string -Template $(get-template $strTemplate) -location (get-folder $strLocation) -pool (get-resourcepool $strPool) -
VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -OSCustomizationSpec $(Get-OSCustomizationSpec $strCusto
mSpec)  | Start-VM
    + CategoryInfo          : NotSpecified: (:) [New-VM], VimException
    + FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVM

======================================================================

Regards

Gurjit Dhillon

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Are you running the script from PowerGUI ?

There has been a similar error report when the user wasn't on the latest PowerGUI version.

See New-VM error (Operation is not valid due to the current state of the object.)

There are ways to throttle you scripts.

One of these is to start the New-VM cmdlet with the RunAsync parameter, followed by a Get-Task cmdlet.

If you see for example 3 task of the New-VM cmdlet with the status running, you can make the scriptwait (Sleep) for a number of seconds and then try the Get-Task again.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
gudhillo
Contributor
Contributor
Jump to solution

Hi LucD,

First of thanks for your reply.

I have upgraded PowerGUI from ver 3 to ver 3.1, after which there was no more error. 🙂

I have also added -Runasync in my script as mention below. After which I have found, if I configure the script to deploy more than 1 vm, for example 3, only one deployment starts, once 1st vm is deployed successfully , my 2nd deployment starts  on its own, and after which 3rd vm starts.

Just to test agian I removed the -runasunc commad from the below command and still only 1 vm was getting deployed at a time. it was surprising for me as earlier I was able to see multiple vm's are getting deployed. Is this happening due to upgrade of PowerGUI I did earlier ?

LucD, can you help me with the to configure the script from which I can start concurrent deployment of VM's ?

New-VM -Name $string -Template $(get-template $strTemplate) -location (get-folder $strLocation) -pool (get-resourcepool $strPool) -VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec) | Start-VM -RunAsync

Regards

Gurjit Dhillon

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The RunAsync parameter should go on the New-VM cmdlet.

The following is a simple version, the script will start a maximum of 3 new VM creation task in parallel.

If 3 tasks are running, the script will sleep for 30 seconds and then check again how many are running.

...
$Max
-Running = 3

for ([int]$seq = 1;$seq -le $HOW_MANY_TO_CREATE;$seq++){     $string = $NameVM + ($seq.tostring(0##)) #original
   Creating $string
   
New-VM -Name $string -Template $(get-template $strTemplate) -location (get-folder $strLocation) -pool (get-resourcepool $strPool) -VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec) -RunAsync
   
while ((Get-Task -Status queued,running | where {$_.Name -eq "CreateVM_Task"} | Measure-Object).Count -gt $Max-Running){         sleep 30
    } } for ([int]$seq = 1;$seq -le $HOW_MANY_TO_CREATE;$seq++){     $string = $NameVM + ($seq.tostring(0##)) #original
   Starting $string
   
Get-VM -Name $string | Start-VM -Confirm:$false
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
gudhillo
Contributor
Contributor
Jump to solution

HI LucD,

Thanks again for your reply and script.

I have tried running the scipt, scipt do deploy the multiple VM's now at the same time, but the concurrent things are not working.

I have set the script as per below, but still scripts starts 7 VM's deployment and not only 2. BTW, I have removed "-" from $Max-Running, as script was taking it as operator.

$MaxRunning = 2

$HOW_MANY_TO_CREATE=7

Is something missing ?

Regards

Gurjit Dhillon

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I suspect you are not trying to limit the number of VM (New-VM) but the actual deployment of the OS inside the VM.

Then you will have to check on the Start-VM instead of the New-VM.

Something like this

$HOW_MANY_TO_CREATE = 7 
$MaxRunning = 3

for ([int]$seq = 1;$seq -le $HOW_MANY_TO_CREATE;$seq++){     $string = $NameVM + ($seq.tostring(0##)) #original
   Creating $string
    New-VM -Name $string -Template $(get-template $strTemplate) -location (get-folder $strLocation) -pool (get-resourcepool $strPool) -VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec) | Start-VM -RunAsync
    while ((Get-Task -Status queued,running | where {$_.Name -eq "PowerOnVM_Task"} | Measure-Object).Count -gt $MaxRunning){         sleep 30
    } }


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos