Sunday, 2 August 2015

Using PowerCLI and vSphere tags for VM lifecycle

VM sprawl can get seriously out of control. I recently deleted 50 VM in an environment after it appeared they were no longer required or worse, nobody knew what they were used for. Some of these VM were deployed a few years ago and were never used. The obvious thing to do here was to delete them. Going forward I want to ensure that all VM get reviewed on an annual basis so that they can be deleted if no longer required. One good way of identifying objects in vCenter is by making use of tags. Before you can create tags you will need to have a tag category. I created a category called "Expiry Date" and ensured that it is only applicable to virtual machines

New-TagCategory -Name "Expiry Date" -Cardinality "Single" -EntityType "VirtualMachine" -Description "Expiry Date for VM"

The idea is that I check my VM once a month and I want to retrieve a listing of all VM that expire in a given month. I will need to create a tag for each month. Additionally I want a tag that is called "No Expiry" which I will apply to the foundation infrastucture such as Active Directory servers or Nutanix CVM. I will place all tags in an array and then create a tag for each.

$Months = @("January", "February","March","April","May","June","July","August","September","October","November","December","No Expiry")

ForEach($Month in $Months){
    Get-TagCategory "Expiry Date" | New-Tag -Name $Month -Description "VM that expire in $Month"    
}


With the tags in place we can now assign them to the VM.

$Tag = Get-Tag "August"
Get-vm VM1 | New-TagAssignment -Tag 

Assigning tags one by one would have taken me a long time so I have written a function that should make life a bit easier

function Set-VMExpiry {
<#
.SYNOPSIS
    Set the Expiry month of a VM.
.DESCRIPTION
    Set the Expiry month of a VM . This will allow for determining when VM is due for review.
.NOTES
    Author      : Guy Defryn
    Version     : 1.0
    Date        : 28/7/2015   
.PARAMETER VirtualMachine
    Specify the VM to which apply expiry date
.PARAMETER Month
    Specify the month in which the VM expires
.EXAMPLE
    Set-VMExpiry -VirtualMachine VM1 -Month July
.EXAMPLE
    Import-CSV .\vmexpiry.csv | Set-VMExpiry
    Add all expiry dates as defined in the csv file vmexpiry.csv.
#>
    [CmdletBinding()]
    param(
    [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)][String] $VirtualMachine,
    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$True)][String] $Month
    )
    Begin{
        If (!$Month) {
            $Month = get-date -Format MMMM
        }
    }
    Process{
        write-output "Setting Expiry for $VirtualMachine to $Month"
        $VM = get-vm $Virtualmachine
        $OldTag = Get-TagAssignment $VM -Category "Expiry Date"
        if($OldTag){
           Remove-Tagassignment $OldTag -Confirm:$false 
        }
        $VM | New-TagAssignment -Tag $Month | out-null
    }
    End{
    }
}

Now that we have our VM tagged with an expiry we can report on these. I have created a function that will allow to get you VM that are set to expire in given month. I also like to know which VM are not tagged so I can actually go and tag these accordingly.

function Get-VMExpiry {
<#
.SYNOPSIS
    Get a list of VM that are expiring based on month input
.DESCRIPTION
    Get a list of VM that are expiring based on month input. This will allow for determining if the VM is still required.
.NOTES
    Author      : Guy Defryn
    Version     : 1.1
    Date        : 31/7/2015   
.PARAMETER MONTH
    Specify Month to obtain list of expired VM. If not specified current month will be returned.
.PARAMETER ExportPath
    Specify the path if you want to export to CSV
.EXAMPLE
    Get-VMExpiry -Month July
    Get VM that expire in the month of July
.EXAMPLE
    Get-VMExpiry
    Get VM that expire in current month
.EXAMPLE
    Get-VMExpiry -Month "No Expiry"
    Get VM that are set to not expire
.EXAMPLE
    Get-VMExpiry -Month Unspecified
    Get VM that have no expiry date tag set
.EXAMPLE
    Get-VMExpiry -Month Unspecified -ExportPath C:\Temp\tags.csv
    Get VM that have no expiry date tag set and export it to file
.TODO
#>
    [CmdletBinding()]
    param(
    [Parameter(Mandatory=$false)][String] $Month,
    [Parameter(Mandatory=$false)][String] $ExportPath

    )
    Begin{
        If(!$Month){
            $Month = get-date -Format MMMM
        }
        $Category = Get-TagCategory -Name "Expiry Date"
        
    }
    Process{
        If($Month -eq "No Expiry"){
            write-output "VM which are not expiring"
            $Tags = get-vm -tag $Month | select Name
        }
        ElseIf($Month -eq "Unspecified"){
            write-output "VM which have no expiry date specified"
            $Tags = get-vm | Where {!(Get-Tagassignment -Entity $_ -Category $Category)} | Select Name
        }
        Else{
            write-output "VM expiring during the month of $Month"
            $Tags = get-vm -tag $Month | select Name
        }
    }
    End{
        $Tags
        if($ExportPath){
            $Tags | export-csv $ExportPath -NoTYpeInformation
        }
    }
}

1 comment:

  1. Thank you for this. ive been searching everywhere to figure out how to list vm's that do not have a tag. After seeing your script its so simple. I only found 3 different articles, and this was the only one that worked.

    ReplyDelete