193 lines
5.7 KiB
PowerShell
193 lines
5.7 KiB
PowerShell
function Out-DataTable
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Creates a DataTable for an object
|
|
|
|
.DESCRIPTION
|
|
Creates a DataTable based on an object's properties.
|
|
|
|
.PARAMETER InputObject
|
|
One or more objects to convert into a DataTable
|
|
|
|
.PARAMETER NonNullable
|
|
A list of columns to set disable AllowDBNull on
|
|
|
|
.INPUTS
|
|
Object
|
|
Any object can be piped to Out-DataTable
|
|
|
|
.OUTPUTS
|
|
System.Data.DataTable
|
|
|
|
.EXAMPLE
|
|
$dt = Get-psdrive | Out-DataTable
|
|
|
|
# This example creates a DataTable from the properties of Get-psdrive and assigns output to $dt variable
|
|
|
|
.EXAMPLE
|
|
Get-Process | Select Name, CPU | Out-DataTable | Invoke-SQLBulkCopy -ServerInstance $SQLInstance -Database $Database -Table $SQLTable -force -verbose
|
|
|
|
# Get a list of processes and their CPU, create a datatable, bulk import that data
|
|
|
|
.NOTES
|
|
Adapted from script by Marc van Orsouw and function from Chad Miller
|
|
Version History
|
|
v1.0 - Chad Miller - Initial Release
|
|
v1.1 - Chad Miller - Fixed Issue with Properties
|
|
v1.2 - Chad Miller - Added setting column datatype by property as suggested by emp0
|
|
v1.3 - Chad Miller - Corrected issue with setting datatype on empty properties
|
|
v1.4 - Chad Miller - Corrected issue with DBNull
|
|
v1.5 - Chad Miller - Updated example
|
|
v1.6 - Chad Miller - Added column datatype logic with default to string
|
|
v1.7 - Chad Miller - Fixed issue with IsArray
|
|
v1.8 - ramblingcookiemonster - Removed if($Value) logic. This would not catch empty strings, zero, $false and other non-null items
|
|
- Added perhaps pointless error handling
|
|
|
|
.LINK
|
|
https://github.com/RamblingCookieMonster/PowerShell
|
|
|
|
.LINK
|
|
Invoke-SQLBulkCopy
|
|
|
|
.LINK
|
|
Invoke-Sqlcmd2
|
|
|
|
.LINK
|
|
New-SQLConnection
|
|
|
|
.FUNCTIONALITY
|
|
SQL
|
|
#>
|
|
[CmdletBinding()]
|
|
[OutputType([System.Data.DataTable])]
|
|
param(
|
|
[Parameter( Position=0,
|
|
Mandatory=$true,
|
|
ValueFromPipeline = $true)]
|
|
[PSObject[]]$InputObject,
|
|
|
|
[string[]]$NonNullable = @()
|
|
)
|
|
|
|
Begin
|
|
{
|
|
$dt = New-Object Data.datatable
|
|
$First = $true
|
|
|
|
function Get-ODTType
|
|
{
|
|
param($type)
|
|
|
|
$types = @(
|
|
'System.Boolean',
|
|
'System.Byte[]',
|
|
'System.Byte',
|
|
'System.Char',
|
|
'System.Datetime',
|
|
'System.Decimal',
|
|
'System.Double',
|
|
'System.Guid',
|
|
'System.Int16',
|
|
'System.Int32',
|
|
'System.Int64',
|
|
'System.Single',
|
|
'System.UInt16',
|
|
'System.UInt32',
|
|
'System.UInt64')
|
|
|
|
if ( $types -contains $type ) {
|
|
Write-Output "$type"
|
|
}
|
|
else {
|
|
Write-Output 'System.String'
|
|
}
|
|
} #Get-Type
|
|
}
|
|
Process
|
|
{
|
|
foreach ($Object in $InputObject)
|
|
{
|
|
$DR = $DT.NewRow()
|
|
foreach ($Property in $Object.PsObject.Properties)
|
|
{
|
|
$Name = $Property.Name
|
|
$Value = $Property.Value
|
|
|
|
#RCM: what if the first property is not reflective of all the properties? Unlikely, but...
|
|
if ($First)
|
|
{
|
|
$Col = New-Object Data.DataColumn
|
|
$Col.ColumnName = $Name
|
|
|
|
#If it's not DBNull or Null, get the type
|
|
if ($Value -isnot [System.DBNull] -and $Value -ne $null)
|
|
{
|
|
$Col.DataType = [System.Type]::GetType( $(Get-ODTType $property.TypeNameOfValue) )
|
|
}
|
|
|
|
#Set it to nonnullable if specified
|
|
if ($NonNullable -contains $Name )
|
|
{
|
|
$col.AllowDBNull = $false
|
|
}
|
|
|
|
try
|
|
{
|
|
$DT.Columns.Add($Col)
|
|
}
|
|
catch
|
|
{
|
|
Write-Error "Could not add column $($Col | Out-String) for property '$Name' with value '$Value' and type '$($Value.GetType().FullName)':`n$_"
|
|
}
|
|
}
|
|
|
|
Try
|
|
{
|
|
#Handle arrays and nulls
|
|
if ($property.GetType().IsArray)
|
|
{
|
|
$DR.Item($Name) = $Value | ConvertTo-XML -As String -NoTypeInformation -Depth 1
|
|
}
|
|
elseif($Value -eq $null)
|
|
{
|
|
$DR.Item($Name) = [DBNull]::Value
|
|
}
|
|
else
|
|
{
|
|
$DR.Item($Name) = $Value
|
|
}
|
|
}
|
|
Catch
|
|
{
|
|
Write-Error "Could not add property '$Name' with value '$Value' and type '$($Value.GetType().FullName)'"
|
|
continue
|
|
}
|
|
|
|
#Did we get a null or dbnull for a non-nullable item? let the user know.
|
|
if($NonNullable -contains $Name -and ($Value -is [System.DBNull] -or $Value -eq $null))
|
|
{
|
|
write-verbose "NonNullable property '$Name' with null value found: $($object | out-string)"
|
|
}
|
|
|
|
}
|
|
|
|
Try
|
|
{
|
|
$DT.Rows.Add($DR)
|
|
}
|
|
Catch
|
|
{
|
|
Write-Error "Failed to add row '$($DR | Out-String)':`n$_"
|
|
}
|
|
|
|
$First = $false
|
|
}
|
|
}
|
|
|
|
End
|
|
{
|
|
Write-Output @(,$dt)
|
|
}
|
|
|
|
} #Out-DataTable |