Functions/Convert-CsvStringToObject.ps1
<#
.SYNOPSIS This function converts a CSV string to a CSV object. .DESCRIPTION This function converts a CSV string to a CSV object. The CSV object is represented as an array of PSObjects. #> function Convert-CsvStringToObject { [CmdletBinding(PositionalBinding=$true)] [OutputType([Object[]])] param ( # The string containing the CSV representation. [Parameter(Mandatory=$true, Position=0)] [ValidateNotNullOrEmpty()] [String]$csvString, # If this parameter is set, the names of the headers will be trimmed. [Parameter(Mandatory=$false)] [ValidateNotNull()] [Switch]$trimHeaders = [Switch]::Present, # If this parameter is set, strings consisting solely of digits with an optional '-' in front # which are shorter than the maximum length will be converted to integer variables. [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateScript({ $_ -gt 0 -and $_ -le 6})] [Int]$convertIntegersMaxLength, # Select if strings like "true" and "false" are processed into boolean $true and $false. # This also performs a whitespace trim on the strings before comparing against "true" and "false". [Parameter(Mandatory=$false)] [ValidateNotNull()] [Switch]$convertBooleans = [Switch]::Present, # Select if strings should have starting and trailing whitespace trimmed. [Parameter(Mandatory=$false)] [ValidateNotNull()] [Switch]$trimStrings = $false, # Select the stream where the failure messages will be directed. [Parameter(Mandatory=$false)] [ValidateSet("Information", "Warning", "Error")] [String]$outputStream = "Error" ) try { # Remove extra first line for Excel if present if ($csvString -match "sep=,[\s]+([\s\S]*)") { $csvString = $Matches[1] } # Output CSV string to temporary file # Try to create a temporary file try { $tempFile = New-TemporaryFile } catch { Invoke-Expression "Write-$($outputStream) 'Exception while creating temporary file for converting CSV string to CSV object.$($CRLF + $_.Exception.Message)'" return } if (!$tempFile) { Invoke-Expression "Write-$($outputStream) 'Failed to create temporary file for converting CSV string to CSV object.'" return } # Try to set the content of the temporary file try { $csvString | Set-Content -NoNewline -Path $tempFile.FullName -Encoding BigEndianUnicode } catch { Invoke-Expression "Write-$($outputStream) 'Exception while setting content of temporary file for converting CSV string to CSV object.$($CRLF + $_.Exception.Message)'" return } # Try to import CSV file to object try { $csvObject = Import-Csv -Path $tempFile.FullName -Encoding BigEndianUnicode } catch { Invoke-Expression "Write-$($outputStream) 'Exception while importing temporary file into CSV object.$($CRLF + $_.Exception.Message)'" return } if (!$csvObject) { Invoke-Expression "Write-$($outputStream) 'Failed to import temporary file into CSV object.'" return } # Trim the headers if ($trimHeaders) { $csvObject = $csvObject | ForEach-Object -Process { $updatedObject = [PSCustomObject]@{} foreach ($property in $_.PSObject.Properties) { $updatedObject | Add-Member -NotePropertyName $property.Name.Trim() -NotePropertyValue $property.Value } $updatedObject } } # Convert single objects to array try { $csvObject = ConvertTo-Array $csvObject } catch { Invoke-Expression "Write-$($outputStream) 'Exception while converting CSV object to an array.$($CRLF + $_.Exception.Message)'" return } if (!$csvObject) { Invoke-Expression "Write-$($outputStream) 'Failed to convert CSV object to an array.'" return } # The CSV should be post-processed if ($convertIntegersMaxLength -or $convertBooleans -or $trimStrings) { # Iterate through each of the rows in the CSV foreach ($csv in $csvObject) { # Iterate through each of the columns foreach ($propertyName in $csv.PSObject.Properties.Name) { # Only process non-null values if ([String]::IsNullOrWhiteSpace($csv.$propertyName)) { continue } # Only process string values if ($csv.$propertyName.GetType() -ne [String]) { continue } # Check if string should be converted to an integer if ($convertIntegersMaxLength -and $csv.$propertyName.length -le $convertIntegersMaxLength -and $csv.$propertyName -match "^-{0,1}[0-9]{1,$($convertIntegersMaxLength)}$") { $csv.$propertyName = [Int]$csv.$propertyName } # Check if string should be converted to boolean elseif ($convertBooleans -and $csv.$propertyName.Trim() -in @("true", "false")) { $csv.$propertyName = $csv.$propertyName.Trim() -eq "true" } # Check if string should be trimmed elseif ($trimStrings) { $csv.$propertyName = $csv.$propertyName.Trim() } } } } # Return the converted CSV object return $csvObject } finally { # Delete the temporary file created if ($tempFile) { $tempFile | Remove-Item } } } |