Pinball
Enthusiast
Enthusiast

Bulk deploy vm's with customization via csv import

Hi there

I'm trying to deploy 200 vm's from a predefined csv file including customization but it seems to fail with the declaring of variables as the fields is Null or empty. Could you pleasehelp any poiny out where i'm going wrong with this approach.

Script used:

'*******************************************************************************************************************************************************************************************************'

'Beginning Script'

'Loading Snapins'

function LoadSnapin{

  param($PSSnapinName)

  if (!(Get-PSSnapin | where {$_.Name   -eq $PSSnapinName})){

    Add-pssnapin -name $PSSnapinName

  }

}

LoadSnapin -PSSnapinName   "VMware.VimAutomation.Core"

'Reading CSV file'

$vms = Import-CSV "C:\PS\TVGTest.csv"

'Reading the contents of the CSV, and for each line execute the following code'

foreach ($vm in $vms){

'Declaring variables that correspond to the column names in the CSV'

      $VMName = $vm.name

      $VMHost = $vm.host

      $Datastore = $vm.datastore

      $Template = $vm.template

      $Customization = $vm.customization

      $IPAddress = $vm.ipaddress

      $Subnetmask = $vm.subnetmask

      $DefaultGW = $vm.defaultgw

      $DNS1 = $vm.dns1

      $DNS2 = $vm.dns2

      $VLAN = $vm.vlan

   $Memory = $vm.mem

   $CPU = $vm.cpu

     

      'Modifying the customization file with the network information you specified in the CSV'

      Get-OSCustomizationSpec $Customization | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress $IPAddress -SubnetMask $Subnetmask -DefaultGateway $DefaultGW -Dns $DNS1,$DNS2

     

      'Deploying a new VM from the template you specified in the CSV'

      New-VM -Name $VMName -OSCustomizationSpec $Customization -Template $Template -VMHost $VMHost -Datastore $Datastore | Set-VM -NumCpu $CPU -MemoryMB $Memory -Confirm:$false -RunAsync

  

   'Set new VM VLAN'

   Get-VM -Name $VMName | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $VLAN -Confirm:$false

     

      'Powering up the newly created VM, to allow the guest customization to complete'

      Start-VM -VM $VMName -RunAsync

}

'Ending Script'

'*******************************************************************************************************************************************************************************************************'

Output:

PowerCLI C:\PS> .\TVG_Test.ps1

*****************************************************************************************************************************************************

**************************************************

Beginning Script

Loading Snapins

Reading CSV file

Reading the contents of the CSV, and for each line execute the following code

Declaring variables that correspond to the column names in the CSV

Modifying the customization file with the network information you specified in the CSV

Get-OSCustomizationSpec : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or

empty, and then try the command again.

At C:\PS\TVG_Test.ps1:33 char:31

+       Get-OSCustomizationSpec $Customization | Get-OSCustomizationNicMapping | S ...

+                               ~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-OSCustomizationSpec], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetOSCustomizationSpec

Deploying a new VM from the template you specified in the CSV

New-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try

the command again.

At C:\PS\TVG_Test.ps1:36 char:20

+       New-VM -Name $VMName -OSCustomizationSpec $Customization -Template $Templa ...

