TdisalvoOrinoco
Enthusiast
Enthusiast

Create VM using PowerCLI and csv file

Jump to solution

I know that there is a lot of info out there about this and I think I have a prety good working script.  A lot was borrowed from this thread, http://communities.vmware.com/thread/315193 many thanks to LucD.

My code is as follows:

## Deploy VMs from CSV File
## Much borrowed from http://communities.vmware.com/thread/315193?start=15&tstart=0


## Imports CSV file
Import-Csv "C:\guests.csv" -UseCulture | %{
## Gets Customization info to set NIC to Static and assign static IP address
    Get-OSCustomizationSpec $_.Customization | Get-OSCustomizationNicMapping | `
    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `
        -SubnetMask $_.Subnet -DefaultGateway $_.Gateway -Dns $_.DNS
    $vm=New-VM -Name $_."Server Name" -Template $_.Template -Host $_."Esx Host" `
        -Datastore $_.Datastore -OSCustomizationSpec $_.Customization `
        -Confirm:$false -RunAsync
## .......
}

It will go through and clone the VM, and then it looks like it is running the OSCustomizaitonSpec and then it bombs.  It does clean up the bad VM.  The Recent Tasks shows "clone virtual machine fails a specified parapeter was not correct. hostname"

The issue is that I am not trying to set a hostname with the OSCustomixationSpec, I am only trying to put in IP address info.

I am runningn PowerCLI 5.0.1 build 581491

My ESXi host is 5.0.0 build 914586

My vCenter Server is Ver 5.0.0 build 623373

I opened a new thread, becuase the age of the old thread.  Not sure if that is the best way to do things.     

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

A very simple and straightforward brake system 🙂

## Deploy VMs from CSV File
## Much borrowed from http://communities.vmware.com/thread/315193?start=15&tstart=0  

$maxJobs = 3 
$currentJobs
= 0
## Imports CSV file
Import-Csv "C:\temp\TestDeploy1" -UseCulture | %{ ## Gets Customization info to set NIC to Static and assign static IP address     Get-OSCustomizationSpec $_.Customization | Get-OSCustomizationNicMapping | `
## Sets the Static IP info
    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `
        -SubnetMask $_.Subnet -DefaultGateway $_.Gateway -Dns $_.DNS
## Sets the name of the VMs OS
    $cust = Get-OSCustomizationSpec -Name Test
    Set-OSCustomizationSpec -OSCustomizationSpec $cust -NamingScheme Fixed -NamingPrefix $_.VMName
## Creates the New VM from the template
    $vm=New-VM -Name $_."Server Name" -Template $_.Template -Host $_."Esx Host" `
        -Datastore $_.Datastore -OSCustomizationSpec $_.Customization `
       
-Confirm:$false -RunAsync

   
$currentJobs = Get-Job -State Running | Measure-Object | Select -ExpandProperty Count
   
while($currentJobs -ge $maxJobs){       sleep 30
     
$currentJobs = Get-Job -State Running | Measure-Object | Select -ExpandProperty Count
    }
## ....... }

You can be more selective on getting the current jobs. You could for example check if the name of the jobs shows that they are actually cloning jobs.


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

View solution in original post

0 Kudos
48 Replies
LucD
Leadership
Leadership

Could it be that the "Esx Host" column in the CSV doesn't contain a correct ESXi hostname ?

I suspect the error might be about the VMhost or Host parameter on the New-VM cmdlet.

Could you perhaps include the complete error message you get in PowerCLI ?


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

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

Hi LucD,

I do not get the error in power CLI.  Here is the output I get.

PowerCLI C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\custom> .
\Deploy.PS1

              SpecId Position IPMode           IPAddress       DefaultGateway
              ------ -------- ------           ---------       --------------
...rk 10.10.160.0/21        1 UseStaticIP      10.10.163.10    10.10.160.1

No issues there.  I get the error in Recent Tasks on the ESXi host.  I am not sure if I have to go into the vpxd.log to find more info or not.  I am getting a bundle of the logs on the target host.

If there is a specific log file location that I should be looking at please advise:-)

I verified that the ESX Host is a valid host in the cluster I am hopeing to work on.

Your help is greatly apreciated.

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

It gets to the Reconfiguring VM and that is when it fails.  IT is at 95% of the clone option.

Reconfigured mciptiershw013.********.lan
info
2/22/2013 10:31:31 AM
mciptiershw013.*********.lan
ASP\j********m

Not much more info there.

0 Kudos
LucD
Leadership
Leadership

I see, let's dig a bit deeper.

Is that template for a Linux OS ?

Try this alternative where we do the customization after the clone (New-VM) cmdlet.

## Imports CSV file
Import-Csv "C:\guests.csv" -UseCulture | %{
## Gets Customization info to set NIC to Static and assign static IP address
    Get-OSCustomizationSpec $_.Customization | Get-OSCustomizationNicMapping | `
   
Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `
        -SubnetMask $_.Subnet -DefaultGateway $_.Gateway -Dns $_.DNS
   
$vm=New-VM -Name $_."Server Name" -Template $_.Template -Host $_."Esx Host" `
        -Datastore $_.Datastore -Confirm:$false -RunAsync |
        Set-OSCustomizationSpec -OSCustomizationSpec $_.Customization
## .......
}

