0

I have the below string which is returned from an Invoke-RestMethod call. How can I transform the results into an object or data table to be able to use it? The first row would be the properties.

I tried the Out-File and Export-CSV first but the only length is added to the file. Then I tried the format table which did nothing.

Any ideas?

Name,Main No, Sec No

Alex,34.6743,22.7800

Tom,33.8798,21.9098 

Tim,34.6743,41.7800

Mark,33.8798,21.9098 

1 Answer 1

1

The ConvertFrom-Csv cmdlet is smart enough to exclude the empty lines we see in your example. To output as CSV, simply use:

$data | ConvertFrom-Csv

#output to csv file:

$data | ConvertFrom-Csv | Export-Csv -Path 'D:\test.csv' -NoTypeInformation

Your CSV file will look like this:

"Name","Main No","Sec No"
"Alex","34.6743","22.7800"
"Tom","33.8798","21.9098 "
"Tim","34.6743","41.7800"
"Mark","33.8798","21.9098"

If you want it converted to datatable, you can use below function:

function ConvertTo-DataTable {
    [CmdletBinding()]
    Param(
        [Parameter(Position=0, Mandatory=$true, ValueFromPipeline = $true)]
        [PSObject[]]$InputObject
    )

    Begin {
        $dataTable = New-Object System.Data.DataTable
        $first = $true

        function _GetSafeTypeName($type) {
            # internal helper function to return the correct typename for a datatable
            $types = @('System.Boolean', 'System.Byte', 'System.SByte', 'System.Char', 'System.Datetime',
                       'System.TimeSpan', 'System.Decimal', 'System.Double', 'System.Guid', 'System.Single')
            $ints  = @('System.Int16', 'System.Int32', 'System.Int64')
            $uints = @('System.UInt16', 'System.UInt32', 'System.UInt64')

            if ($types -contains $type) { return "$type" }
            # if the type is Int or UInt, always return the largest variety
            if ($ints  -contains $type) { return 'System.Int64' }
            if ($uints -contains $type) { return 'System.UInt64' }
            return 'System.String'
        }
    }
    Process {
        foreach ($object in $InputObject) {
            $dataRow = $dataTable.NewRow()
            foreach($property in $object.PSObject.Properties) {
                # read the data type for this property and make sure it is a valid type for a DataTable
                $dataType = _GetSafeTypeName $property.TypeNameOfValue
                # ensure the property name does not contain invalid characters
                $propertyName = $property.Name -replace '[\W\p{Pc}-[,]]', '_' -replace '_+', '_'
                if ($first) {
                    $dataColumn = New-Object System.Data.DataColumn $propertyName, $dataType
                    $dataTable.Columns.Add($dataColumn)
                }
                if ($property.Gettype().IsArray -or ($property.TypeNameOfValue -like '*collection*')) {
                    $dataRow.Item($propertyName) = $property.Value | ConvertTo-XML -As String -NoTypeInformation -Depth 1
                }
                else {
                    $value = if ($null -ne $property.Value) { $property.Value } else { [System.DBNull]::Value }
                    $dataRow.Item($propertyName) = $value -as $dataType
                }
            }
            $dataTable.Rows.Add($dataRow)
            $first = $false
        }
    }
    End {
        Write-Output @(,($dataTable))
    }
}

Then use it like this:

$data | ConvertFrom-Csv | ConvertTo-DataTable

P.S. $data is the result of your Invoke-RestMethod call.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.