VMware Cloud Community
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Thin migration script error

Hi,

I'm using the below given script to migrate the list of VM's given in csv file to specified datastore. This script runs fine on many VM's but suddenly stops on certain VM's with the error given below. But if i manually migrate that particular VM using "Migrate" option and by selecting "thin" i can sucessfully convert it. The problem is that when it breaks on particular VM, the operation stops and for other VM's have to start the script again.

Any help?

Script,

Connect-viserver <vcserver>
function Move-VMThin {
param(
[parameter(ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[System.String]$VM,
[ValidateNotNullOrEmpty()]
[System.String]$Datastore
)

Begin {
  #Nothing Necessary to process
} #Begin

Process {
  #Prepare Migration info, uses .NET API to specify a transformation to thin disk
  $vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM"}
  $dsView = Get-View -ViewType Datastore -Filter @{"Name" = "$Datastore"}

  #Abort Migration if free space on destination datastore is less than 50GB
  if (($dsView.info.freespace / 1GB) -lt 50) {Throw "Move-ThinVM ERROR: Destination Datastore $Datastore has less than 50GB of free space. This script requires at least 50GB of free space for safety. Please free up space or use the VMWare Client to perform this Migration"}

  #Prepare VM Relocation Specificatoin
  $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
  $spec.datastore = $dsView.MoRef
  $spec.transform = "sparse"

  #Perform Migration
  $vmView.RelocateVM($spec, $null)
} #Process
}
$ds = Get-Datastore (Read-Host "enter the name of the datastore")
Import-Csv "c:\thin.csv" | %{
Get-VM $_.vmname | Move-VMThin -Datastore $ds }


Error,

Method invocation failed because [System.Object[]] doesn't contain a method named 'RelocateVM'.

At :line:29 char:20

+ $vmView.RelocateVM <<<< ($spec, $null)

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Ah, now all is clear.

The -Filter for Get-View uses RegEx to compare the values.

So a value of for example "abc" will compare postive on "abc" and "abcd".

The solution is to say that there shouldn't be anymore characters after the name.

Replace the line

$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM"}

with

$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM$"}

The $ at the end says that "abc" should be the last characters in the name.


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

View solution in original post

Reply
0 Kudos
19 Replies
LucD
Leadership
Leadership
Jump to solution

Could it be that you also have some VMs that have RegEx meta-characters in their name ?

See the [regex]::Escape solution I gave in Re: Move-VMThin Function (Powercli Thick to Thin svMotion)


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

sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

I don't have any special characters in VM names. All Vm names are of 13 characters of Letters and numbers, even without a space inbetween.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Another possible cause is that you have more than 1 hit with the filter.

For example: the filter VM1 will return VM1 but also VM11.

In that case the result will be an array, which doesn't have the RelocateVM method of course.

Test with the following.

Import-Csv "c:\thin.csv" | %{
    $vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$_.vmname"}
    Write-Host $_.vmname $vmView.Count
}

If you have entries that show a count greater than 1, then this is the problem.

The solution is simple, just specify that the mask in the filter should stop after the name.

Something like this

$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM$"}


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

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

I tested this. I had 5 VM's in the thin.csv file. and when i run the script, only those 5 vm names are printed as output.

This line Write-Host $_.vmname $vmView.Count has two values to output, $_.vmname and $vmview.count. But i get only the vmnames in the output and do not get any count value printed as output.

Please suggest.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That means the $vmView is not an array and consequently doesn't have a Count property.

That also means you have no multiple hits for 1 or more specific names.

Which is strange, since in the error message System.Object[] seems to indicate it's an array.


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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I completely overlooked this, but the function requires a string with the name of the VM, not the VM object.

Can you do the call as follows

$ds = Get-Datastore (Read-Host "enter the name of the datastore")
Import-Csv "c:\thin.csv" | %{
   Move-VMThin -VM $_.vmname -Datastore $ds
}


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

sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

I tried this now with VM name as string, but again it's giving the same error. Out of the 5 VM's which i have in the thin.csv file now, the first VM in the queue is giving the problem. If i take it out of the list again few Vm's will migrate then anyone VM will give problem.

Method invocation failed because [System.Object[]] doesn't contain a method named 'RelocateVM'.

At :line:29 char:20

+ $vmView.RelocateVM <<<< ($spec, $null)

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Strange, would you mind attaching the updated script you are using and the CSV file your are using ?


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

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc, this is the exact script i'm using,

Connect-viserver xxxxxxxxxxx -User xxxxx\xxxxxxxx
function Move-VMThin {
param(
[parameter(ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[System.String]$VM,
[ValidateNotNullOrEmpty()]
[System.String]$Datastore
)

Begin {
  #Nothing Necessary to process
} #Begin

Process {
  #Prepare Migration info, uses .NET API to specify a transformation to thin disk
  $vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM"}
  $dsView = Get-View -ViewType Datastore -Filter @{"Name" = "$Datastore"}

  #Abort Migration if free space on destination datastore is less than 50GB
  if (($dsView.info.freespace / 1GB) -lt 50) {Throw "Move-ThinVM ERROR: Destination Datastore $Datastore has less than 50GB of free space. This script requires at least 50GB of free space for safety. Please free up space or use the VMWare Client to perform this Migration"}

  #Prepare VM Relocation Specificatoin
  $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
  $spec.datastore = $dsView.MoRef
  $spec.transform = "sparse"

  #Perform Migration
  $vmView.RelocateVM($spec, $null)
} #Process
}
$ds = Get-Datastore (Read-Host "enter the name of the datastore")
Import-Csv "c:\thin.csv" | %{
Get-VM $_.vmname | Move-VMThin -Datastore $ds }


And this is the CSV file i use, sorry but not able give exact names,

vmname

provm123epp12

ultvm234ipp300

provm123ipp246

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That looks all ok and works in my environment.

One more test, can you add a line before the RelocateVM call.

Like this

...
$vmView.GetType() | Select * 
$vmView.RelocateVM($spec, $null)

Perhaps that will help to shed some light 🙂


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

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

Please find the output below after adding that line of code. i just masked that publickeytoken since really i don't know what is that :smileylaugh:

Module : CommonLanguageRuntimeLibrary

Assembly : mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx

TypeHandle : System.RuntimeTypeHandle

DeclaringMethod :

BaseType : System.Array

UnderlyingSystemType : System.Object[]

FullName : System.Object[]

AssemblyQualifiedName : System.Object[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxx

Namespace : System

GUID : 00000000-0000-0000-0000-000000000000

GenericParameterAttributes :

IsGenericTypeDefinition : False

IsGenericParameter : False

GenericParameterPosition :

IsGenericType : False

ContainsGenericParameters : False

StructLayoutAttribute :

Name : Object[]

MemberType : TypeInfo

DeclaringType :

ReflectedType :

MetadataToken : xxxxxxxx

TypeInitializer :

IsNested : False

Attributes : AutoLayout, AnsiClass, Class, Public, Sealed, Serializable

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 : True

IsEnum : False

IsSpecialName : False

IsImport : False

IsSerializable : True

IsAnsiClass : True

IsUnicodeClass : False

IsAutoClass : False

IsArray : True

IsByRef : False

IsPointer : False

IsPrimitive : False

IsCOMObject : False

HasElementType : True

IsContextful : False

IsMarshalByRef : False

Method invocation failed because [System.Object[]] doesn't contain a method named 'RelocateVM'.

At :line:30 char:20

+ $vmView.RelocateVM <<<< ($spec, $null)

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You're definitely getting an array instead of a single VirtualMachine object in the Move-VMThin function.

The lines

IsArray : True

and

Name : Object[]

confirm this.

If you just do

$ds = Get-Datastore (Read-Host "enter the name of the datastore")

Get-VM provm123epp12 | Move-VMThin -Datastore $ds

it should work. Is that correct ?


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

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

Bit confused. Do you want me to run Move-VM without the function Move-VMthin?

Like this,

$ds = Get-Datastore (Read-Host "enter the name of the datastore")

Get-VM provm123epp12 | Move-VM -Datastore $ds

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Sorry, i got it now. You want me to avoid csv file and move that one Vm alone.

Will try it.

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

Interestingly,  this does NOT work. Again "IsArray = TRUE".

I commented the csv lines like this and added VM name directly,

$ds= Get-Datastore (Read-Host "enter the name of the datastore")
#Import-Csv "c:\thin.csv" | %
{Get-VM provm123epp12 | Move-VMThin -Datastore $ds #}

One more thing, we have one more vm named provm123epp127. Just in the same pattren with last digits as 127. But as we tested earlier if we print $vmview.count, that doesnot give any values and returned only the vmnames in csv.

error message,

Module : CommonLanguageRuntimeLibrary

Assembly : mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxx

TypeHandle : System.RuntimeTypeHandle

DeclaringMethod :

BaseType : System.Array

UnderlyingSystemType : System.Object[]

FullName : System.Object[]

AssemblyQualifiedName : System.Object[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxx

Namespace : System

GUID : 00000000-0000-0000-0000-000000000000

GenericParameterAttributes :

IsGenericTypeDefinition : False

IsGenericParameter : False

GenericParameterPosition :

IsGenericType : False

ContainsGenericParameters : False

StructLayoutAttribute :

Name : Object[]

MemberType : TypeInfo

DeclaringType :

ReflectedType :

MetadataToken : xxxxxxxx

TypeInitializer :

IsNested : False

Attributes : AutoLayout, AnsiClass, Class, Public, Sealed, Serializable

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 : True

IsEnum : False

IsSpecialName : False

IsImport : False

IsSerializable : True

IsAnsiClass : True

IsUnicodeClass : False

IsAutoClass : False

IsArray : True

IsByRef : False

IsPointer : False

IsPrimitive : False

IsCOMObject : False

HasElementType : True

IsContextful : False

IsMarshalByRef : False

Method invocation failed because [System.Object[]] doesn't contain a method named 'RelocateVM'.

At :line:30 char:20

+ $vmView.RelocateVM <<<< ($spec, $null)

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ah, now all is clear.

The -Filter for Get-View uses RegEx to compare the values.

So a value of for example "abc" will compare postive on "abc" and "abcd".

The solution is to say that there shouldn't be anymore characters after the name.

Replace the line

$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM"}

with

$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM$"}

The $ at the end says that "abc" should be the last characters in the name.


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

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Yes!!!!!!!!

It works perfect now. Thanks so much Luc. 

You are a champion. Smiley Happy

Reply
0 Kudos
sureshadmin2011
Enthusiast
Enthusiast
Jump to solution

Luc,

How do i include a -runasync parameter to the script, so that max concurrent migration tasks are 2 at a time? Currently it runs one at a time which is very slow.

Reply
0 Kudos
celavey
Enthusiast
Enthusiast
Jump to solution

same problem here. im lucky to have read this posts. thanks to you LucD. my VM is up and working now. got this problem with migration error before a lot of timeshttp://imagicon.info/cat/5-59/1.gif

Reply
0 Kudos