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
}
}
}