And I would also be interested to see the content of the OSCustomizationSpec (make sure to hide the sensitive data).

Can you do a

Get-OSCustomizationSpec $_.Customization | Select * 

You can replace the $_.Customization with the actual name, as it is defined in the CSV, for that oscustomizationspec.

If the error keeps popping up, a closer look at the vpxd logs would be the next course of action.


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

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

Here is the output from PowerCLI C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\custom> G
et-OSCustomizationSpec "MCI - Windows 2008 R2 Standard - ************ Trusted N
etwork 10.10.192.0/21" | Select *

As you can see it is a windows Guest OS

Name                  : MCI - Windows 2008 R2 Standard - ********Trusted
                        Network 10.10.192.0/21
Type                  : Persistent
ServerId              : /VIServer=@mcipvcntw001.***.****.lan:443/
Server                : MCIPVCNTW001.***.****.lan
LastUpdate            : 7/5/2012 4:54:39 PM
DomainAdminUsername   : ******
DomainUsername        : ******
Description           :
AutoLogonCount        : 1
ChangeSid             : True
DeleteAccounts        : False
DnsServer             :
DnsSuffix             :
Domain                : **************
FullName              : ***** Infrastructure
GuiRunOnce            :
NamingPrefix          :
NamingScheme          :
OrgName               : ******************
OSType                : Windows
ProductKey            : 82VMD-*****-*****-******-H2X8F
TimeZone              : Central (U.S. and Canada)
Workgroup             :
LicenseMode           : PerSeat
LicenseMaxConnections :
EncryptionKey         :
ExtensionData         : VMware.Vim.CustomizationSpecItem
Id                    : MCI - Windows 2008 R2 Standard - ***********Trusted
                        Network 10.10.192.0/21
Uid                   : /VIServer=@mcipvcntw001.***.****.lan:443/OSCustomizatio
                        nSpec=MCI - Windows 2008 R2 Standard - **********Tr
                        usted Network 10.10.192.0&slash;21/

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

OK when I run the updated script, 1st I was warned that I had to run it in a 32bit PowerCLI shell.

PowerCLI C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\custom> .
\Deploy1.PS1

              SpecId Position IPMode           IPAddress       DefaultGateway
              ------ -------- ------           ---------       --------------
...rk 10.10.160.0/21        1 UseStaticIP      10.10.163.10    10.10.160.1
Set-OSCustomizationSpec : This cmdlet requires 32bit process. Please run PowerC
LI in 32 bit mode.
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\custom\Deploy1
.ps1:12 char:26
+         Set-OSCustomizationSpec <<<<  -OSCustomizationSpec $_.Customization
    + CategoryInfo          : NotSpecified: (:) [Set-OSCustomizationSpec], ViE
   rror
    + FullyQualifiedErrorId : VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.
   VimException.ViError,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetCusto
  mizationSpec

Once I did this, I got a differnt error.

PowerCLI C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\custom> .
\Deploy1.ps1

              SpecId Position IPMode           IPAddress       DefaultGateway
              ------ -------- ------           ---------       --------------
