VMware Cloud Community
LittleNickey
Enthusiast
Enthusiast
Jump to solution

New-VM with OSCustomizationSpec, Error "A specified parameter was not correct"

I am making a script where I read a CSV-file with parameters to deploy multiple VMs. Now I've added functionality to get it to do sysprep with the help of OSCustomizationSpec and when I tested it was working fine. After that I made some minor modifications, such as added "-ResourcePool" and some other things I can't quite remember unfortunately. Or at least I thought they were minor changes that should affect anything negatively, but when I now run it I get error "A specified parameter was not correct". I found this thread saying it was a bug in older version but that should've been fixed. I tried the workaround but I do get the same error still. The script runs fine when I remove the "-OSCustomizationSpec" parameter, but there seems to be nothing wrong with the file as I can manually deploy VMs with the OSCust file from the GUI and with the same templates. And as I said, it worked fine earlier when I used that parameter. Any ideas on which "parameter" that is incorrect?


PSVersion: 4.0

PowerCLI Version: VMware vSphere PowerCLI 5.5 Release 2 build 1671586


The script throws error:

New-VM : 2014-07-14 10:13:13    New-VM        The operation for the entity "Template" failed with the following message: "A specified parameter was not correct. spec.identity.userData.computerName"

At script.ps1:141 char:6

+                     New-VM -Template $Template `

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

    + CategoryInfo          : NotSpecified: (:) [New-VM], InvalidArgument

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

And in the GUI:

Task: Clone virtual machine

Status: A specified parameter was not correct. spec.identity.userData.computerName


Below is the part of the script regarding New-VM and OSCust:

New-OSCustomizationSpec -Name "PowerCLI" `

  -AdminPassword "password" `

  -AutoLogonCount 0 `

  -ChangeSID:$True `

  -Confirm:$False `

  -DeleteAccounts:$False `

  -Description "Only for use with PowerCLI." `

  -FullName $Customer `

  -LicenseMode "NotSpecified" `

  -NamingScheme "Fixed" `

  -NamingPrefix $VMName `

  -OrgName $Customer `

  -OSType "Windows" `

  -TimeZone 110 `

  -Type "Persistent" `

  -Workgroup "WORKGROUP" | Out-Null

New-VM -Template $Template `

  -Name $VMName `

  -VMHost $VMHost `

  -Datastore $Datastore `

  -Location $Folder `

  -ResourcePool $ResourcePool `

  -OSCustomizationSpec PowerCLI | Out-Null

-- Oskar
Reply
0 Kudos
1 Solution

Accepted Solutions
LittleNickey
Enthusiast
Enthusiast
Jump to solution

Damn I'm stupid, I do believe it is Monday today! :smileyangry:

Just like you figured, it has something to do with the computer name.

"spec.identity.userData.computerName"

Or more specifically "-NamingPrefix $row.Name". Since this is the NETBIOS name which may only contain letters, numbers and hyphens.

As previously stated I'm stupid. I had $row.Name defined as "nickey_test01", and underscore isn't an allowed character. This explains why the script worked earlier when I created customer VM's. Guess I'll have to build in more checks in the script, to idiot proof it.

Cheers for the help Luc.

-- Oskar

View solution in original post

15 Replies
LucD
Leadership
Leadership
Jump to solution

The Template parameter expects a String with the name of the template, or a Template object (as returned by Get-Template).

According to the error the value you pass is neither of these.

How did you populate the $Template variable ?


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

LittleNickey
Enthusiast
Enthusiast
Jump to solution

Thanks Luc for the quick reply as usual.

I too figured it might have something to do with that, but when I try fetching the template manually it works fine...

Here is how the script populates $Template:

$Filename = ".\NewVM.csv"

foreach($row in Import-Csv $Filename -UseCulture){

(...)

  $Template = Get-Template -Name $row.Template

  ## And some more variables related to the Template

  $ViewTemplate = Get-View -id $Template.id

  $TemplateCPU = $ViewTemplate.config.hardware.numcpu

  $TemplateMem = ($ViewTemplate.config.hardware.memorymb / 1024)

  $TemplateOS = $ViewTemplate.config.guestid

  $DiskSize = Get-HardDisk -Template $Template | Select-Object -ExpandProperty CapacityGB | Measure-Object -Sum | Select-Object -ExpandProperty Sum

  $ResourcePool = Get-Cluster $row.Cluster | Get-ResourcePool $row.ResourcePool

(...)

}

