VMware Cloud Community
markdjones82
Expert
Expert

VM Deployment with customization, parallel

All,

  I am using a modified script I found on Jase's blog, (Thanks!) and it appears to be working great, but my big problem is it does one at a time.  I would like them to go in parallel. Is there anyway to do this?  I have tried to add the -RunAsync option on my new-vm command, but then I get errors. Without the runasync command it works group see errors below the script.

##########################################################
# cloneandsetip.ps1

##########################################################
Connect-VIServer vcentername.name.com

$vmlist = Import-CSV vms.csv

foreach ($item in $vmlist) {

    # I like to map out my variables
    $basevm = $item.basevm
    $datastore = $item.datastore
    $vmhost = $item.vmhost
    $custspec = $item.custspec
    $vmname = $item.vmname
    $ipaddr = $item.ipaddress
    $subnet = $item.subnet
    $gateway = $item.gateway
    $pdns = $item.pdns
    $sdns = $item.sdns
    $vlan = $item.vlan

    #Get the Specification and set the Nic Mapping
    Get-OSCustomizationSpec $custspec | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress $ipaddr -SubnetMask $subnet -DefaultGateway $gateway -Dns $pdns,$sdns
   
    #Clone the BaseVM with the adjusted Customization Specification
   New-VM -Name $vmname -template $basevm -Datastore $datastore -VMHost $vmhost -RunAsync | Set-VM -OSCustomizationSpec $custspec -Confirm:$false

    #Set the Network Name (I often match PortGroup names with the VLAN name)
    Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $vlan -Confirm:$false

    #Remove the NicMapping (Don't like to leave things unkept)
    Remove-OSCustomizationNicMapping -OSCustomizationNicMapping (Get-OSCustomizationSpec Test | Get-OSCustomizationNicMapping) -Confirm:$false

Errors that occur:

Set-VM : The input object cannot be bound to any parameters for the command eit
her because the command does not take pipeline input or the input and its prope
rties do not match any of the parameters that take pipeline input.
At U:\powercli\deployvm.ps1:30 char:100
+     New-VM -Name $vmname -template $basevm -Datastore $datastore -VMHost $vmh
ost -RunAsync | Set-VM <<<<  -OSCustomizationSpec $custspec -Confirm:$false
    + CategoryInfo          : InvalidArgument: (CloneVM_Task:PSObject) [Set-VM
   ], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.
   Cmdlets.Commands.SetVM

Get-OSCustomizationSpec : 2/17/2012 12:59:16 PM    Get-OSCustomizationSpec
   Could not find Customization Specification with name 'Test'.
At U:\powercli\deployvm.ps1:36 char:89
+     Remove-OSCustomizationNicMapping -OSCustomizationNicMapping (Get-OSCustom
izationSpec <<<<  Test | Get-OSCustomizationNicMapping) -Confirm:$false
    + CategoryInfo          : ObjectNotFound: (Test:String) [Get-OSCustomizati
   onSpec], VimException
    + FullyQualifiedErrorId : Common_CommonUtil_FilterCollection_ObjectNotFoun
   d,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetOSCustomizationSpec

Remove-OSCustomizationNicMapping : Cannot bind argument to parameter 'OSCustomi
zationNicMapping' because it is null.
At U:\powercli\deployvm.ps1:36 char:64
+     Remove-OSCustomizationNicMapping -OSCustomizationNicMapping <<<<  (Get-OS
CustomizationSpec Test | Get-OSCustomizationNicMapping) -Confirm:$false
    + CategoryInfo          : InvalidData: (:) [Remove-OSCustomizationNicMappi
   ng], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,V

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
72 Replies
BrianLBLESD
Contributor
Contributor

I am trying to run this script that Mark Jones wrote/posted on page 2 of this thread (Version 2 with the #convert back to string stuff added in, and it executes flawlessly (no nasty red text in the powercli window, except it WILL not bind to AD.

And none of the NICs work in the guest OS, though the IP address and VMNetwork name are set properly.

I am using Vsphere 5.1 build 1157734, 32bit version of PowerCli.

It looks like the script is trying to bind to AD before setting an IP.

Here are the csv columns:

template,datastore,vmhost,custspec,vmname,ipaddress,subnet,gateway,pdns,sdns,vlan,pass,adminpass,username

There are 4 blocks of output from the customization spec:

Name                  : GUESTNAME

Type                  : Persistent

ServerId              : /VIServer=NTLM\useradminuser@virtualcenter.server

                        s:443/

Server                : myvirtualcenter.windows.domain

LastUpdate            : 8/6/2013 12:05:46 PM

DomainAdminUsername   : adminuser@MY.WINDOWS.DOMAIN

DomainUsername        : adminuser@MY.WINDOWS.DOMAIN

Description           : For use with powershell script to auto clone and deploy

                         SQL servers

AutoLogonCount        : 5

ChangeSid             : True

DeleteAccounts        : False

DnsServer             :

DnsSuffix             :

Domain                : MY.WINDOWS.DOMAIN

FullName              : NETWORK SERVICES

GuiRunOnce            : {slmgr /ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX, slmgr /skms

                        10.0.0.10, slmgr /ato}

NamingPrefix          :

NamingScheme          :

OrgName               : PUBLIC AGENCY NAME

OSType                : Windows

ProductKey            : XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

TimeZone              : Pacific

Workgroup             :

LicenseMode           : PerSeat

LicenseMaxConnections :

EncryptionKey         :

ExtensionData         : VMware.Vim.CustomizationSpecItem

Id                    : GUESTNAME

Uid                   : /VIServer=NTLM\useradminuser@virtualcenter.server

                        s:443/OSCustomizationSpec=GUESTNAME/

Name                  : GUESTNAME

Type                  : Persistent

ServerId              : /VIServer=NTLM\useradminuser@virtualcenter.server

                        s:443/

Server                : myvirtualcenter.windows.domain

LastUpdate            : 8/6/2013 12:05:50 PM

DomainAdminUsername   : adminuser@MY.WINDOWS.DOMAIN

DomainUsername        : adminuser@MY.WINDOWS.DOMAIN

Description           : For use with powershell script to auto clone and deploy

                         SQL servers

AutoLogonCount        : 5

ChangeSid             : True

DeleteAccounts        : False

DnsServer             :

DnsSuffix             :

Domain                : MY.WINDOWS.DOMAIN

FullName              : NETWORK SERVICES

GuiRunOnce            : {slmgr /ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX, slmgr /skms

                        10.0.0.10, slmgr /ato}

NamingPrefix          :

NamingScheme          :

OrgName               : PUBLIC AGENCY NAME

OSType                : Windows

ProductKey            : XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

TimeZone              : Pacific

Workgroup             :

LicenseMode           : PerSeat

LicenseMaxConnections :

EncryptionKey         :

ExtensionData         : VMware.Vim.CustomizationSpecItem

Id                    : GUESTNAME

Uid                   : /VIServer=NTLM\useradminuser@virtualcenter.server

                        s:443/OSCustomizationSpec=GUESTNAME/

Dns                   : {10.0.4.138, 10.0.4.139}

Wins                  :

SpecId                : GUESTNAME

Spec                  : GUESTNAME

SpecType              : Persistent

NetworkAdapterMac     :

Position              : 1

IPMode                : UseStaticIP

IPAddress             : 10.0.5.209

SubnetMask            : 255.255.255.0

DefaultGateway        : 10.0.5.1

AlternateGateway      :

VCApplicationArgument :

Id                    : /VIServer=NTLM\useradminuser@virtualcenter.server

                        s:443/OSCustomizationNicMapping=OSCustomizationNicMappi

                        ngImpl-GUESTNAME-Persistent-1/

Uid                   : /VIServer=NTLM\useradminuser@virtualcenter.server

                        s:443/OSCustomizationNicMapping=OSCustomizationNicMappi

                        ngImpl-GUESTNAME-Persistent-1/

ExtensionData         : VMware.Vim.CustomizationAdapterMapping

PowerState              : PoweredOn

Version                 : v8

Description             :

Notes                   :

Guest                   : GUESTNAME:

NumCpu                  : 4

MemoryMB                : 8192

MemoryGB                : 8

HardDisks               : {Hard disk 1}

NetworkAdapters         : {Network adapter 1}

UsbDevices              : {}

CDDrives                : {CD/DVD drive 1}

FloppyDrives            : {Floppy drive 1}

Host                    : ESXi5HOST

HostId                  : HostSystem-host-10437

VMHostId                : HostSystem-host-10437

VMHost                  : ESXi5HOST

VApp                    :

FolderId                : Folder-group-v3

Folder                  : vm

ResourcePoolId          : ResourcePool-resgroup-8697

ResourcePool            : Resources

PersistentId            : 500885b9-263a-6b3e-fc25-4b8867afa657

UsedSpaceGB             : 40.00001154839992523193359375

ProvisionedSpaceGB      : 40.00001154839992523193359375

DatastoreIdList         : {Datastore-datastore-417}

HARestartPriority       : ClusterRestartPriority

HAIsolationResponse     : AsSpecifiedByCluster

DrsAutomationLevel      : AsSpecifiedByCluster

VMSwapfilePolicy        : Inherit

VMResourceConfiguration : CpuShares:Normal/4000 MemShares:Normal/81920

Name                    : GUESTNAME

CustomFields            : {[FA.GosAgent, ], [PnC.CustSpec, ], [PnC.Deployed, ],

                           [PnC.GroupID, ]...}

ExtensionData           : VMware.Vim.VirtualMachine

Id                      : VirtualMachine-vm-11351

Uid                     : /VIServer=NTLM\useradminuser@virtualcenter.serveror

                          .us:443/VirtualMachine=VirtualMachine-vm-11351/

I am at a loss, why would it attempt to join a domain before networking is setup?

Reply
0 Kudos
LucD
Leadership
Leadership

I suspect this might be a timing problem.

Can't you build in a While loop where you ping the IP address until it comes back with a reply ?


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

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

Luc, it is the script you collaborated with the OP to get working.

##########################################################

#

# Mark Jones 2/20/2012

# Version 2

#

##########################################################

#Prompt for domain username/password and local admin password

$username = read-host "Enter your domain admin username for customization"

$pass = Read-Host -AsSecureString "Enter your password"

$adminpass = Read-Host -AsSecureString "Enter local admin password"

#convert back to string

$pass = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass)

$pass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($pass)

$adminpass = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($adminpass)

$adminpass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($adminpass)

Connect-VIServer vcenter

$vmlist = Import-CSV vms.csv

foreach ($item in $vmlist) {

    # I like to map out my variables

    $template = $item.template

    $datastore = $item.datastore

    $vmhost = $item.vmhost

    $custspec = $item.custspec

    $vmname = $item.vmname

    $ipaddr = $item.ipaddress

    $subnet = $item.subnet

    $gateway = $item.gateway

    $pdns = $item.pdns

    $sdns = $item.sdns

    $vlan = $item.vlan

  $pass = $item.pass

  $adminpass = $item.adminpass

  $username = $item.username

       

    #Clone the templates

    New-VM -Name $vmname -template $template -Datastore $datastore -VMHost $vmhost -RunAsync

}

while (get-task -status running | Where-Object {$_.name -eq "clonevm_task"})

{

    sleep 20

}

foreach ($item in $vmlist) {

    $datastore = $item.datastore

    $vmhost = $item.vmhost

    $custspec = $item.custspec

    $ipaddr = $item.ipaddress

    $subnet = $item.subnet

    $gateway = $item.gateway

    $pdns = $item.pdns

    $sdns = $item.sdns

    $vlan = $item.vlan

    $vmname = $item.vmname

    $username = $item.username

    $pass = $item.pass

    $adminpass = $item.adminpass

   #set customization spec

   New-OSCustomizationSpec -spec $custspec -Name $vmname -type Persistent

   Set-OSCustomizationSpec -spec $vmname -AdminPassword $adminpass -DomainUsername $username -DomainPassword $pass -Confirm:$false

   Get-OSCustomizationSpec $vmname | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress $ipaddr -SubnetMask $subnet -DefaultGateway $gateway -Dns $pdns,$sdns

    

    #Set network label

    Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $vlan -Confirm:$false | Out-Null

    #set vm

    #Set-VM -VM $vmname -OSCustomizationSpec $vmname -NumCpu $cpu -MemoryMB $mem -Confirm:$false

 

    #Remove Cust Spec

    Remove-OSCustomizationSpec -CustomizationSpec $vmname -Confirm:$false

    #Start VM

    Start-VM -VM $vmname -Confirm:$false

}

Reply
0 Kudos
LucD
Leadership
Leadership

Did you check the logs in the guest (the ones I mentioned earlier in this thread) ?

Perhaps these can make it clearer what exactly is happening during the customisation.


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

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

No logs.  I get zero errors in output as that script stands, if I comment out the remove component, and check the custspec it creates for each one, the parameters are correct, nothing ever gets passed through to the VM other than changing the VM Network name from our DHCP subnet to a Production subnet.  IPs do not get set, it doesn't do anything, even though the powercli output I posted shows it clearly doing something.

Shouldn't the VM power on before the customization?

Reply
0 Kudos
LucD
Leadership
Leadership

I mean these logs inside the guest

c:\windows\temp\vmware-imc\*

c:\windows\setup-act.log

c:\windows\setup-err.log

c:\windows\debug\*

The customization will start when the VM is powered on, that's the Start-VM at the end of the script


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

Reply
0 Kudos
markdjones82
Expert
Expert

Luc, how can I get my output to show in HTML or proper formatting?  I tried copying as HTML but it doesn't seem to work like it used to

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
Reply
0 Kudos
LucD
Leadership
Leadership

See the updated procedure in Some ways to enter PowerCLI code under the new forum SW

PS: I removed that answer with the long HTML line


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

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

There is nothing new, no logs specifying what you posted. 

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

The debug directory has a PASSWD file, and it is blank.

The other file areas and/or names have nothing since the parent VM was finished building.

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

Does the customization spec already saved that I am calling with the script require:

NetBIOS Name

Enter a Name (Leaving this blank)

Use the Virtual Machine Name (tried this, doesn't work)

Enter a name in the deploy wizard (tried this, doesn't work)

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

I am using the script to build the customization specs and not delete them, power off the vm's, destroy them, and invoke with another script.

I am running out of time to debug this, and have to have the systems up tomorrow because I still have to deploy SQL server on 38 of them, make 4 web servers, and 5 terminal servers, and 2 domain controllers so on Friday I can do flex clone split operations to divest a single instance SQL server cluster with 800 databases to 38 SQL servers, and deploy the latest version of Citrix, and a Netscaler by 5 pm Friday.

Reply
0 Kudos
LucD
Leadership
Leadership

Can you give some more details on the environment in which you are trying to run the script ?

vSphere version, PowerCLI version ?

From where and how do you run the script (PowerCLI promp,Gui...) ?

Does the customizationspec you created work when you use it from the vSphere client ?


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

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

Vsphere 5.1 build 1157734

PowerCLI Version

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

   VMware vSphere PowerCLI 5.1 Release 2 build 1012425

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

Snapin Versions

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

   VMWare AutoDeploy PowerCLI Component 5.1 build 768137

   VMWare ImageBuilder PowerCLI Component 5.1 build 768137

   VMware License PowerCLI Component 5.1 build 669840

   VMware VDS PowerCLI Component 5.1 build 1012428

   VMware vSphere PowerCLI Component 5.1 build 1012428

Running script via powercli 32bit prompt

The script referenced in this thread is not working for me.

I am attempting to join Win2008R2 systems to a Windows 2003 domain.  I have the custspec putting in the IP, dns, subnet, gateway, and dns suffix for our environment

I ran the script to build the custom spec per machine, and then deleted the VM, and ran this:

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false

Connect-VIServer virtualcenter

New-VM -vmhost esxihost -Name GUEST -Template WIN2008R2-WITHSQL-TEMPLATE -Datastore NETAPP -OSCustomizationSpec GUEST

Start-VM -VM GUEST -Confirm:$false

Customizationspec is failing.  netpjoindomainonds: function exits with status of: 0x52e

I have tried:

user principal name, DOMAIN\username, and username for credentials

I have tried FQDN of the AD domain, and its netbios name

I'm really at a loss.  I've at least gotten it to set the IP, and change the DNS/Netbios name, but it will not join Active Directory.

Reply
0 Kudos
LucD
Leadership
Leadership

Those version all look ok, and you're using a supported OS on the guest.

The 0x52e on the domain join indicates a logon failure.

In which format did you specify the administrator account ? In the administrator@mydomain.whatever format ?


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

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

I have tried:

FQDN domain with UPN (user@fqdn)

FDQN domain with DOMAIN\user

NETBIOS domain with DOMAIN\user

NETBIOS domain with user

dcdiag /test:dns from both DC's passes

Message was edited by: BrianLBLESD

Reply
0 Kudos
LucD
Leadership
Leadership

And it always returns the 0x52e error ?

That is definitely a logon failure.

Is there anything in the Security eventlogs on your DCs ?

Or is the network net connected ? Could it be a 802.1x problem ? Is that VM allowed to connect to the network ?

Still find it strange that you don't have any logs of the customisation process.

The sysprep process that is driving this always produces some of these logs.


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

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

If i remove the fields in the csv for username, password, and adminpassword and rely on the input lines to trap the $pass $username and $adminpass it doesn't work at all

Set-OSCustomizationSpec : Cannot validate argument on parameter 'AdminPassword'

. The argument is null or empty. Supply an argument that is not null or empty a

nd then try the command again.

At C:\scripts\clonecustom.ps1:71 char:56

+    Set-OSCustomizationSpec -spec $vmname -AdminPassword <<<<  $adminpass -Dom

ainUsername $username -DomainPassword $pass -Confirm:$false

    + CategoryInfo          : InvalidData: (:) [Set-OSCustomizationSpec], Para

   meterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

   ation.ViCore.Cmdlets.Commands.SetCustomizationSpec

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

I'm using my account, it has all permissions.  it is not locked out, and I can manually join the machines to the domain.

Reply
0 Kudos
BrianLBLESD
Contributor
Contributor

It won't even login to the machine, even though the custspec says to do it 5 times.  I'm going to test it against another AD domain.

Reply
0 Kudos