Private/Set-HyperVNotesTags.ps1
|
function Set-HyperVNotesTags { <# .SYNOPSIS Stores VM-AutoTagger tags as a JSON block in a Hyper-V VM's Notes field. .DESCRIPTION Since Hyper-V does not have a native tag system like vSphere, this function stores tags as a structured JSON block appended to (or replacing in) the VM Notes field. The format uses a separator line to distinguish user notes from auto-tagger tags: [any existing notes text] ---VM-AUTOTAGGER-TAGS--- {"OS-Family":"Windows","CPU-Tier":"4-8 vCPU","Memory-Tier":"Medium (8-16GB)"} If an existing tag block is found, it is replaced. User notes above the separator are preserved. .PARAMETER VM A Hyper-V VM object from Get-VM. .PARAMETER Tags A hashtable of category-name to tag-value pairs to store. .PARAMETER Server The Hyper-V host name (used for -ComputerName on remote hosts). .EXAMPLE $tags = @{ 'OS-Family' = 'Windows'; 'CPU-Tier' = '4-8 vCPU' } Set-HyperVNotesTags -VM $vm -Tags $tags .EXAMPLE Set-HyperVNotesTags -VM $vm -Tags @{ 'Power-State' = 'Running' } -Server 'hyperv01' .NOTES Author: Larry Roberts Part of the VM-AutoTagger module. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [object]$VM, [Parameter(Mandatory)] [hashtable]$Tags, [string]$Server ) $separator = "`n---VM-AUTOTAGGER-TAGS---`n" $currentNotes = if ($VM.Notes) { $VM.Notes } else { '' } # Strip existing tag block if present $sepIndex = $currentNotes.IndexOf('---VM-AUTOTAGGER-TAGS---') if ($sepIndex -ge 0) { $currentNotes = $currentNotes.Substring(0, $sepIndex).TrimEnd() } $tagJson = $Tags | ConvertTo-Json -Compress $newNotes = if ([string]::IsNullOrWhiteSpace($currentNotes)) { $separator.TrimStart() + $tagJson } else { $currentNotes + $separator + $tagJson } if ($PSCmdlet.ShouldProcess($VM.Name, "Set VM Notes with tags")) { $setParams = @{ VM = $VM; Notes = $newNotes; ErrorAction = 'Stop' } if ($Server -and $Server -ne 'localhost' -and $Server -ne $env:COMPUTERNAME -and $Server -ne '.') { $setParams['ComputerName'] = $Server } Hyper-V\Set-VM @setParams } } function Get-HyperVNotesTags { <# .SYNOPSIS Reads VM-AutoTagger tags from a Hyper-V VM's Notes field. .DESCRIPTION Parses the VM Notes field looking for the VM-AutoTagger tag separator line and extracts the JSON tag block. Returns a hashtable of category-name to tag-value pairs. If no tag block is found, returns an empty hashtable. .PARAMETER VM A Hyper-V VM object from Get-VM. .EXAMPLE $tags = Get-HyperVNotesTags -VM $vm $tags['OS-Family'] # Returns 'Windows' .EXAMPLE $vm = Hyper-V\Get-VM -Name 'WebServer01' $tags = Get-HyperVNotesTags -VM $vm if ($tags.Count -eq 0) { Write-Host 'No tags found' } .NOTES Author: Larry Roberts Part of the VM-AutoTagger module. #> [CmdletBinding()] param( [Parameter(Mandatory)] [object]$VM ) $notes = if ($VM.Notes) { $VM.Notes } else { return @{} } $sepIndex = $notes.IndexOf('---VM-AUTOTAGGER-TAGS---') if ($sepIndex -lt 0) { return @{} } $jsonStart = $sepIndex + '---VM-AUTOTAGGER-TAGS---'.Length $jsonStr = $notes.Substring($jsonStart).Trim() if ([string]::IsNullOrWhiteSpace($jsonStr)) { return @{} } try { $parsed = $jsonStr | ConvertFrom-Json -ErrorAction Stop $result = @{} foreach ($prop in $parsed.PSObject.Properties) { $result[$prop.Name] = $prop.Value } return $result } catch { Write-Verbose "Failed to parse tags from VM Notes: $_" return @{} } } |