...rk 10.10.160.0/21        1 UseStaticIP      10.10.163.10    10.10.160.1
Set-OSCustomizationSpec : The input object cannot be bound to any parameters fo
r the command either because the command does not take pipeline input or the in
put and its properties do not match any of the parameters that take pipeline in
put.
At C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\custom\Deploy1
.ps1:12 char:26
+         Set-OSCustomizationSpec <<<<  -OSCustomizationSpec $_.Customization
    + CategoryInfo          : InvalidArgument: (CloneVM_Task:PSObject) [Set-OS
   CustomizationSpec], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.
   Cmdlets.Commands.SetCustomizationSpec

This error outputed, prior to the VM being cloned in the Recent Tasks.  Is this because the -RunAsync is set?

Either way once the VM started cloning, it died at the same point as the prior one did.

I have manually run the clone and it does work when you are manually inputting the value.

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

I think that I got it!  Well most of it

So in the OSCustomizationSpec that I was using, under the Computer Name Section, the NetBIOS Name was set to the radio button for Enter a name in the DeployWizard.

So the name it was looking for was the Host Name of the VM!

The one issue I now see is that on the Virtual Mahcine Tab from the host, where it lists all of the VMs Names, State, Status, Host Mem, Guest Mem, VMware Tools, DNS Name,....

The DNS Name is incorrect.  the VM - Name is mvicptiershw013.*************.lan however the DNS name is mciptiershw013w.  Is there a way to set this?

0 Kudos
LucD
Leadership
Leadership

The fact that you had a prompt in the OSCustomizationSpec explains the error.

There are several ways to change the hostname inside the guest OS.

You can use the WMI cmdlet, but that requires the VM to be accessible over the network.

Or use the Invoke-VMScript and execute the WMI cmdlet or the netdom command inside the guest OS.

But once you correct the NetBIOS name in the OSCustomizationSpec, is the generated hostname still incorrect ?


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

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

No it looks like if I correc the NetBIOS name I am ok.

Can I use the  Set-OSCustomizationSpec -Name filed and then pass it a name from the csv file?

If so please let me know where I would be placing this info.  I was thinking after the Get-OSCustomizationSpec line.

Please advise, and again thanks for all your help.

Tony

0 Kudos
LucD
Leadership
Leadership

No, the Name parameter on the Set-OSCustomizationSpec cmdlet is for the name you want to give to the customizationspec.

You will have to use the NamingScheme and NamingPrefix parameters.

For example, this

$cust = Get-OSCustomizationSpec -Name Test 
Set-OSCustomizationSpec
-OSCustomizationSpec $cust -NamingScheme Fixed -NamingPrefix MyName

will change the Customizationspec as follows

custName.png


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

TdisalvoOrinoco
Enthusiast
Enthusiast

LucD,

That seems to have done it.  I do have one final question.  Is there a way to limit the amount of VMs that it attemps to create at a time, other than limiting the number that are in the CSV file?  I am concernted that we may beat the crunck out of the hosts and affect the currenlty running VMs

Here is the script so far.

## Deploy VMs from CSV File
## Much borrowed from http://communities.vmware.com/thread/315193?start=15&tstart=0


## Imports CSV file
Import-Csv "C:\temp\TestDeploy1" -UseCulture | %{
## Gets Customization info to set NIC to Static and assign static IP address
    Get-OSCustomizationSpec $_.Customization | Get-OSCustomizationNicMapping | `
## Sets the Static IP info
    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `
        -SubnetMask $_.Subnet -DefaultGateway $_.Gateway -Dns $_.DNS
## Sets the name of the VMs OS
    $cust = Get-OSCustomizationSpec -Name Test
    Set-OSCustomizationSpec -OSCustomizationSpec $cust -NamingScheme Fixed -NamingPrefix $_.VMName
## Creates the New VM from the template
    $vm=New-VM -Name $_."Server Name" -Template $_.Template -Host $_."Esx Host" `
        -Datastore $_.Datastore -OSCustomizationSpec $_.Customization `
        -Confirm:$false -RunAsync
## .......
}

0 Kudos
LucD
Leadership
Leadership

In which sense do you want to limit this ?

The number of parallel clone jobs that can run at a given time ?

Or a maximum number of cloned VMs that can be created (irrespective of what number of lines are in the CSV file).


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

0 Kudos
TdisalvoOrinoco
Enthusiast
Enthusiast