When running just the above code and not the rest of the script PowerCLI fetches all the parameters correctly and finds the Template.

-- Oskar
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I suspect you might be overwriting the content of the $Template variable somewhere.

You could display the content of the $Template variable just before you do the New-VM.

And perhaps also check the type.

Write-Output $Template

$Template.GetType()

$Template | Get-Member


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

Reply
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

It only gives me output for 1 template:


## Write-Output $Template

Name

----

WIN2012_R2_STD_template

## $Template.GetType()

Module                     : VMware.VimAutomation.ViCore.Impl.dll

Assembly                   : VMware.VimAutomation.ViCore.Impl, Version=5.5.0.0, Culture=neutral, PublicKeyToken=null

TypeHandle                 : System.RuntimeTypeHandle

DeclaringMethod            :

BaseType                   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl

UnderlyingSystemType       : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

FullName                   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

AssemblyQualifiedName      : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl, VMware.VimAutomation.ViCore.Impl, Version=5.5.0.0, Culture=neutral, PublicKeyToken=null

Namespace                  : VMware.VimAutomation.ViCore.Impl.V1.Inventory

GUID                       : bdfb3c64-a617-3970-850f-f51d784bee4e

IsEnum                     : False

GenericParameterAttributes :

IsSecurityCritical         : False

IsSecuritySafeCritical     : False

IsSecurityTransparent      : True

IsGenericTypeDefinition    : False

IsGenericParameter         : False

GenericParameterPosition   :

IsGenericType              : False

IsConstructedGenericType   : False

ContainsGenericParameters  : False

StructLayoutAttribute      : System.Runtime.InteropServices.StructLayoutAttribute

Name                       : TemplateImpl

MemberType                 : TypeInfo

DeclaringType              :

ReflectedType              :

MetadataToken              : 33554721

GenericTypeParameters      : {}

