I know this is a super old thread, but I wanted to put the solution in that I have been using. I borrowed it from https://github.com/RamblingCookieMonster/PSSQLite/blob/master/PSSQLite/Invoke-SqliteQuery.ps1
this project scrubbed it out using a bit of imbedded c# code that is very efficient and clean:
if ($As -eq 'PSObject') {
#This code scrubs DBNulls. Props to Dave Wyatt
$cSharp = @'
using System;
using System.Data;
using System.Management.Automation;
public class DBNullScrubber
{
public static PSObject DataRowToPSObject(DataRow row)
{
PSObject psObject = new PSObject();
if (row != null && (row.RowState & DataRowState.Detached) != DataRowState.Detached)
{
foreach (DataColumn column in row.Table.Columns)
{
Object value = null;
if (!row.IsNull(column))
{
value = row[column];
}
psObject.Properties.Add(new PSNoteProperty(column.ColumnName, value));
}
}
return psObject;
}
}
'@
try {
if ($PSEdition -eq 'Core') {
# Core doesn't auto-load these assemblies unlike desktop?
# Not csharp coder, unsure why
# by fffnite
$Ref = @(
'System.Data.Common'
'System.Management.Automation'
'System.ComponentModel.TypeConverter'
)
} else {
$Ref = @(
'System.Data'
'System.Xml'
)
}
Add-Type -TypeDefinition $cSharp -ReferencedAssemblies $Ref -ErrorAction stop
} catch {
if (-not $_.ToString() -like "*The type name 'DBNullScrubber' already exists*") {
Write-Warning "Could not load DBNullScrubber. Defaulting to DataRow output: $_"
$As = 'Datarow'
}
}
}
# to use it to convert the DBNull into $null I use it like this:
try {
$CSBuilder = New-Object System.Data.Odbc.OdbcConnectionStringBuilder
$Cred = Get-Credential -Message "Please provide credentials for $Server"
$OdbcDriverName = 'SQL Server'
$CSBuilder['driver'] = $OdbcDriverName
$CSBuilder['DSURL'] = $Server
#$CSBuilder['Database'] = 'master'
$CSBuilder['Database'] = $Database
$CSBuilder['uid'] = $cred.UserName
$CSBuilder['pwd'] = $cred.GetNetworkCredential().Password
$CSBuilder['EncryptedPassword'] = 2
$CSBuilder['ConnectionIdleTimeout'] = 600
$conn = New-Object System.Data.Odbc.OdbcConnection
$conn.ConnectionString = $CSBuilder.ConnectionString
$conn.ConnectionTimeout = 30
$conn.Open()
#$conn.ChangeDatabase($Database)
$cmd = New-Object System.Data.Odbc.OdbcCommand($QryText, $conn)
$cmd.CommandTimeout = 30
$ds = New-Object System.Data.DataSet
$da = New-Object System.Data.Odbc.OdbcDataAdapter($cmd)
[void]$da.Fill($ds)
switch ($As) {
'DataSet' { return $ds }
'Table' { return $($ds.Tables[0]) }
'Row' { return $($ds.Tables[0].Rows[0]) }
'PSObject' {
foreach ($row in $ds.Tables[0].Rows) {
#--- DBNull scrubber conversion ---#
[DBNullScrubber]::DataRowToPSObject($row)
}
}
'SingleValue' {
return $ds.Tables[0] | Select-Object -ExpandProperty $ds.Tables[0].Columns[0].ColumnName
}
default { return $ds }
}
} catch {
Write-Warning "Query failed: $($_.Exception.Message)"
}