Private/Initialize-TagCategory.ps1
|
function Initialize-TagCategory { <# .SYNOPSIS Ensures a vSphere tag category exists, creating it if necessary. .DESCRIPTION Idempotent function that checks whether a vSphere tag category with the given name already exists. If it does, returns the existing category object. If not, creates a new tag category with the specified cardinality and description. This is called by Sync-VMTags before processing VMs to guarantee that all categories defined in the tag profile exist in vCenter. Cardinality options: - Single: Only one tag from this category can be assigned per entity. - Multiple: Multiple tags from this category can be assigned per entity. .PARAMETER Name The name for the tag category (e.g., "OS-Family", "CPU-Tier"). .PARAMETER Cardinality The cardinality for the tag category. Valid values: Single, Multiple. Default: Single. .PARAMETER Description A description for the tag category. If not specified, a default description is generated. .EXAMPLE $cat = Initialize-TagCategory -Name "OS-Family" -Cardinality "Single" -Description "Operating system family" .EXAMPLE $cat = Initialize-TagCategory -Name "Network" -Cardinality "Multiple" .NOTES Author: Larry Roberts Requires: VMware.PowerCLI module (connected to vCenter) Part of the VM-AutoTagger module. #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter()] [ValidateSet('Single', 'Multiple')] [string]$Cardinality = 'Single', [Parameter()] [string]$Description ) process { if ([string]::IsNullOrWhiteSpace($Description)) { $Description = "Auto-managed by VM-AutoTagger: $Name" } # Check if category already exists $existing = $null try { $existing = Get-TagCategory -Name $Name -ErrorAction SilentlyContinue } catch { Write-Verbose "Category '$Name' not found, will create." } if ($existing) { Write-Verbose "Tag category '$Name' already exists (Cardinality: $($existing.Cardinality))." # Warn if cardinality mismatch but do not change it (could break existing assignments) if ($existing.Cardinality -ne $Cardinality) { Write-Warning "Category '$Name' exists with Cardinality '$($existing.Cardinality)' but profile specifies '$Cardinality'. Existing cardinality will be preserved." } return $existing } # Create the category Write-Verbose "Creating tag category: $Name (Cardinality: $Cardinality)" try { $newCategory = New-TagCategory -Name $Name ` -Cardinality $Cardinality ` -Description $Description ` -EntityType 'VirtualMachine' ` -ErrorAction Stop Write-Verbose "Created tag category: $Name" return $newCategory } catch { Write-Error "Failed to create tag category '$Name': $_" return $null } } } function Initialize-Tag { <# .SYNOPSIS Ensures a vSphere tag exists within a given category, creating it if necessary. .DESCRIPTION Idempotent function that checks whether a tag with the given name exists in the specified category. If it does, returns the existing tag. If not, creates a new tag. .PARAMETER Name The name for the tag (e.g., "Windows", "1-2 vCPU", "Production"). .PARAMETER Category The tag category object (from Get-TagCategory or Initialize-TagCategory) in which the tag should exist. .EXAMPLE $cat = Get-TagCategory -Name "OS-Family" $tag = Initialize-Tag -Name "Windows" -Category $cat .NOTES Author: Larry Roberts Requires: VMware.PowerCLI module (connected to vCenter) Part of the VM-AutoTagger module. #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [object]$Category ) process { # Check if tag already exists $existing = $null try { $existing = Get-Tag -Name $Name -Category $Category -ErrorAction SilentlyContinue } catch { Write-Verbose "Tag '$Name' not found in category '$($Category.Name)', will create." } if ($existing) { Write-Verbose "Tag '$($Category.Name)/$Name' already exists." return $existing } # Create the tag Write-Verbose "Creating tag: $($Category.Name)/$Name" try { $newTag = New-Tag -Name $Name ` -Category $Category ` -Description "Auto-created by VM-AutoTagger" ` -ErrorAction Stop Write-Verbose "Created tag: $($Category.Name)/$Name" return $newTag } catch { Write-Error "Failed to create tag '$($Category.Name)/$Name': $_" return $null } } } |