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
} #BeginProcess {
#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)
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
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
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.
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
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.
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
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
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)
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
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
} #BeginProcess {
#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
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
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)
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
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
Sorry, i got it now. You want me to avoid csv file and move that one Vm alone.
Will try it.
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)
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
Yes!!!!!!!!
It works perfect now. Thanks so much Luc.
You are a champion.
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.
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 times