PowerShell: Issue Returning DataTable from Function.

Swahela Mulla 95 Reputation points
2023-12-18T15:21:18.24+00:00

Hello Everyone,

I am facing an issue with a PowerShell script where I have a function (Get-EncryptionData) intended to return data as a DataTable. However, when I call this function from a parent script, the variable storing the result ($EncryptionSuccess) is treated as a PowerShell object rather than a DataTable.

Here is a simplified description of the problem:

  1. The function retrieves data and processes it into a DataTable.
  2. I expect the variable $EncryptionSuccess to be of type DataTable, but it is being treated as a PowerShell object.
  3. This causes complications when attempting to use $EncryptionSuccess for bulk copy operations.

I've explored various approaches without success. Could you provide guidance on how to explicitly return data as a DataTable from the function, ensuring that the variable is of the correct type? Additionally, if there are conventions or methods specific to handling DataTables in PowerShell functions, any references or documentation would be greatly appreciated.

Thank you for your assistance.

function Get-EncryptionData {

        try {
    
            $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method Get -ErrorAction Stop
    
            $Encryption = ($response.Content | ConvertFrom-Json).value 
            $Encryption = $Encryption | Select-Object -Property id, deviceName, isEncrypted, userPrincipalName
    
            # Create a new DataTable
            $table = New-Object System.Data.DataTable
    
            # Define columns
            $table.Columns.Add("DeviceID", [string])
            $table.Columns.Add("DeviceName", [string])
            $table.Columns.Add("IsEncrypted", [bool])
            $table.Columns.Add("UserPrincipalName", [string])
            
            $Encryption | ForEach-Object {
                # Add a new row to the DataTable
                $row = $table.NewRow()
                $row["DeviceID"] = $_.id
                $row["DeviceName1"] = $_.deviceName
                $row["IsEncrypted1"] = $_.isEncrypted
                $row["UserPrincipalName1"] = $_.userPrincipalName
    
                $table.Rows.Add($row)
            }
        
            return $table
        }
        catch {
            write-host An error occurred: $($_.Exception.Message)
            return $false
        }
    }

#Calling Encryption Script
. ("$Config_ScriptFolderPath\EncryptionStatus.ps1")

$EncryptionSuccess = Get-EncryptionData -ConfigFilePath $ConfigFilePath
Azure SQL Database
Windows for business | Windows Server | User experience | PowerShell
SQL Server | Other
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 47,901 Reputation points
    2023-12-18T16:38:41.55+00:00

    Change the return $table to return , $table. The comma is an overlooked operator that's almost magical!

    You're running into a PowerShell behavior that sends an enumerable object into the pipeline one item at a time. To counter that, add the comma before the value you want returned. The comma is an array operator but because there's nothing before the comma the second element (your datatable) is passed into the pipeline (intact).

    If you examine the object type of the value returned from the function you'll see it's an array of type "Object". If you examine the properties of the returned object you'll find the methods and data are those of the System.Data.Datatable.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Oury Ba-MSFT 20,911 Reputation points Microsoft Employee Moderator
    2023-12-20T18:59:51.6733333+00:00

    Swahela Mulla

    Thank you for reaching out.

    Could you please try updating the column names in the $row object to match the column names defined in the $table object. Here is the updated code for the ForEach-Object loop:

    
    $Encryption | ForEach-Object {
        # Add a new row to the DataTable
        $row = $table.NewRow()
        $row["DeviceID"] = $_.id
        $row["DeviceName"] = $_.deviceName
        $row["IsEncrypted"] = $_.isEncrypted
        $row["UserPrincipalName"] = $_.userPrincipalName
    
        $table.Rows.Add($row)
    }
    

    Please do let us know the result from your end.

    Regards,

    Oury

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.