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