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