Public/ps1/Export-VMTagReport.ps1

<#
.Synopsis
    Generates a CSV report of all VMs with their tag assignments categorized and sorted by a specified property.
 
.Description
    This function retrieves all virtual machines (VMs), sorts them by a specified property (default is "Name"), and then retrieves all tag assignments for these VMs. It processes each VM to map its tags to the corresponding categories, creating a detailed report which is then exported to a CSV file at a specified output path.
 
.Parameter OutputPath
    Specifies the path where the CSV report will be saved. Default is '.\report.csv'.
 
.Parameter SortProperty
    Specifies the property by which to sort the list of VMs. Default is "Name", but can be any property associated with VMs such as "CPU" or "Memory".
 
.Example
    Export-VMTagReport -OutputPath "C:\path\to\your\report.csv" -SortProperty "Name"
    This example generates a report of all VMs, sorted by their names, with their associated tags categorized and exported to the specified path.
 
.Notes
    Author: bensiegit
    Version: 1.0.0
 
    Requires that you are connected to a vCenter server with appropriate permissions to retrieve VMHost information.
#>


function Export-VMTagReport {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$false)]
        [string]$OutputPath,
        [Parameter(Mandatory=$false)]
        [string]$SortProperty
    )

    # Retrieve all VMs and sort by the specified property
    $allVM = Get-VM | Sort-Object -Property $SortProperty

    # Retrieve all tag assignments
    $assigned = $allVM | Get-TagAssignment
    $ordered = $assigned.Tag.Category.Name | Sort-Object -Unique

    # Process each VM to map tags to categories
    $data = $allVM | ForEach-Object -Process {
        $obj = [ordered]@{
            VM = $_.Name
        }

        # Create a column header using the categories
        $ordered | ForEach-Object -Process {
            $obj.Add($_, '')
        }

        # Filter tag assignments for the current VM and group by category
        $assigned | Where-Object { $_.Entity.Name -eq $obj.VM } |
        Group-Object -Property {$_.Tag.Category.Name} |
        ForEach-Object -Process {
            $obj[$_.Name] = $_.Group.Tag.Name -join '|'
        }

        # Return the custom object with VM tags and categories
        New-Object -TypeName PSObject -Property $obj
    }

    # Export the data to CSV using specified path
    $data | Export-Csv -Path $OutputPath -NoTypeInformation -UseCulture
    Write-Output "Data exported to $OutputPath"
}