Sunday, August 23, 2026

PowerShell Scripting: Converts list-view CSV data into table-view CSV format

Some time I need this script Converts list-view CSV data into table-view CSV format.

---------------------------------------------------------------------------------------------------------------------------------
<#
.SYNOPSIS
    Converts list-view CSV data into table-view CSV format.

.DESCRIPTION
    Reads a CSV-like file containing repeated key/value pairs separated
    by blank rows and converts each group into a PowerShell object.

    The resulting objects are exported as a standard table-format CSV.

.PARAMETER InputFile
    Path to the source list-view CSV file.

.PARAMETER OutputFile
    Path to the destination table-view CSV file.

.EXAMPLE
    .\Convert-ListViewToTable.ps1 `
        -InputFile ".\ListViewData.csv" `
        -OutputFile ".\TableViewData.csv"

.EXAMPLE
    .\Convert-ListViewToTable.ps1 `
        -InputFile "C:\Data\Input.csv" `
        -OutputFile "C:\Data\Output.csv"
        
.NOTES
    File Name : Convert-ListViewToTable.ps1
    Author    : mimi
    Purpose   : Convert list-view key/value CSV data into table-view CSV format.
    Version   : 1.0
#>

[CmdletBinding()]
param (
    [Parameter(
        Mandatory = $true,
        Position = 0,
        HelpMessage = "Specify the input list-view CSV file."
    )]
    [ValidateNotNullOrEmpty()]
    [ValidateScript({
        if (-not (Test-Path -LiteralPath $_ -PathType Leaf)) {
            throw "Input file does not exist: $_"
        }

        $true
    })]
    [string]$InputFile,

    [Parameter(
        Mandatory = $true,
        Position = 1,
        HelpMessage = "Specify the output table-view CSV file."
    )]
    [ValidateNotNullOrEmpty()]
    [string]$OutputFile
)

try {

    # Resolve the input path
    $InputFile = (Resolve-Path -LiteralPath $InputFile).Path

    # Convert output path to an absolute path
    $OutputFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
        $OutputFile
    )

    Write-Verbose "Input file : $InputFile"
    Write-Verbose "Output file: $OutputFile"

    # Make sure the output directory exists
    $OutputDirectory = Split-Path -Path $OutputFile -Parent

    if (-not (Test-Path -LiteralPath $OutputDirectory -PathType Container)) {
        throw "Output directory does not exist: $OutputDirectory"
    }

    $Records = [System.Collections.Generic.List[object]]::new()
    $CurrentRecord = [ordered]@{}

    foreach ($Line in Get-Content -LiteralPath $InputFile) {

        # Blank line or "," indicates the end of a record
        if (
            [string]::IsNullOrWhiteSpace($Line) -or
            $Line.Trim() -eq ","
        ) {

            if ($CurrentRecord.Count -gt 0) {

                $Records.Add(
                    [PSCustomObject]$CurrentRecord
                )

                $CurrentRecord = [ordered]@{}
            }

            continue
        }

        # Split only on the first comma
        $Parts = $Line -split ',', 2

        $Key = $Parts[0].Trim()

        if ($Parts.Count -gt 1) {
            $Value = $Parts[1].Trim()
        }
        else {
            $Value = ""
        }

        # Ignore empty property names
        if (-not [string]::IsNullOrWhiteSpace($Key)) {
            $CurrentRecord[$Key] = $Value
        }
    }

    # Add the final record if the file doesn't end
    # with a blank/separator line
    if ($CurrentRecord.Count -gt 0) {
        $Records.Add(
            [PSCustomObject]$CurrentRecord
        )
    }

    if ($Records.Count -eq 0) {
        throw "No records were found in the input file."
    }

    # Export as normal table-view CSV
    $Records |
        Export-Csv `
            -LiteralPath $OutputFile `
            -NoTypeInformation `
            -Encoding UTF8

    Write-Host "Conversion completed successfully."
    Write-Host "Records converted : $($Records.Count)"
    Write-Host "Output file       : $OutputFile"
}
catch {
    Write-Error "Conversion failed: $($_.Exception.Message)"
    exit 1
}

---------------------------------------------------------------------------------------------------------------------------------

Save it as Convert-ListViewToTable.ps1 and run it like this:

.\Convert-ListViewToTable.ps1 ` -InputFile ".\ListViewData.csv" ` -OutputFile ".\TableViewData.csv"

or Or because I've defined Position, this also works:

.\Convert-ListViewToTable.ps1 ".\ListViewData.csv" ".\TableViewData.csv"


For troubleshooting, you can use -Verbose:

.\Convert-ListViewToTable.ps1 ` -InputFile ".\ListViewData.csv" ` -OutputFile ".\TableViewData.csv" ` -Verbose




No comments:

Post a Comment