public/Merge-Csv.ps1

using namespace System.Text
using namespace System.IO
using namespace System.Management.Automation

function Merge-Csv {
    [cmdletbinding()]
    param(
        [Parameter(Position = 0, Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [alias('FullName')]
        [string[]] $Path,

        [Parameter(Mandatory)]
        [string] $DestinationPath,

        [Parameter()]
        [EncodingTransformation()]
        [ArgumentCompleter([EncodingCompleter])]
        [Encoding] $Encoding = 'utf8',

        [Parameter()]
        [switch] $PassThru,

        [Parameter()]
        [switch] $Force
    )

    begin {
        $isFirstObject = $true
        $Destination   = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($DestinationPath)
    }

    process {
        foreach($chunk in $Path) {
            try {
                $reader  = [StreamReader]::new($chunk, $Encoding, $true)
                $headers = $reader.ReadLine()

                if($isFirstObject) {
                    $params = @{
                        Path        = $Destination
                        ItemType    = 'File'
                        Force       = $Force.IsPresent
                        ErrorAction = 'Stop'
                    }
                    $Destination   = New-Item @params
                    $isFirstObject = $false
                    $writer        = [StreamWriter]::new($Destination, $Encoding)
                    $writer.WriteLine($headers)
                }

                while(-not $reader.EndOfStream) {
                    $writer.WriteLine($reader.ReadLine())
                }
            }
            catch [DirectoryNotFoundException] {
                $PSCmdlet.ThrowTerminatingError(
                    [ErrorRecord]::new(
                        [DirectoryNotFoundException]::new(
                            $_.Exception.Message +
                            ' Use the -Force parameter to create new folders.'
                        ),
                        'DirectoryNotFound',
                        [ErrorCategory]::WriteError,
                        $DestinationPath
                    )
                )
            }
            catch [IOException] {
                if($_.Exception.Message.EndsWith('already exists.')) {
                    $PSCmdlet.ThrowTerminatingError(
                        [ErrorRecord]::new(
                            [IOException]::new(
                                $_.Exception.Message +
                                ' Use the -Force parameter to overwrite the file.'
                            ),
                            'FileExists',
                            [ErrorCategory]::WriteError,
                            $DestinationPath
                        )
                    )
                }
                $PSCmdlet.ThrowTerminatingError($_)
            }
            catch {
                $PSCmdlet.ThrowTerminatingError($_)
            }
            finally {
                if($reader) {
                    $reader.Dispose()
                }
            }
        }
    }
    end {
        if($writer) {
            $writer.Dispose()
        }

        if($PassThru.IsPresent) {
            $Destination
        }
    }
}