VMware Cloud Community
JProvencher
Contributor
Contributor

Remove-VM with logging

I'm not sure which board this should actually go to, but I've been working on a system to delete powered off VMs.  Granted, I'm not the only one doing this but where I work, they are more about documentation and accountability and want everything logged.

It would? help a lot if Remove-VM had a -PassThru paramter because I could pass a list of VMs in a variable, and use another variable to trap the VMs that passed down the pipeline to be removed, then use the original list bounced against that to get a list of those that were excluded -> $Result = Remove-VM $VMs -Confirm -PassThru.  No -Passthru parameter so I need another way.

I was wanting to use -Confirm so if the user had to delete 100 VMs, he could answer 'A' for 'Yes to All'.

Is there a way to separately trap the successes and failures for Remove-VM?

Am I restricted to processing them one by one?

By the way, what I'm doing is processing an input file of powered off VMs.  For those in the selected area, I present them in a grid view for selection (via out-gridview -passthru).  The selected VMs are grouped by VCenter, then for each of those connect-viserver to the vcenter and get the named VMs, then pass those to Remove-VM.  It'd be awesome if there was a way to trap success/failure when answering 'Yes to All', and/or recording those that were selected but excluded from removal by answering 'N' or 'L' to the -Confirm prompt.

Reply
0 Kudos
2 Replies
LucD
Leadership
Leadership

Afaik, there is no (easy) possibility to get the reply to the prompt caused by a Confirm switch.
You could consider creating a proxy function for the Remove-VM cmdlet, but that would be rather complex.

An easier option is to mimic the Confirm switch.
That way you get the reply and you can control what happens depending on the reply.

Basically, that mimicking could be something like this.
You will just have to complete the different code blocks for each of the switch cases.

$vm = 'MyVM'

$title    = 'Perform operation'
$question = "Performing operation 'Removing VM from disk.' on VM '$vm'"
$choices  = '&Yes', 'Yes to &All', '&No', 'No to A&ll', '&Suspend'

$answer = $Host.UI.PromptForChoice($title, $question, $choices, 0)
switch($answer){
  '0' {
    'Yes'
  }
  '1' {
    'Yes to All'
  }
  '2' {
    'No'
  }
  '3' {
    'No to All'
  }
  '4' {
    'Suspend'
  }
}

 You can include that in your own function, which you would then call instead of calling Remove-VM directly.


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

Reply
0 Kudos
JProvencher
Contributor
Contributor

And here is what I came up with.  I created a function for the prompt and left out 'Suspend'

Function Confirm {
    Param(
        [string]$title,
        [string]$Question
    )

    $choices = '&Yes','Yes to &All', '&No', 'No to A&ll'
    $answer = $Host.UI.PromptForChoice($title, $question, $choices,0)
    switch ($answer) {
        '0' { 'Yes' }
        '1' { 'Yes to All' }
        '2' { 'No' }
        '3' { 'No to All' }
        default {'Yes'}
    }
}

$processed = [System.Collections.ArrayList]::New()
$skipped = [System.Collections.ArrayList]::New()
$queue=[System.Collections.Queue]::Synchronized((New-Object System.Collections.Queue))
$vms.name | Foreach {$queue.enqueue($_)}

While ($queue.count -gt 0) {
    $vm = $queue.dequeue()
    $answer = confirm -title "Question" -Question "Process $($vm)?" -Item $vm
    switch ($answer) {
        'Yes' { [void]$processed.add($vm); Remove-VM -VM $vm -DeletePermanently }
        'No' { [void]$skipped.add($vm) }
        'Yes to All' { [void]$processed.add($vm); Remove-VM -VM $vm -DeletePermanently;
            do { $vm = $queue.dequeue();
                 Remove-VM -VM $vm -DeletePermanently;
                 [void]$processed.Add($vm)
               } Until ($Queue.count -eq 0) }
        'No to All' { [void]$skipped.add($vm);
            do { [void]$skipped.add($queue.dequeue()) } Until ($queue.count -eq 0) }
    }
}

I thought using a queue was the easiest way to go through one by one, skipping here and there and at some point answering 'Yes to All' or 'No to All'.  This is the first time I've used a queue in this way.  I typically use one when processing threaded jobs.

Reply
0 Kudos