Ideally I would like to limit the number of paralle clone jobs.  Just to allow that warm fuzzy feeling, to not over strees an environment.  I know that it should not be an issue but by being able to limit the number of clones there is more of a feeling of control over how much load you are going to drop onto a system.

0 Kudos
LucD
Leadership
Leadership

A very simple and straightforward brake system 🙂

## Deploy VMs from CSV File
## Much borrowed from http://communities.vmware.com/thread/315193?start=15&tstart=0  

$maxJobs = 3 
$currentJobs
= 0
## Imports CSV file
Import-Csv "C:\temp\TestDeploy1" -UseCulture | %{ ## Gets Customization info to set NIC to Static and assign static IP address     Get-OSCustomizationSpec $_.Customization | Get-OSCustomizationNicMapping | `
## Sets the Static IP info
    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `
        -SubnetMask $_.Subnet -DefaultGateway $_.Gateway -Dns $_.DNS
## Sets the name of the VMs OS
    $cust = Get-OSCustomizationSpec -Name Test
    Set-OSCustomizationSpec -OSCustomizationSpec $cust -NamingScheme Fixed -NamingPrefix $_.VMName
## Creates the New VM from the template
    $vm=New-VM -Name $_."Server Name" -Template $_.Template -Host $_."Esx Host" `
        -Datastore $_.Datastore -OSCustomizationSpec $_.Customization `
       
-Confirm:$false -RunAsync

   
$currentJobs = Get-Job -State Running | Measure-Object | Select -ExpandProperty Count
   
while($currentJobs -ge $maxJobs){       sleep 30
     
$currentJobs = Get-Job -State Running | Measure-Object | Select -ExpandProperty Count
    }
## ....... }

You can be more selective on getting the current jobs. You could for example check if the name of the jobs shows that they are actually cloning jobs.


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

View solution in original post

0 Kudos
mohan_reddy
Contributor
Contributor

Hi,

need help to install the 100 linux vm's with the powerCLI,

I read the previce scripts and used the same, i able to create the vm's but all the vm's are comming with the same host name( but the vm display name is redding from the excel as in csv file ) and the ip also now getting assined.

.ps1 file :

---------------------------------------------------------------------------------------------------------------------------------------------

Import-Csv "C:\guests.csv" -UseCulture | %{
    Get-OSCustomizationSpec $_.Customization | Get-OSCustomizationNicMapping | `
    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `
        -SubnetMask $_.Subnet -DefaultGateway $_.Gateway -Dns $_.DNS
    $vm=New-VM -Name $_."Server Name" -Template $_.Template -Host $_."Esx Host" `
        -Datastore $_.Datastore -Confirm:$false -RunAsync |
        Set-OSCustomizationSpec -OSCustomizationSpec $_.Customization

--------------------------------------------------------------------------------------------------------------------------------------------

.csv hedding :

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Server   NameEsx HostDatastoreTemplateCustomizationIP AddressSubnetGatewayDNS

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Error message :

------------------------------------------------------------------------------------------------------------------------------------------

Set-OSCustomizationNicMapping : 3/7/2013 4:19:11 PM    Set-OSCustomizationNicMa
pping        You must not provide Wins or Dns when you create NIC mapping for a
customization spec with type 'linux'.
At C:\vmps2.ps1:3 char:34
+     Set-OSCustomizationNicMapping <<<<  -IpMode UseStaticIP -IpAddress $_."IP
Address" `
    + CategoryInfo          : InvalidArgument: (:) [Set-OSCustomizationNicMapp
   ing], ViError
    + FullyQualifiedErrorId : Core_NicMappingCmdletBase_ValidateParameters_Lin
   uxAndWins,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetOSCustomizationN
  icMapping

Set-OSCustomizationSpec : The input object cannot be bound to any parameters fo
r the command either because the command does not take pipeline input or the in
put and its properties do not match any of the parameters that take pipeline in
put.
At C:\vmps2.ps1:7 char:32
+         Set-OSCustomizationSpec <<<<  -OSCustomizationSpec $_.Customization
    + CategoryInfo          : InvalidArgument: (CloneVM_Task:PSObject) [Set-OS
   CustomizationSpec], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.
   Cmdlets.Commands.SetCustomizationSpec

Set-OSCustomizationNicMapping : 3/7/2013 4:19:16 PM    Set-OSCustomizationNicMa
pping        You must not provide Wins or Dns when you create NIC mapping for a
customization spec with type 'linux'.
At C:\vmps2.ps1:3 char:34
+     Set-OSCustomizationNicMapping <<<<  -IpMode UseStaticIP -IpAddress $_."IP
Address" `
    + CategoryInfo          : InvalidArgument: (:) [Set-OSCustomizationNicMapp
   ing], ViError
    + FullyQualifiedErrorId : Core_NicMappingCmdletBase_ValidateParameters_Lin
   uxAndWins,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetOSCustomizationN
  icMapping

Set-OSCustomizationSpec : The input object cannot be bound to any parameters fo
r the command either because the command does not take pipeline input or the in
put and its properties do not match any of the parameters that take pipeline in
put.
At C:\vmps2.ps1:7 char:32
+         Set-OSCustomizationSpec <<<<  -OSCustomizationSpec $_.Customization
    + CategoryInfo          : InvalidArgument: (CloneVM_Task:PSObject) [Set-OS
   CustomizationSpec], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.
   Cmdlets.Commands.SetCustomizationSpec

Set-OSCustomizationNicMapping : 3/7/2013 4:19:22 PM    Set-OSCustomizationNicMa
pping        You must not provide Wins or Dns when you create NIC mapping for a
customization spec with type 'linux'.
At C:\vmps2.ps1:3 char:34
+     Set-OSCustomizationNicMapping <<<<  -IpMode UseStaticIP -IpAddress $_."IP
Address" `
    + CategoryInfo          : InvalidArgument: (:) [Set-OSCustomizationNicMapp
   ing], ViError
    + FullyQualifiedErrorId : Core_NicMappingCmdletBase_ValidateParameters_Lin
   uxAndWins,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetOSCustomizationN
  icMapping

Set-OSCustomizationSpec : The input object cannot be bound to any parameters fo
r the command either because the command does not take pipeline input or the in
put and its properties do not match any of the parameters that take pipeline in
put.
At C:\vmps2.ps1:7 char:32
+         Set-OSCustomizationSpec <<<<  -OSCustomizationSpec $_.Customization
    + CategoryInfo          : InvalidArgument: (CloneVM_Task:PSObject) [Set-OS
   CustomizationSpec], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.
   Cmdlets.Commands.SetCustomizationSpec

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Regrds,

Mohan.

0 Kudos
LucD
Leadership
Leadership

For a Linux OS you can not specify the DNS parameter on the Set-OSCustomization cmdlet.

First try leaving out the this DNS parameter


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

0 Kudos
mohan_reddy
Contributor
Contributor

Thanks LucD its working, i can able to install,

is thare any option to run a script or command's after installation the linux vm's onely after the first start.

Regards,

Mohan.

0 Kudos
StivOstenberg
Contributor
Contributor

Trying to make this work,  and it is failing, I THINK because I have no OSCustomizationSpec defined.  This would be a prereq to make this work, and not sure how to set it up.  Will figure it out, but might want to add something so this works out of the box.
  And thanks for the script!

Just because it's Virtual doesn't mean it ain't real!
0 Kudos
Sivaramsharmar
Enthusiast
Enthusiast

Hi Lucd,

I am not able to limit the VM Cloning as per your below script. Please suggest.

$MaxClones = 3

$CurrentClones = 0

$CSV = "C:\users\$env:username\Linux.csv"

$nvm = Import-CSV $CSV -Useculture

$nvm | %{

New-VM -Name $_.Name -vm $(Get-Cluster $_.cluster | Get-ResourcePool $_.SVMLocation | get-vm $_.SourceVM) -VMHost $(Get-Cluster $_.cluster | Get-VMHost -state "connected" | Get-Random) -ResourcePool $(Get-Cluster $_.cluster | Get-ResourcePool $_.rp) -datastore $(Get-Cluster $_.cluster | Get-DataStore $_.ds) -Notes $_.Notes -RunAsync

$CurrentClones = Get-Job -State Running | Measure-Object | Select -ExpandProperty Count

  while($CurrentClones -ge $MaxClones)

  {

  sleep 30

  $CurrentClones = Get-Job -State Running | Measure-Object | Select -ExpandProperty Count

  }

}

0 Kudos