+                    ~~~~~~~

    + CategoryInfo          : InvalidData: (:) [New-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVM

Set new VM VLAN

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try

the command again.

At C:\PS\TVG_Test.ps1:39 char:16

+      Get-VM -Name $VMName | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $V ...

+                   ~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Powering up the newly created VM, to allow the guest customization to complete

Start-VM : Cannot validate argument on parameter 'VM'. The argument is null or empty. Provide an argument that is not null or empty, and then try

the command again.

At C:\PS\TVG_Test.ps1:42 char:20

+       Start-VM -VM $VMName -RunAsync

+                    ~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Start-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.StartVM

Ending Script

8 Replies
naiksidd
Enthusiast
Enthusiast

can you post your csv headers as well.??

it mostly could be position of your headers

I would Generally do this "import-csv -path <path> -header ("<Header1>","Header2",...);"

0 Kudos
Pinball
Enthusiast
Enthusiast

csv Header:

host,

datastore,

name,

template,

customization,

guestid,

cpu,

mem,

vlan,

ipaddress,

subnetmask

,defaultgw,

dns1,

dns2

0 Kudos
naiksidd
Enthusiast
Enthusiast

hi,

try using this

$vms = import-csv -path "C:\PS\TVGTest.csv" -header ( "host","datastore","name","template","customization","guestid","cpu","mem","vlan","ipaddress","subnetmask","defaultgw","dns1","dns2");

instead of "$vms = Import-CSV "C:\PS\TVGTest.csv"

0 Kudos
LucD
Leadership
Leadership

Your import of the CSV file seems to fail.

Is

Import-Csv "C:\PS\TVGTest.csv"

returning anything ?

Eventually try

Import-Csv "C:\PS\TVGTest.csv" -UseCulture


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

0 Kudos
JVidanez
Contributor
Contributor

Hi,

I was trying to follow your script after fix it with the "-useculture".

But I found that you can not set the hostname on the guest os in linux. How do you fix it?

Regards,

JJ

0 Kudos
LucD
Leadership
Leadership

That should be possible through the OSCustomizationSpec and the NamingScheme parameter in there.

Do you have that in your OSCustomizationSpec, and do you update the OSCustomizationSpec for each VM you deploy ?


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

JVidanez
Contributor
Contributor

This is how the script look like now:

#Beginning Script

#Loading Snapins

function LoadSnapin{

  param($PSSnapinName)

  if (!(Get-PSSnapin | where {$_.Name   -eq $PSSnapinName})){

    Add-pssnapin -name $PSSnapinName

  }

}

LoadSnapin -PSSnapinName   "VMware.VimAutomation.Core"

#Reading CSV file'

$vms = Import-CSV ".\vmlistfile1.csv" -UseCulture

#Reading the contents of the CSV, and for each line execute

foreach ($vm in $vms){

       

      #Modifying the customization file with the network information you specified in the CSV for each vm

      $vmocustpervm = Get-OSCustomizationSpec $vm.oscust | New-OSCustomizationSpec -name $vm.oscust_$vms.name -OSType Linux

      Get-OSCustomizationSpec $vmoscustpervm | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress $vm.ip -SubnetMask $vm.mask -DefaultGateway $vm.gw

   

      #Selecting a Random hots to place the VM

      $vmcluster = Get-Cluster $vm.cluster | Get-VMHost | Where{$_.ConnectionState -eq "Connected"} | Get-Random

   

      #Deploying a new VM from the template and setting cpu and memory

      New-VM -VMhost $vmcluster -Name $vm.name -Location $vm.folder -OSCustomizationSpec $vmoscustpervm -Template $vm.template -Datastore $vm.datastorecluster | Set-VM -NumCpu $vm.numcpu -MemoryMB $vm.memorygb -Confirm:$false -RunAsync

   

      #Set distributed portgroup if there is one

      If ($vm.netgroup -gt 1){

      $vm.name | Get-NetworkAdapter | Set-NetworkAdapter -Portgroup $vm.netgroup -confirm:$false

      }

          

      #Powering up the newly created VM, to allow the guest customization to complete'

      Start-VM -VM $vm.name -RunAsync

}

#Ending Script

Would it be like modify the line:

  $vm.ocustpervm = Get-OSCustomizationSpec $vm.oscust | New-OSCustomizationSpec -name $vm.oscust_$vms.name -OSType Linux

for

  $vm.ocustpervm = Get-OSCustomizationSpec $vm.oscust | New-OSCustomizationSpec -name $vm.oscust_$vms.name -Namingscheme $vm.name -OSType Linux –Type NonPersistent

??

I have some customization done about set dns and domain

0 Kudos
JVidanez
Contributor
Contributor

Hello LUCD,

Thanks for your help.

Taking your advice and another script from http://blog.smasterson.com/2014/05/21/deploying-multiple-vms-via-powercli-updated-v1-2/comment-page-... he

That script it is referencing to you too and I have created another version called 1.3 http://www.vidanez.com/2014/11/02/crear-multiples-linux-vms-de-un-fichero-csv-usando-powercli-deploy...

Thanks so much.

Message was edited by: JVidanez www.vidanez.com

0 Kudos