2

I have a script that will power off and DeletePermanently all VMs that match a certain prefix. I use this when testing other automation tools to make it easy to reset the lab. The script connects to multiple, pre-defined vCenter servers and then gets a list of all the VMs. The problem I have is that when I try to power off or delete the VMs, it says "Could not find VirtualMachine with name 'VMNAME'."

Code that connects to the vCenter servers:

$vcservers = @("VC1","VC2")
Connect-VIServer $vcservers

Code that gets a list of VMs from both vCenter servers:

$prefix = "TEST"
ForEach ($vc in $vcservers) {
    $vms += Get-VM -Server $vc | where {$_.Name -like "$prefix*"}
}

Code that powers off and deletes each VM:

ForEach ($vm in $vms) {
    $vmname = $vm.name
    if ($vm.PowerState -eq "PoweredOn") {
        Stop-VM -VM $vmname -confirm:$false
        Remove-VM -VM $vmname -DeletePermanently -confirm:$false
    }
}

I have set the "Multiple" property on the Users and AllUsers scope by using Set-PowerCLIConfiguration, so it should search all vCenter servers, but for some reason it is not working.

EDIT 1/25/17 Updated the code to make the $vcservers variable consistent.

McKenning
  • 631
  • 4
  • 20
  • 32
  • What does `$vms` contain? I assume it is an array of arrays while you expect an array of VMs. –  Jan 14 '17 at 17:34
  • It contains a list of virtual machines that matches the search from the second code block. It is an array that contains the name, powerstate and other properties. – McKenning Jan 15 '17 at 00:18

1 Answers1

2

Since the first issue (related to variable naming) was resolved, I'm currently suspecting that the issue is due to PowerCLI being unsure on which VCenter the VMs you want to delete live. Thus, you could go VCenter by vCenter instead of trying to run against all vCenters at once:

$prefix = "TEST"
$vcservers = @("VC1","VC2")
ForEach ($vc in $vcservers) {
    Connect-VIServer $vc
    $vms += Get-VM -Server $vc | where {$_.Name -like "$prefix*"}

    ForEach ($vm in $vms) {
        $vmname = $vm.name
        if ($vm.PowerState -eq "PoweredOn") {
            Stop-VM -VM $vmname -confirm:$false
            Remove-VM -VM $vmname -DeletePermanently -confirm:$false
        }
    Disconnect-VIServer $vc
}
twglomski
  • 96
  • 4
  • Good catch, but this was an error in my translation from the original code. I've updated the question so the variables are the same. – McKenning Jan 25 '17 at 16:28
  • 1
    I don't have a vcenter to test against, but looking at your issue again I think it might be because when you run Stop-VM and Remove-VM, it doesn't know which VCenter to be looking at. What you could do is contain everything - including the Connect-VIServer - inside the same ForEach loop. Try that out and let me know how it goes. If it works I'll add it as a separate answer. – twglomski Jan 25 '17 at 19:01
  • I'm unsure how to contain everything in the same ForEach loop. How can I do a loop on the vms when I'm not connecting to the vCenters until I'm inside the foreach loop? – McKenning Jan 26 '17 at 14:12
  • I edited the answer to properly show how I'd modify your code. – twglomski Jan 26 '17 at 18:29