Functions/Get-FilteredCsvString.ps1

<#
.SYNOPSIS
    This function filters a CSV string, keeping rows which have $true or the specified values for the specified columns.
#>

function Get-FilteredCsvString {
    [CmdletBinding()]
    [OutputType([Object[]])]
    param (
        # The CSV string to filter.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$csv,

        # The columns used to filter the CSV string.
        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [String[]]$columns,

        # The column values used to filter the CSV string.
        [Parameter(Mandatory=$false)]
        [PSObject[]]$columnValues,

        # Select if the filtering is 'and' or 'or'.
        # If the filtering is 'and', all the specified columns must match the column values
        [Parameter(Mandatory=$false)]
        [ValidateSet("and", "or")]
        [String]$filtering = "and"
    )

    # Convert columns and column values to array
    $columns = ConvertTo-Array $columns
    $columnValues = ConvertTo-Array $columnValues

    # Provide default for column values used for filtering
    # Default is that value must be $true for the row to be kept
    if ($columns.count -gt 0 -and $columnValues.count -eq 0) {
        $columnValues = $columns | ForEach-Object {
            $true
        }
    }

    # Verify column values
    if ($columns.count -ne $columnValues.count) {
        Write-Error "Number of columns ($($columns.count)) and number of column values ($($columnValues.count)) provided are not the same."
        return $null
    }

    # Convert the CSV string to CSV object
    $csvObject = ConvertTo-CsvObject $csv
    if (!$csvObject) {
        Write-Error "Failed to convert input CSV string to CSV object."
        return $null
    }

    # Filter the CSV by the column names
    if ($columns) {
        $columnNames = ConvertTo-Array ($columns.Split(",") | ForEach-Object { $_.Trim() })

        # Run through each entry in the CSV
        $csvObject = $csvObject | ForEach-Object -Process {
            $csvEntry = $_

            # Perform a count of the number of properties which are true
            $filterResult = @()
            for ($i = 0; $i -lt $columns.count; ++$i) {
                if ($csvEntry.($columns[$i]) -eq $columnValues[$i]) {
                    $filterResult += $true
                }
            }

            # All the properties are true, the entry stays
            if ($filtering -eq "and" -and $filterResult.length -eq $columns.count) {
                $csvEntry
            }

            # At least one property is true, the entry stays
            elseif ($filtering -eq "or" -and $filterResult.length -gt 0) {
                $csvEntry
            }
        }
    }

    # No items left after filtering
    if (!$csvObject) {
        return $null
    }

    # Return the result as a CSV string
    $csvString = ConvertTo-CsvString $csvObject
    if ([String]::IsNullOrWhiteSpace($csvString)) {
        Write-Error "Failed to convert CSV object to CSV string."
        return $null
    }
    return $csvString
}