Export-CSV -Append #powershell


Export-CSV -Append

Here’s the solution for those who need to append rows to existing CSV files (andcannot do that): I have just used PowerShell 2.0 code snippets to create a proxy cmdlet – function which wraps standard Export-CSV cmdlet but adds handling of the-Append parameter.

So you can do something like:

Get-Process | Export-Csv-Path'c:\Temp\processes.csv'-Append-Delimiter';'

As you can see, other parameters – such as Delimiter – still function as well. If the file does not exist – the cmdlet will essentially ignore -Append and create the file as normal. If you specify -Append and the file is present, the function will turn the objects into CSV strings, remove the first row with the property names and append to the existing file.

For your convenience, I have posted the source code to PoshCode. Here’s it is as well for those interested:

#Requires -Version 2.0<#
  This Export-CSV behaves exactly like native Export-CSV
  However it has one optional switch -Append
  Which lets you append new data to existing CSV file: e.g.
  Get-Process | Select ProcessName, CPU | Export-CSV processes.csv -Append

  For details, see

http://dmitrysotnikov.wordpress.com/2010/01/19/export-csv-append/

  (c) Dmitry Sotnikov  
#>functionExport-CSV {
[CmdletBinding(DefaultParameterSetName='Delimiter',
  SupportsShouldProcess=$true, ConfirmImpact='Medium')]
param(
 [Parameter(Mandatory=$true, ValueFromPipeline=$true,
           ValueFromPipelineByPropertyName=$true)]
 [System.Management.Automation.PSObject]
 ${InputObject},

 [Parameter(Mandatory=$true, Position=0)]
 [Alias('PSPath')]
 [System.String]
 ${Path},

 #region -Append (added by Dmitry Sotnikov)
 [Switch]
 ${Append},
 #endregion 

 [Switch]
 ${Force},

 [Switch]
 ${NoClobber},

 [ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32',
                  'BigEndianUnicode','Default','OEM')]
 [System.String]
 ${Encoding},

 [Parameter(ParameterSetName='Delimiter', Position=1)]
 [ValidateNotNull()]
 [System.Char]
 ${Delimiter},

 [Parameter(ParameterSetName='UseCulture')]
 [Switch]
 ${UseCulture},

 [Alias('NTI')]
 [Switch]
 ${NoTypeInformation})

begin
{
 # This variable will tell us whether we actually need to append# to existing file$AppendMode=$falsetry {
  $outBuffer=$nullif ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
  {
      $PSBoundParameters['OutBuffer'] =1
  }
  $wrappedCmd=$ExecutionContext.InvokeCommand.GetCommand('Export-Csv',
    [System.Management.Automation.CommandTypes]::Cmdlet)

 #String variable to become the target command line$scriptCmdPipeline=''# Add new parameter handling#region Dmitry: Process and remove the Append parameter if it is present
 if ($Append) {

  $PSBoundParameters.Remove('Append') | Out-Nullif ($Path) {
   if (Test-Path$Path) {        
    # Need to construct new command line$AppendMode=$trueif ($Encoding.Length -eq0) {
     # ASCII is default encoding for Export-CSV$Encoding='ASCII'
    }

    # For Append we use ConvertTo-CSV instead of Export$scriptCmdPipeline+='ConvertTo-Csv -NoTypeInformation '# Inherit other CSV convertion parametersif ( $UseCulture ) {
     $scriptCmdPipeline+=' -UseCulture '
    }
    if ( $Delimiter ) {
     $scriptCmdPipeline+=" -Delimiter '$Delimiter' "
    } 

    # Skip the first line (the one with the property names) $scriptCmdPipeline+=' | Foreach-Object {$start=$true}'$scriptCmdPipeline+='{if ($start) {$start=$false} else {$_}} '# Add file output$scriptCmdPipeline+=" | Out-File -FilePath '$Path'"$scriptCmdPipeline+=" -Encoding '$Encoding' -Append "if ($Force) {
     $scriptCmdPipeline+=' -Force'
    }

    if ($NoClobber) {
     $scriptCmdPipeline+=' -NoClobber'
    }   
   }
  }
 } 

 $scriptCmd= {& $wrappedCmd @PSBoundParameters }

 if ( $AppendMode ) {
  # redefine command line$scriptCmd=$ExecutionContext.InvokeCommand.NewScriptBlock(
      $scriptCmdPipeline
    )
 } else {
  # execute Export-CSV as we got it because# either -Append is missing or file does not exist$scriptCmd=$ExecutionContext.InvokeCommand.NewScriptBlock(
      [string]$scriptCmd
    )
 }

 # standard pipeline initialization$steppablePipeline=$scriptCmd.GetSteppablePipeline(
        $myInvocation.CommandOrigin)
 $steppablePipeline.Begin($PSCmdlet)

 } catch {
   throw
 }

}

process
{
  try {
      $steppablePipeline.Process($_)
  } catch {
      throw
  }
}

end
{
  try {
      $steppablePipeline.End()
  } catch {
      throw
  }
}
<#

.ForwardHelpTargetName Export-Csv
.ForwardHelpCategory Cmdlet

#>

}

Hope this helps!

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s