DeclaredConstructors       : {Void .cctor(), Void .ctor(System.String), Void .c

                             tor(System.String, System.String), Void .ctor(Syst

                             em.String, System.String, System.String, System.St

                             ring, System.String[], VMware.VimAutomation.ViCore

                             .Impl.V1.VimClient, System.Collections.Generic.Dic

                             tionary`2[System.String,System.String], VMware.Vim

                             .VirtualMachine)}

DeclaredEvents             : {}

DeclaredFields             : {_isInitialized, _hostId, _folderId, _datastoreIdList...}

DeclaredMembers            : {VMware.VimAutomation.ViCore.Impl.V1.Inventory.Tem

                             plateImpl Create(VMware.Vim.ManagedObjectReference

                             , VMware.VimAutomation.ViCore.Impl.V1.VimClient, S

                             ystem.Collections.Generic.Dictionary`2[System.Stri

                             ng,System.Object], System.Collections.Generic.Dict

                             ionary`2[System.String,System.String], System.Obje

                             ct), VMware.VimAutomation.ViCore.Impl.V1.ManagedCl

                             assInfo get_ClassInfo(), System.String VMware.VimA

                             utomation.ViCore.Interop.V1.Inventory.TemplateInte

                             rop.get_HostId(), System.String get_FolderId()...}

DeclaredMethods            : {VMware.VimAutomation.ViCore.Impl.V1.Inventory.Tem

                             plateImpl Create(VMware.Vim.ManagedObjectReference

                             , VMware.VimAutomation.ViCore.Impl.V1.VimClient, S

                             ystem.Collections.Generic.Dictionary`2[System.Stri

                             ng,System.Object], System.Collections.Generic.Dict

                             ionary`2[System.String,System.String], System.Obje

                             ct), VMware.VimAutomation.ViCore.Impl.V1.ManagedCl

                             assInfo get_ClassInfo(), System.String VMware.VimA

                             utomation.ViCore.Interop.V1.Inventory.TemplateInte

                             rop.get_HostId(), System.String get_FolderId()...}

DeclaredNestedTypes        : {}

DeclaredProperties         : {VMware.VimAutomation.ViCore.Impl.V1.ManagedClassI

                             nfo ClassInfo, System.String VMware.VimAutomation.

                             ViCore.Interop.V1.Inventory.TemplateInterop.HostId

                             , System.String FolderId, System.String[] Datastor

                             eIdList}

ImplementedInterfaces      : {VMware.VimAutomation.Sdk.Types.V1.VIObject, VMwar

                             e.VimAutomation.Sdk.Types.V1.VIObjectCore, VMware.

                             VimAutomation.Sdk.Types.V1.NamedObject, VMware.Vim

                             Automation.ViCore.Interop.V1.VIObjectInterop...}

TypeInitializer            : Void .cctor()

IsNested                   : False

Attributes                 : AutoLayout, AnsiClass, Class, Public

IsVisible                  : True

IsNotPublic                : False

IsPublic                   : True

IsNestedPublic             : False

IsNestedPrivate            : False

IsNestedFamily             : False

IsNestedAssembly           : False

IsNestedFamANDAssem        : False

IsNestedFamORAssem         : False

IsAutoLayout               : True

IsLayoutSequential         : False

IsExplicitLayout           : False

IsClass                    : True

IsInterface                : False

IsValueType                : False

IsAbstract                 : False

IsSealed                   : False

IsSpecialName              : False

IsImport                   : False

IsSerializable             : False

IsAnsiClass                : True

IsUnicodeClass             : False

IsAutoClass                : False

IsArray                    : False

IsByRef                    : False

IsPointer                  : False

IsPrimitive                : False

IsCOMObject                : False

HasElementType             : False

IsContextful               : False

IsMarshalByRef             : False

GenericTypeArguments       : {}

CustomAttributes           : {}

## $Template | Get-Member

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : ConvertToVersion

MemberType : Method

Definition : T VersionedObjectInterop.ConvertToVersion[T]()

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : Equals

MemberType : Method

Definition : bool Equals(System.Object obj)

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : GetHashCode

MemberType : Method

Definition : int GetHashCode()

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : GetType

MemberType : Method

Definition : type GetType()

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : IsConvertableTo

MemberType : Method

Definition : bool VersionedObjectInterop.IsConvertableTo(type type)

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : LockUpdates

MemberType : Method

Definition : void ExtensionData.LockUpdates()

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : ToString

MemberType : Method

Definition : string ToString()

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : UnlockUpdates

MemberType : Method

Definition : void ExtensionData.UnlockUpdates()

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : Client

MemberType : Property

Definition : VMware.VimAutomation.ViCore.Interop.V1.VIAutomation Client {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : CustomFields

MemberType : Property

Definition : System.Collections.Generic.IDictionary[string,string] CustomFields

              {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : DatastoreIdList

MemberType : Property

Definition : string[] DatastoreIdList {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : ExtensionData

MemberType : Property

Definition : System.Object ExtensionData {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : FolderId

MemberType : Property

Definition : string FolderId {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : HostId

MemberType : Property

Definition : string HostId {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : Id

MemberType : Property

Definition : string Id {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : Name

MemberType : Property

Definition : string Name {get;}

TypeName   : VMware.VimAutomation.ViCore.Impl.V1.Inventory.TemplateImpl

Name       : Uid

MemberType : Property

Definition : string Uid {get;}

Then the error is thrown:

New-VM : 2014-07-14 11:58:31    New-VM        The operation for the entity "WIN2012_R2_STD_template" failed with the following message: "A specified parameter was not correct. spec.identity.userData.computerName"

At script.ps1:146 char:6

+                     New-VM -Template $Template `

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

    + CategoryInfo          : NotSpecified: (:) [New-VM], InvalidArgument

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

-- Oskar
Reply
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

I added the commands in between New-OSCustomizationSpec and New-VM.

-- Oskar
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

In the OSCustomizationSpec your are using, called PowerCLI, how did you define the Computer Name entry ?

Is that "Use the virtual machine name" ?


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

LittleNickey
Enthusiast
Enthusiast
Jump to solution

No, it's "Enter a name".

As far as I understand from New-OSCustomizationSpec, -NamingPrefix (together with "-NamingScheme = Fixed") populates this field.

From the help: "If the "Fixed" naming scheme is used, NamingPrefix should indicate the name of the virtual machine."

The reason I use this is so that I can have a different OS hostname than the display name in vSphere because we set a prefix on the display name in vSphere depending on which customer the VM is regarding.

So in my script it's actually:

  -NamingScheme "Fixed" `

  -NamingPrefix $row.Name `

that sets the OS hostname and:

New-VM -Template $Template `

  -Name $VMName `

that sets the vSphere display name.

-- Oskar
Reply
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

Here is the content of the OSCust File:

C:\> Get-OSCustomizationSpec "PowerCLI" | select *

Name                  : PowerCLI

Type                  : Persistent

ServerId              : /VIServer=user@domain.com:443/

Server                : vcenter@domain.com

LastUpdate            : 2014-07-14 11:57:49

DomainAdminUsername   :

DomainUsername        :

Description           : Only for use with PowerCLI.

AutoLogonCount        :

ChangeSid             : True

DeleteAccounts        : False

DnsServer             :

DnsSuffix             :

Domain                :

FullName              : Customer

GuiRunOnce            :

NamingPrefix          : nickey_test01

NamingScheme          : Fixed

OrgName               : Customer

OSType                : Windows

ProductKey            :

TimeZone              : W. Europe

Workgroup             : WORKGROUP

LicenseMode           : NotSpecified

LicenseMaxConnections :

EncryptionKey         : {48, -126, 1, -27...}

ExtensionData         : VMware.Vim.CustomizationSpecItem

Id                    : PowerCLI

Uid                   : /VIServer=user@domain.com:443/OSCustomizationSpec=PowerCLI/

Client                : VMware.VimAutomation.ViCore.Impl.V1.VimClient

AdminPassword         : raTgAGIwbo8D9MnhgqCKiN8+XnkcyTTYBnhRNOdR6kGq+4W6wSrcGqbzS51BZBg8c7IEZ3z9sg==

DomainAdminPassword   :

DomainPassword        :

-- Oskar
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is correct, but that also means you manipulate the OSCustomizationSpec in your script.

It looks as if something goes wrong there.

There might be some clues in the vpxd.log on the vCenter


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

Reply
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

I'm no expert in log diving Smiley Happy Any pointers what to look for?

-- Oskar
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Well, the New-VM cmdlet will most probably call a CloneVM_Task, and then there is the timestamp you can use to locate the entry.

If there is anything in the vpxd log, you should see a complete dump of the object(s) that is (were) passed to the method.


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

Reply
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

Damn I'm stupid, I do believe it is Monday today! :smileyangry:

Just like you figured, it has something to do with the computer name.

"spec.identity.userData.computerName"

Or more specifically "-NamingPrefix $row.Name". Since this is the NETBIOS name which may only contain letters, numbers and hyphens.

As previously stated I'm stupid. I had $row.Name defined as "nickey_test01", and underscore isn't an allowed character. This explains why the script worked earlier when I created customer VM's. Guess I'll have to build in more checks in the script, to idiot proof it.

Cheers for the help Luc.

-- Oskar
LucD
Leadership
Leadership
Jump to solution

Glad you figured it out :smileycool:


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

Reply
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

Jeah, thanks - so am I. Next time I post a question here I'll just start with "I guess I'm being stupid again, but..." Smiley Wink

-- Oskar
Reply
0 Kudos
AmbroseKTal
Contributor
Contributor
Jump to solution

@LittleNickey It's been almost exactly 7 years since you posted this, but you just saved my sanity today!  Thank you. 

Stupid NetBIOS names.  I looked at the underscores, and thought there was no way that was the issue!  It's Windows! They don't care about silly things like that.....

Reply
0 Kudos