4
\$\begingroup\$

I recently had a requirement to export data to CSV in a different culture & hit an issue (see https://stackoverflow.com/a/40871162/361842).

Here's my workaround:

function ConvertTo-SpecifiedCulture {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,ValueFromPipeline)]
        [PSObject]$InputObject
        ,
        [Parameter(Mandatory)]
        [string]$CultureCode
        ,
        [Parameter(ParameterSetName='DefaultParameter', Position=0)]
        [System.Object[]]$Property
    )
    begin {
        [System.Globalization.CultureInfo] $Culture = [System.Globalization.CultureInfo]::GetCultureInfo($CultureCode) 
    }
    process {
        if($Property -eq $null) {$Property = $InputObject.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames}
        $Result = new-object -TypeName PSObject -Property @{}
        $Property | Foreach-Object -Process {
            $Result | Add-Member -MemberType NoteProperty -Name $_ -Value ($InputObject."$_").ToString($Culture) 
        }
        $Result 
    }
}

#example usage:
Get-Process | select -first 2 | ConvertTo-SpecifiedCulture -CultureCode 'fr' | ConvertTo-CSV -Delimiter ';'
#note that CPU is displayed with a comma instead of a period when converted from EN to FR.

I've also created a proxy function for this:

# $MetaData = New-Object System.Management.Automation.CommandMetaData (Get-Command  ConvertTo-CSV)
# [System.Management.Automation.ProxyCommand]::Create($MetaData)
function ConvertTo-CulturedCSV {
    [CmdletBinding(DefaultParameterSetName='Delimiter', HelpUri='http://go.microsoft.com/fwlink/?LinkID=135203', RemotingCapability='None')]
    param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [psobject]
        $InputObject,

        [Parameter(Mandatory,Position=1)]
        [string]
        $CultureCode,

        [Parameter(ParameterSetName='Delimiter', Position=2)]
        [ValidateNotNull()]
        [char]
        $Delimiter,

        [Alias('NTI')]
        [switch]
        $NoTypeInformation
    )

    begin
    {
        try {

            [System.Object[]]$Property = $null
            [System.Globalization.CultureInfo] $Culture = [System.Globalization.CultureInfo]::GetCultureInfo($CultureCode) 
            $PSBoundParameters.Remove('CultureCode') | Out-Null

            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
            {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('ConvertTo-Csv', [System.Management.Automation.CommandTypes]::Cmdlet)
            $scriptCmd = {& $wrappedCmd @PSBoundParameters }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
        } catch {
            throw
        }
    }

    process
    {
        try {
            if($Property -eq $null) {$Property = $InputObject.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames}
            $Fields = new-object -TypeName PSObject -Property @{}
            $Property | Foreach-Object -Process {
                $Fields | Add-Member -MemberType NoteProperty -Name $_ -Value ($InputObject."$_").ToString($Culture) 
            }
            $steppablePipeline.Process($Fields)
        } catch {
            throw
        }
    }

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

    .ForwardHelpTargetName ConvertTo-Csv
    .ForwardHelpCategory Cmdlet

    #>
}

Having to check whether $Property is null on each iteration seems clumsy; but as it's based on the pipeline input I can't think of a cleaner solution.

Also this is my first proxy function; so I've likely made some mistakes there.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.