Public/ps1/Export-VMsWithoutSpecificTag.ps1

<#
.Synopsis
    Exports a list of virtual machines (VMs) from a specified datacenter, VM folder, or a list of VM names that do not have specific tags.
 
.Description
    This command retrieves all virtual machines (VMs) based on the input type and filters them based on the absence of tags from a given category. The list of VMs that meet these criteria is then exported to a CSV file at the specified output path.
 
.Parameter InputType
    Specifies the type of input to determine VMs' source. Options are 'Datacenter', 'VMFolder', and 'VMList'.
 
.Parameter InputValue
    Specifies the name of the datacenter, VM folder, or an array of VM names from which to retrieve VMs.
 
.Parameter ExcludedCategory
    Specifies the category of tags to exclude from the report. VMs with tags in this category will not be included in the output. Default is 'System Owner'.
 
.Parameter OutputPath
    Specifies the path where the CSV file containing the filtered VM list will be saved. Default is '.\VMsWithoutTagsReport.csv'.
 
.Example
    Export-VMsWithoutSpecificTag -InputType "Datacenter" -InputValue "dc1" -ExcludedCategory "System Owner" -OutputPath "C:\path\to\your\file.csv"
    Exports a list of VMs that do not have tags in the 'System Owner' category from the datacenter named 'dc1' 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-VMsWithoutSpecificTag {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [ValidateSet("Datacenter", "VMFolder", "VMList")]
        [string]$InputType,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        $InputValue,

        [Parameter(Mandatory=$true)]
        [string]$ExcludedCategory,

        [Parameter(Mandatory=$true)]
        [string]$OutputPath
    )

    try {
        # Initialize the VM collection variable
        $vms = @()

        # Determine how to get VMs based on the input type
        switch ($InputType) {
            "Datacenter" {
                $vms = Get-Datacenter -Name $InputValue | Get-VM
            }
            "VMFolder" {
                $vms = Get-Folder -Name $InputValue | Get-VM
            }
            "VMList" {
                $vms = $InputValue | ForEach-Object { Get-VM -Name $_ }
            }
        }

        # Retrieve the category object for the excluded category
        $category = Get-TagCategory -Name $ExcludedCategory

        # Check if the category exists
        if (-not $category) {
            Write-Error "Specified category '$ExcludedCategory' does not exist."
            return
        }

        # Filter VMs based on the absence of tags in the specified category
        $filteredVMs = $vms | Where-Object {
            $tags = Get-TagAssignment -Entity $_ | Select-Object -ExpandProperty Tag
            # Check if VM has no tags or none of the tags belong to the excluded category
            -not ($tags | Where-Object { $_.Category -eq $category.Name })
        } | Select-Object Name

        # Export the filtered VM names to a CSV file
        $filteredVMs | Export-Csv -Path $OutputPath -NoTypeInformation -UseCulture
        Write-Output "Data exported to $OutputPath"
    } catch {
        Write-Error "An error occurred: $_"
    }
}