Hello,
I'm just starting my learning journey in scripting at Powercli and I'm currently writing one to move VMs from anywhere at the Datacenter level to a specific folder inside the same Datacenter that matches the "Value" of a specific custom attribute, at the VM. The idea is to run this script once and a while to sort the VMs at the correct folder based on the VM Custom Attributes field.
I have many Datacenter inside the same vCenter and each Datacenter has the same structure of folders (i.g. production, development, infrastructure ) The idea is to move the VM for the specific folder set the Custom Attribute and if the "Value" is empty or does not match whit any folder name it should move the VM to the "Discovered virtual machines" folder. I have tried some functions from LucD and It gave some good ideas, but I could not implement it well.
When I run the script for singles machines it seems to work, but when the CSV file has a more than one VM of fields it behavior unexpectedly. I'm sure my script is full of mistakes, but I'm trying.
get-vm | get-annotation -customattribute "VM Folder" | Select-Object annotatedentity, value | Export-Csv -Path C:\Users\mhops\Documents\movevms\attributes.csv –NoTypeInformation
Import-Csv C:\Users\mhops\Documents\movevms\attributes.csv -UseCulture | %{
$vm = Get-VM -Name $_.AnnotatedEntity | Select-Object Name
$folder = Get-Folder -Name $_.Value
$dc = Get-View -ViewType VirtualMachine -filter @{ "name" = $vm.Name} | Select-Object -Property Name,
@{ Label = "Datacenter"; Expression = { (Get-view (Get-View (Get-view $_.parent).parent).Parent).name } } | Select-Object Datacenter
$path = Get-Datacenter -Name $dc.Datacenter | Get-Folder -Name $folder
$pathdefault = Get-Datacenter -Name $dc.Datacenter | Get-Folder -Name "Discovered virtual machine"
if (!$folder.Value) {
Move-VM -VM $vm.Name -InventoryLocation $pathdefault
}
else {
Move-VM -VM $vm.Name -InventoryLocation $path
}
}
Thanks for your help
Try like this
Select-Object @{N='VM';E={$vm.Name}}, Value |
Export-Csv -Path C:\Users\mhops\Documents\movevms\attributes.csv –NoTypeInformation
Import-Csv C:\Users\mhops\Documents\movevms\attributes.csv -UseCulture | %{
$vm = Get-VM -Name $_.VM
$dc = Get-Datacenter -VM $vm
if($_.Value -ne ''){
$path = Get-Folder -Name $_.Value -Location $dc
if(-not $path){
$path = Get-Folder -Name 'Discovered virtual machine' -Location $dc
}
}
else{
$path = Get-Folder -Name 'Discovered virtual machine' -Location $dc
}
if ($vm.Folder.Name -ne $path.Name) {
Move-VM -VM $vm -InventoryLocation $path -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try something like this.
This does not change the Custom Attribute, only moves the VM to the folder (if not already there).
Select-Object @{N='VM';E={$vm.Name}}, Value |
Export-Csv -Path C:\Users\mhops\Documents\movevms\attributes.csv –NoTypeInformation
Import-Csv C:\Users\mhops\Documents\movevms\attributes.csv -UseCulture | %{
$vm = Get-VM -Name $_.VM
$dc = Get-Datacenter -VM $vm
if($_.Value -ne ''){
$path = Get-Folder -Name $_.Value -Location $dc
}
else{
$path = Get-Folder -Name 'Discovered virtual machine' -Location $dc
}
if ($vm.Folder.Name -ne $path.Name) {
Move-VM -VM $vm -InventoryLocation $path -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for your lightspeed reply LucD, that worked like a charm :smileyblush::smileycheck:
In fact, I don't need to change the Custom Attributes, I did express myself wrong at my last post.
The Values are already set to match the folder's name or in some cases, they might be a random Value or wrong Value.
I'm a big fan of you and all work you have done contributing to the PowerCli community. I really appreciate your support and I'm learning a lot with your posts.
Regards
The powerstate of a VM should have no impact on whether or not it can be moved to a folder.
Did you try to move one of those VMs manually or directly with the Move-VM cmdlet?
Did that work?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
When I try to move the VM which is powered off using the Move-VM cmdlet it shows this error:
Move-VM -VM vm-lab-01 -InventoryLocation $path -Confirm:$false
Move-VM : 2020-09-03 10:22:24 AM Move-VM Index was outside the bounds of the array.
At line:5 char:3
+ Move-VM -VM vm-lab-01 -InventoryLocation $path -Confirm:$false
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Move-VM], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM
However, when I power it on, it does work perfectly. The same behavior happens for all powered off VMs. When I move manually (drag-drop on UI) it works as expected.
Something else that I could not figure out: The way it's right now, the VMs which custom attribute does not match any folder, are not affected and they stay where they are, however I would like those VMs which Value on a custom attribute does not match any folder also been moved to "Discovered virtual machines". How can I filter that?ks
Thank you so much for your help!
Which PowerCLI version are you using?
This is an error that I know from older PowerCLI versions.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I guess this is the latest one.
PowerCLI Version
----------------
VMware PowerCLI 12.0.0 build 15947286
---------------
Component Versions
---------------
VMware Common PowerCLI Component 12.0 build 15939652
VMware Cis Core PowerCLI Component PowerCLI Component 12.0 build 15939657
VMware VimAutomation VICore Commands PowerCLI Component PowerCLI Component 12.0 build 15939655
VMware VimAutomation Storage PowerCLI Component PowerCLI Component 12.0 build 15939648
VMware VimAutomation Vds Commands PowerCLI Component PowerCLI Component 12.0 build 15940185
VMware vSphere Update Manager PowerCLI 6.5 build 7862888
That is indeed the latest version.
Do these VMs that produce the error happen to have long Displaynames?
See move-vm returns array out of bounds
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for sharing the other thread, did a test whit a new VM called VM-TMP and the behavior is the same:
- when powered off does not move ( Index was outside the bounds of the array.)
- when powered on it moves as expected
Well... it seems to be a bug, but honestly, it has no much impact since most of VMs are in fact powered on, so not a big deal anyways.
In fact, I was wondering more about how to add to the script a way to move as well the VMs which custom attribute value does not match any folder, I would like those VMs to be also moved to "Discovered virtual machines". ( or any other folder I designated for VM's which Value does not fit any folder )
Regards
Try like this
Select-Object @{N='VM';E={$vm.Name}}, Value |
Export-Csv -Path C:\Users\mhops\Documents\movevms\attributes.csv –NoTypeInformation
Import-Csv C:\Users\mhops\Documents\movevms\attributes.csv -UseCulture | %{
$vm = Get-VM -Name $_.VM
$dc = Get-Datacenter -VM $vm
if($_.Value -ne ''){
$path = Get-Folder -Name $_.Value -Location $dc
if(-not $path){
$path = Get-Folder -Name 'Discovered virtual machine' -Location $dc
}
}
else{
$path = Get-Folder -Name 'Discovered virtual machine' -Location $dc
}
if ($vm.Folder.Name -ne $path.Name) {
Move-VM -VM $vm -InventoryLocation $path -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Now It worked perfectly LucD! Sweet
Thanks for the opportunity to follow along whit you, I could learn a lot from those examples. You're a legend.
I strong appreciate your help, have a great day!