Automation

 View Only
  • 1.  Script to delete vms that are x days old on a test server

    Posted Mar 06, 2019 02:15 PM

    Hi

    I am new to PowerCLI and are trying to create a script to delete VMs older than a day (to cleanup on a testserver).

    My plan was to find some code that did something similar and see if I could redo it to fit my purpose.

    I have been trying to merge these 2 scripts and have been failing for a couple of days:

    Create a list of candidates for deletion: Get Snapshots older than X Days – PowerCLI | VMMaster

    Delete the VMs: Script for reporting and removing VMs older than 2 weeks.

    Connect-viserver -Server viserver

    function Get-VMCreationTimes {

       $vms = get-vm -Datastore datastore-9

       $vmevts = @()

       $vmevt = new-object PSObject

       foreach ($vm in $vms) {

    #

    #Progress bar:

    #

          $foundString = "Found: "+$vmevt.name+"   "+$vmevt.createdTime

          $searchString = "Searching: "+$vm.name

          $percentComplete = $vmevts.count / $vms.count * 100

          write-progress -activity $foundString -status $searchString -percentcomplete $percentComplete

          $evt = get-vievent $vm | sort createdTime | select -first 1

          $vmevt = new-object PSObject

          $vmevt | add-member -type NoteProperty -Name createdTime -Value $evt.createdTime

          $vmevt | add-member -type NoteProperty -Name name -Value $vm.name

            

          $vmevts += $vmevt   

       }

       $vmevts | sort createdTime

    }

    $deletioncandidates = Get-VMCreationTimes | Where {$evt.CreatedTime -lt (Get-Date).AddDays(-1)} | Select-Object Name

    Stop-VM -VM $deletioncandidates -Confirm:$false -whatif

    But this gives me this message:

    Stop-VM : Cannot bind parameter 'VM'. Cannot convert the "" value of type "System.Management.Automation.PSCustomObject" to type "VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine".

    At line:29 char:13

    + Stop-VM -VM $deletioncandidates -Confirm:$false -whatif

    +             ~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidArgument: (:) [Stop-VM], ParameterBindingException

        + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.StopVM

    start-sleep 30

    $vms = @{}

    Get-VM | where {$_.PowerState -eq "PoweredOff"} | % {$vms.Add($_.Name, $_)}

    Get-VIEvent -Start (Get-Date).AddDays(-1) -Entity $vms.Values -MaxSamples ([int]::MaxValue) | where {$_ -is [VMware.Vim.VmPoweredOffEvent]} |

      Sort-Object -Property CreatedTime -Unique | % {

      $vms.Remove($_.VM.Name)

    }

    Remove-VM -VM $vms.Values -DeletePermanently -Confirm:$false -WhatIf

    But this gives me this message

    Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'Windows2012'  Key being added: 'Windows2012'"

    At line:3 char:54

    + Get-VM | where {$_.PowerState -eq "PoweredOff"} | % {$vms.Add($_.Name, $_)}

    +                                                      ~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

        + FullyQualifiedErrorId : ArgumentException

    Can anybody figure out what i am doing wrong?

    (or point me in the direction of a script that works)



  • 2.  RE: Script to delete vms that are x days old on a test server
    Best Answer

    Posted Mar 06, 2019 02:26 PM

    I think there is an easier way (although part of it is similar to what you have been doing).

    • get all the VMCreatedEvent from the last 8 days
    • store the names of those VMs in an array
    • remove duplicates in the array with the Sort-Object -Unique
    • get all VMs and let only the ones that are not in the array get through
    • remove the VMs that came through the Where-clause

    $vmNew = @()

    $vm = Get-VM

    Get-VIEvent -Start (Get-Date).AddDays(-8) -Entity $vm -MaxSamples ([int]::MaxValue) |

       where {$_ -is [VMware.Vim.VmCreatedEvent]} |

       ForEach-Object -Process {

       $vmNew += $_.VM.Name

    }

    $vmNew = $vmNew | Sort-Object -Unique


    $vm | where {$vmNew -notcontains $_.Name} |

       Remove-VM -DeletePermanently -Confirm:$false



  • 3.  RE: Script to delete vms that are x days old on a test server

    Posted Mar 06, 2019 02:48 PM

    Thank you LucD.

    Your script catch all the machines on the host.

    At the moment the server only have VMs created today and yesterday, and todays machines also got included when i ran the script with -whatif.

    When i ran the script i modified this part:

    Get-VIEvent -Start (Get-Date).AddDays(-1)

    and this part:

    Get-VM -Datastore datastore-9



  • 4.  RE: Script to delete vms that are x days old on a test server

    Posted Mar 06, 2019 02:54 PM

    You are capturing the events I assume?

    You are connected to a vCenter, and not an ESXi node.

    Check if the following lists anything at all.

    $vm = Get-VM

    Get-VIEvent -Start (Get-Date).AddDays(-1) -Entity $vm -MaxSamples ([int]::MaxValue) |

       where {$_ -is [VMware.Vim.VmCreatedEvent]}



  • 5.  RE: Script to delete vms that are x days old on a test server

    Posted Mar 06, 2019 03:02 PM

    You are right, the events are missing.

    I never thought the machine would be setup this way.

    Thank you for your help.



  • 6.  RE: Script to delete vms that are x days old on a test server

    Posted Mar 07, 2019 08:53 AM

    I ended up with another kind of solution, from this thread:

    Need a script to reboot VM if uptime is more than 1 days

    Where time since boot were used:

    Connect-viserver -Server viserver

    Get-VM -Datastore datastore | Where-Object {($_.ExtensionData.RunTime.BootTime -lt (get-date).AddDays(-1)) -and ($_.PowerState -eq "PoweredOn")} | `

    Remove-VM -Confirm:$False -DeletePermanently

    Thank you for your help LucD.