PSDataKit.psm1

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
# Implement your module commands in this script.


# Export only the functions using PowerShell standard verb-noun naming.
# Be sure to list each exported functions in the FunctionsToExport field of the module manifest file.
# This improves performance of command discovery in PowerShell.




function Merge-Hashtables {



    [cmdletbinding()]
    Param (
        [hashtable]
        # First hashtable to merge, this will have priority
        $primary,

        [hashtable]
        # second hashtable to merge
        $secondary
    )

    # If in debug mode, show the function currently in
    #Write-Log -IfDebug -Message $("***** {0} *****" -f $MyInvocation.MyCommand)

    # Craete an array of types that can be merged.
    # Hashtables and Dictionaries can be merged
    $types = @(
        "Hashtable"
        "Dictionary``2"
    )

    #check for any duplicate keys
    $duplicates = $primary.keys | where {$secondary.ContainsKey($_)}

    if ($duplicates) {
        foreach ($key in $duplicates) {

                # if the item is a hashtable then call this function again
                if ($types -contains $primary.$key.gettype().name -and
                    $types -contains $secondary.$key.gettype().name) {

                    # set the argument hashtable
                    $splat = @{
                        primary = $primary.$key
                        secondary = $secondary.$key
                    }

                    $Primary.$key = Merge-Hashtables @splat
                }

                # if the key is an array merge the two items
                if ($primary.$key.GetType().Name -eq "Object[]" -and $secondary.$key.GetType().name -eq "Object[]") {

                    $result = @()

                    # Because an array can contain many different types, need to be careful how this information is merged
                    # This means that the normal additional functions and the Unique parameter of Select will not work properly
                    # so iterate around each of the two arrays and add to a result array
                    foreach ($arr in @($primary.$key, $secondary.$key)) {

                        # analyse each item in the arr
                        foreach ($item in $arr) {

                            # Switch on the type of the item to determine how to add the information
                            switch ($item.GetType().Name) {
                                "Object[]" {
                                    $result += , $item
                                }

                                # If the type is a string make sure that the array does not already
                                # contain the same string
                                "String" {
                                    if ($result -notcontains $item) {
                                        $result += $item
                                    }
                                }

                                # For everything else add it in
                                default {
                                    $result += $item
                                }
                            }
                        }
                    }

                    # Now assign the result back to the primary array
                    $primary.$key = $result
                }

                #force primary key, so remove secondary conflict
                $Secondary.Remove($key)

        }
    }

    #join the two hash tables and return to the calling function
    $Primary + $Secondary

}
Export-ModuleMember -Function Merge-Hashtables

Function ConvertTo-FlattenObject {
    # Version 00.02.12, by iRon
    [CmdletBinding()]Param (
        [Parameter(ValueFromPipeLine = $True)][Object[]]$Objects,
        [String]$Separator = ".", [ValidateSet("", 0, 1)]$Base = 1, [Int]$Depth = 5, [Int]$Uncut = 1,
        [String[]]$ToString = ([String], [DateTime], [TimeSpan]), [String[]]$Path = @()
    )
    $PipeLine = $Input | ForEach {$_}; If ($PipeLine) {$Objects = $PipeLine}
    If (@(Get-PSCallStack)[1].Command -eq $MyInvocation.MyCommand.Name -or @(Get-PSCallStack)[1].Command -eq "<position>") {
        $Object = @($Objects)[0]; $Iterate = New-Object System.Collections.Specialized.OrderedDictionary
        If ($ToString | Where-Object {$Object -is $_}) {$Object = $Object.ToString()}
        ElseIf ($Depth) {
            $Depth--
            If ($Object.GetEnumerator.OverloadDefinitions -match "[\W]IDictionaryEnumerator[\W]") {
                $Iterate = $Object
            }
            ElseIf ($Object.GetEnumerator.OverloadDefinitions -match "[\W]IEnumerator[\W]") {
                $Object.GetEnumerator() | ForEach-Object -Begin {$i = $Base} {$Iterate.($i) = $_; $i += 1}
            }
            Else {
                $Names = If ($Uncut) {$Uncut--} Else {$Object.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames}
                If (!$Names) {$Names = $Object.PSObject.Properties | Where-Object {$_.IsGettable} | Select-Object -Expand Name}
                If ($Names) {$Names | ForEach-Object {$Iterate.$_ = $Object.$_}}
            }
        }
        If (@($Iterate.Keys).Count) {
            $Iterate.Keys | ForEach-Object {
                ConvertTo-FlattenObject @(, $Iterate.$_) $Separator $Base $Depth $Uncut $ToString ($Path + $_)
            }
        }
        Else {$Property.(($Path | Where-Object {$_}) -Join $Separator) = $Object}
    }
    ElseIf ($Objects -ne $Null) {
        @($Objects) | ForEach-Object -Begin {$Output = @(); $Names = @()} {
            New-Variable -Force -Option AllScope -Name Property -Value (New-Object System.Collections.Specialized.OrderedDictionary)
            ConvertTo-FlattenObject @(, $_) $Separator $Base $Depth $Uncut $ToString $Path
            $Output += New-Object PSObject -Property $Property
            $Names += $Output[-1].PSObject.Properties | Select -Expand Name
        }
        $Output | Select-Object ([String[]]($Names | Select-Object -Unique))
    }
};

Export-ModuleMember -Function ConvertTo-FlattenObject