VMware Cloud Community
blackh0le
Contributor
Contributor

Recreating existing VMs with powercli

I am trying to recreate existing vms with below script but getting errors.  I just need to rename the old vm and create a new one from a new template and set its windows IP config and vm portgroup.

$csv=Import-CSV respintest.csv

$Template = "template-win7-1547"

$OSCustSpec = "specname"

$datastore = "storename"

foreach($vm in $csv){

Get-VM $($vm.oldname) |

Set-vm -name $($vm.newname) -confirm:$false |

Get-OSCustomizationSpec -name $OSCustSpec | Get-OSCustomizationNICMapping | Set-OSCustomizationNICMapping -IPMode UseStaticIP -IPAddress $($vm.vmip) -SubNetMask $($vm.subnetmask) -DefaultGateway $($vm.defaultgateway) -dns $($vm.dns)

New-VM -VMHost $($vm.vhs) -Name $($vm.oldname) -Template $Template -Datastore $datastore  -OSCustomizationSpec $OSCustSpec |

Set-NetworkAdapter -NetworkName $($vm.portgroup)

}

csv contains below coloumns

oldnamenewnamevmipsubnetmaskdefaultgatewaydnsvhsportgroup

Getting below error:

Get-OSCustomizationSpec : The input object cannot be bound to any parameters for the command either because

the command does not take pipeline input or the input and its properties do not match any of the parameters

that take pipeline input.

At C:\Respin_csv.ps1:9 char:2

+  Get-OSCustomizationSpec -name $OSCustSpec | Get-OSCustomizationNICMa ...

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

    + CategoryInfo          : InvalidArgument: (01sbx:PSObject) [Get-OSCustomizationSpec], ParameterBindingE

   xception

    + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetOSCustomiz

   ationSpec

0 Kudos
10 Replies
LucD
Leadership
Leadership

You seem to be piping the object returned by Set-VM to the Get-OSCustomizationSpec cmdlet.

I'm afraid that cmdlet doesn't take pipeline parameters, and it doesn't take a VirtualMachine object either


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

0 Kudos
blackh0le
Contributor
Contributor

$csv=Import-CSV respintest.csv

$Template = "templatename"

$OSCustSpec = "specname"

$datastore = "storename"

Get-OSCustomizationSpec -name $OSCustSpec | Get-OSCustomizationNICMapping | Set-OSCustomizationNICMapping -IPMode UseStaticIP -IPAddress $($vm.vmip) -SubNetMask $($vm.subnetmask) -DefaultGateway $($vm.defaultgateway) -dns $($vm.dns)

foreach($vm in $csv){

Get-Cluster clustername | Get-VM $($vm.oldname) | Set-vm -name $($vm.newname) -confirm:$false

New-VM -VMHost $($vm.vhs) -Name $($vm.oldname) -Template $Template -Datastore $datastore -OSCustomizationSpec $OSCustSpec

Get-NetworkAdapter -VM $($vm.oldname) | Set-NetworkAdapter -Portgroup $($vm.portgroup) -confirm:$false

}

I got the VM deployed with the above edit, but with issues getting below error on OScustmisationspec:

New-VM : 2/21/2018 6:17:48 PM    New-VM        The operation for the entity "templatename" failed with the following message: "Cannot complete customization."

At C:\Respin_csv.ps1:9 char:2

+  New-VM -VMHost $($vm.vhs) -Name $($vm.oldname) -Template $Template - ...

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

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

    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.Vim

   Automation.ViCore.Cmdlets.Commands.NewVM

Also, the OscustomisationSpec is updated everytime with the new IP config.  How do I stop that ??Will

Get-OSCustomizationSpec -name $OSCustSpec -type NonPersistent

Work ???

0 Kudos
LucD
Leadership
Leadership

You can make a copy of the OSCustomizationSpec, and work with that copy.

That way the original is not changed.

I would advise to have a look at the series on OSCustomization Dimitar did, start with Working with Customization Specifications in PowerCLI Part 1

On the error, unfortunately your screenshot seems to be missing exactly the part of the message that could have given more clues.


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

0 Kudos
blackh0le
Contributor
Contributor

Ok, I get your point about the OSCustomisationSpec.

This is what the error looks like and I dont understand at what point it exactly fails and why.

New-VM : 2/21/2018 6:17:48 PM    New-VM        The operation for the entity "mds-template-1547" failed with

the following message: "Cannot complete customization."

At C:\Respin_csv.ps1:9 char:2

+  New-VM -VMHost $($vm.vhs) -Name $($vm.oldname) -Template $Template - ...

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

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

    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.Vim

   Automation.ViCore.Cmdlets.Commands.NewVM

