Public/ConvertTo-WFDataTable.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
function ConvertTo-WFDataTable
{
    <#
        .SYNOPSIS
            Converts objects into a DataTable.
     
        .DESCRIPTION
            Converts objects into a DataTable, which are used for DataBinding.
     
        .PARAMETER InputObject
            The input to convert into a DataTable.
     
        .PARAMETER Table
            The DataTable you wish to load the input into.
     
        .PARAMETER RetainColumns
            This switch tells the function to keep the DataTable's existing columns.
         
        .PARAMETER FilterWMIProperties
            This switch removes WMI properties that start with an underline.
     
        .EXAMPLE
            $DataTable = ConvertTo-WFDataTable -InputObject (Get-Process)
     
        .NOTES
            SAPIEN Technologies, Inc.
            http://www.sapien.com/
     
            VERSION HISTORY
            1.0 ????/??/?? From Sapien.com Version
            2.0 2014/12/03 Francois-Xavier Cat - In the rows workk, I added a
                small piece of code to handle the $null value with [DBNull]::Value
            2.1 2016/03/23 Some improvements added
                 
    #>

    [CmdletBinding()]
    [OutputType([System.Data.DataTable])]
    param (
        [ValidateNotNull()]
        $InputObject,
        
        [ValidateNotNull()]
        [System.Data.DataTable]$Table,
        
        [switch]$RetainColumns,
        
        [switch]$FilterWMIProperties
    )
    
    if ($Table -eq $null)
    {
        $Table = New-Object System.Data.DataTable
    }
    
    if ($InputObject -is [System.Data.DataTable])
    {
        $Table = $InputObject
    }
    else
    {
        if (-not $RetainColumns -or $Table.Columns.Count -eq 0)
        {
            #Clear out the Table Contents
            $Table.Clear()
            
            if (-not$InputObject) { return } #Empty Data
            
            $object = $null
            
            #find the first non null value
            foreach ($item in $InputObject)
            {
                if ($item)
                {
                    $object = $item
                    break
                }
            }
            
            if (-not$object) { return } #All null then empty
            
            #COLUMN
            #Get all the properties in order to create the columns
            foreach ($prop in $object.PSObject.Get_Properties())
            {
                if (-not $FilterWMIProperties -or -not $prop.Name.StartsWith('__')) #filter out WMI properties

                {
                    #Get the type from the Definition string
                    $type = $null
                    
                    if ($prop.Value)
                    {
                        try { $type = $prop.Value.GetType() }
                        catch { Write-Verbose -Message "Can't find type of $prop" }
                    }
                    
                    if ($type) # -and [System.Type]::GetTypeCode($type) -ne 'Object')

                    {
                        Write-Verbose -Message "Creating Column: $($Prop.name) (Type: $type)"
                        [void]$table.Columns.Add($prop.Name, $type)
                    }
                    else #Type info not found

                    {
                        #if ($prop.name -eq "" -or $prop.name -eq $null) { [void]$table.Columns.Add([DBNull]::Value) }
                        [void]$table.Columns.Add($prop.Name)
                    }
                }
            }
            
            if ($object -is [System.Data.DataRow])
            {
                foreach ($item in $InputObject)
                {
                    $Table.Rows.Add($item)
                }
                #return @(, $Table)
                return $Table
            }
        }
        else
        {
            $Table.Rows.Clear()
        }
        
        #Rows Work
        foreach ($item in $InputObject)
        {
            # Create a new row object
            $row = $table.NewRow()
            
            if ($item)
            {
                foreach ($prop in $item.PSObject.Get_Properties())
                {
                    #Find the appropriate column to put the value
                    if ($table.Columns.Contains($prop.Name))
                    {
                        if (-not$prop.value) { $prop.value = [DBNull]::Value }
                        $row.Item($prop.Name) = $prop.Value
                    }
                }
            }
            [void]$table.Rows.Add($row)
        }
    }
    
    #return @(, $Table)
    return $Table
}