0 Kudos
LucD
Leadership
Leadership

That seems to say that something is wrong with your OSCustomizationSpec when applied on the guest OS in the template.

For eaxmple, is the Template a Windows version, and did you spceify the ChangeSid option in the OSCustomizationSPec?

You will need to give more details:

  • what is in the OSCustomizationSpec? A Get-OSCustomizationSpec -Name <yourname> | Select * would help
  • What guest OS is the template?
  • which vSphere version are you running this against?
  • Which PowerCLI version are you using?


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

0 Kudos
blackh0le
Contributor
Contributor

Template is windows.

ChangeSID is true

Only thing I have setup in the OSCustomizationSpec is Hostname (netbios option) and IP (to be prompted with netmask and 1 DNS entry filled).  Also the admin password is blank and initial login is passwordless.

Name                  : NAME

Type                  : Persistent

ServerId              : /VIServer=vsphere.local\administrator@vcenter.domain.com:443/

Server                : vcenter.domain.com

LastUpdate            : 2/21/2018 7:34:41 PM

DomainAdminUsername   :

DomainUsername        :

Description           :

AutoLogonCount        : 2

ChangeSid             : True

DeleteAccounts        : False

DnsServer             :

DnsSuffix             :

Domain                :

FullName              : Somename

GuiRunOnce            :

NamingPrefix          : test-win7

NamingScheme          : Fixed

OrgName               : somecomapany

OSType                : Windows

ProductKey            :

TimeZone              :

Workgroup             : WORKGROUP

LicenseMode           : NotSpecified

LicenseMaxConnections :

EncryptionKey         : {48, -126, 4, 14...}

ExtensionData         : VMware.Vim.CustomizationSpecItem

Id                    : NAME

Uid                   : /VIServer=vsphere.local\administrator@vcenter.domain.com:443/OSCustomizationS

                        pec=NAME/

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

AdminPassword         :

DomainAdminPassword   :

DomainPassword        :

0 Kudos
LucD
Leadership
Leadership

That looks ok at first sight.

Do you have that with every OSCustomizationSpec you make? Can you perhaps try with one?

Is there any further indication of the error in the vpxd log?


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

0 Kudos
blackh0le
Contributor
Contributor

Blank Admin password is not allowed and was the cause of this issue.

This is what I got working

foreach($vm in $csv){

# Get the OS CustomizationSpec and clone

$OSCusSpec = Get-OSCustomizationSpec -Name SpecName | New-OSCustomizationSpec -Name 'temp1' -Type NonPersistent

# Get VM from CSV file and Rename as "old"

Get-Cluster $cluster | Get-VM $($vm.oldname) | Set-vm -name $($vm.newname) -confirm:$false

#Update temp Spec with IP information

Get-OSCustomizationNICMapping -OSCustomizationSpec temp1 | Set-OSCustomizationNICMapping -IPMode UseStaticIP -IPAddress $($vm.vmip) -SubNetMask $($vm.subnetmask) -DefaultGateway $($vm.defaultgateway) -dns $($vm.dns)

#Get updated Spec

$OSCusSpec = Get-OSCustomizationSpec -Name 'temp1'

# Create New VM with Old VM name, template and custom IP spec.

New-VM -VMHost $($vm.vhs) -Name $($vm.oldname) -Template $Template -Datastore $datastore -OSCustomizationSpec $OSCusSpec

# Assign the correct Portgroup as per CSv value

Get-NetworkAdapter -VM $($vm.oldname) | Set-NetworkAdapter -Portgroup $($vm.portgroup) -confirm:$false

# start VM

Start-VM -VM $($vm.oldname)

# Remove the temp Customisation Spec

Remove-OSCustomizationSpec $OSCusSpec -Confirm:$false

}

There is one issue though.  I also want to change the IP of old VMs to blank or something, so they dont conflict with the new one (We need to retain this VMs for some days before deletion).

is it possible to apply OSCustomizationSpec to an existing VM and set their IP to blank??

0 Kudos
LucD
Leadership
Leadership

Not sure if a blank IP address is accepted, but why don't you use an APIPA address instead?
That should in theory effectively take away network connectivity, unless you are using one of those actively.


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

0 Kudos
blackh0le
Contributor
Contributor

Ok This is as far as could get today.

0.0.0.0 Ip works, only netmask needs to be valid and I used 255.255.255.0.

Also, VMtools need to be updated on the VMs for the customization to work.  So I am doing

$csv=Import-CSV respintest.csv

foreach($vm in $csv){

Update-Tools -VM $($vm.oldname) -RunAsync

}

and then running the actual respin script.

0 Kudos