EnvironmentModuleCore.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
function Get-EnvironmentModule([String] $ModuleFullName = "*", [switch] $ListAvailable, [string] $Architecture = "*", [string] $Version = "*")
{
    <#
    .SYNOPSIS
    Get the environment module object(s) matching the defined filters.
    .DESCRIPTION
    This function will return any environment modules that matches the given filter attributes.
    .PARAMETER ModuleFullName
    The full module name of the required module object(s). Can contain wildcards.
    .PARAMETER ListAvailable
    Show all environment modules that are available on the system.
    .PARAMETER Architecture
    Show only modules matching the given architecture.
    .PARAMETER Version
    Show only modules matching the given version.
    .OUTPUTS
    The EnvironmentModule-object(s) matching the filter. If no module was found, $null is returned.
    #>

    if([string]::IsNullOrEmpty($Architecture)) {
        $Architecture = "*"
    }

    if([string]::IsNullOrEmpty($Version)) {
        $Version = "*"
    }

    if($ListAvailable) {
        foreach($module in Get-AllEnvironmentModules) {
            if(-not ($module.FullName -like $ModuleFullName)) {
                continue
            }

            if(($null -ne $module.Architecture) -and (-not ($module.Architecture -like $Architecture))) {
                continue
            }

            if(($null -ne $module.Version) -and (-not ($module.Version -like $Version))) {
                continue
            }

            New-EnvironmentModuleInfo -Module $module
        }
    }
    else {
        $filteredResult = $script:loadedEnvironmentModules.GetEnumerator() | Where-Object {$_.Value.FullName -like $ModuleFullName} | Select-Object -ExpandProperty "Value"
        $filteredResult = $filteredResult | Where-Object {(($null -eq $_.Version) -or ($_.Version -like $Version)) -and (($null -eq $_.Architecture) -or ($_.Architecture -like $Architecture))}

        return $filteredResult
    }
}

function Test-EnvironmentModuleLoaded([String] $ModuleFullName)
{
    <#
    .SYNOPSIS
    Check if the environment module with the given name is already loaded.
    .DESCRIPTION
    This function will check if Import-Module was called for an enivronment module with the given name.
    .PARAMETER ModuleFullName
    The full name of the module that should be tested.
    .OUTPUTS
    $true if the environment module was already loaded, otherwise $false.
    #>

    $loadedModule = (Get-EnvironmentModule $ModuleFullName)
    if(-not $loadedModule) {
        return $false
    }

    return $true
}

function Get-LoadedEnvironmentModules()
{
    <#
    .SYNOPSIS
    Get all loaded environment modules.
    .OUTPUTS
    All loaded environment modules.
    #>

    return $script:loadedEnvironmentModules.Values
}

function Get-AllEnvironmentModules()
{
    <#
    .SYNOPSIS
    Get all known environment modules.
    .OUTPUTS
    All environment modules.
    #>

    return $script:environmentModules.Values
}

function Get-NonTempEnvironmentModules()
{
    <#
    .SYNOPSIS
    Get all environment modules that are not stored in the temp folder.
    .OUTPUTS
    All non temp environment modules.
    #>

    return Get-AllEnvironmentModules | Where-Object { -not(Test-PartOfTmpDirectory $_.ModuleBase) }
}

function Get-ConcreteEnvironmentModules([switch] $ListAvailable, [switch] $ExcludeMetaModules)
{
    <#
    .SYNOPSIS
    Get all environment modules that are not abstract (that can be loaded by the user).
    .OUTPUTS
    All concrete environment modules.
    #>

    $moduleSet = @()

    if($ListAvailable) {
        $moduleSet = Get-AllEnvironmentModules
    }
    else {
        $moduleSet = Get-EnvironmentModule
    }

    if($ExcludeMetaModules) {
        return $moduleSet | Where-Object {($_.ModuleType -ne [EnvironmentModuleCore.EnvironmentModuleType]::Abstract) -and ($_.ModuleType -ne [EnvironmentModuleCore.EnvironmentModuleType]::Meta)}
    }
    else {
        return $moduleSet | Where-Object {$_.ModuleType -ne [EnvironmentModuleCore.EnvironmentModuleType]::Abstract}
    }
}

function Get-EnvironmentModuleFunction([String] $FunctionName = "*", [String] $ModuleFullName = "*", [Switch] $ReturnTopLevelFunction)
{
    <#
    .SYNOPSIS
    Get all loaded modules that define a function with the given name.
    .DESCRIPTION
    This function will search the function stack for functions defined with the passed name.
    .PARAMETER FunctionName
    The name of the function.
    .PARAMETER ModuleFullName
    The name of the module defining the function.
    .PARAMETER ReturnTopLevelFunction
    If set, only the top level function is returned.
    .OUTPUTS
    The list of modules defining the function. The last function in the list is the executed one.
    #>

    foreach($key in $script:loadedEnvironmentModuleFunctions.Keys) {
        $values = $script:loadedEnvironmentModuleFunctions.Item($key)
        if(-not($key -like $FunctionName)) {
            continue
        }

        for($i = $values.Count - 1; $i -ge 0; $i--) {
            $value = $values[$i]
            if(-not($value.ModuleFullName -like $ModuleFullName)) {
                continue
            }

            $value
            if($ReturnTopLevelFunction) {
                break
            }
        }
    }
}

function Invoke-EnvironmentModuleFunction([String] $FunctionName, [String] $ModuleFullName, [Object[]] $ArgumentList)
{
    <#
    .SYNOPSIS
    Invoke the given function as specified by the given module.
    .PARAMETER FunctionName
    The name of the function to execute.
    .PARAMETER ModuleFullName
    The name of the module that defines the function.
    .PARAMETER ArgumentList
    The arguments that should be passed to the function execution.
    .OUTPUTS
    The result of the function execution. An exception is thrown if the module does not define a function with the given name.
    #>

    if(-not $script:loadedEnvironmentModuleFunctions.ContainsKey($FunctionName))
    {
        throw "The function $FunctionName is not registered"
    }

    $knownFunctions = $script:loadedEnvironmentModuleFunctions[$FunctionName]

    foreach($functionInfo in $knownFunctions) {
        if($functionInfo.ModuleFullName -eq $ModuleFullName) {
            return Invoke-Command -ScriptBlock ([ScriptBlock]$functionInfo.Definition) -ArgumentList $ArgumentList
        }
    }

    throw "The module $ModuleFullName has no function registered named $FunctionName"
}

function Get-EnvironmentModuleAlias([String] $ModuleFullName = "*", [String] $AliasName = "*")
{
    <#
    .SYNOPSIS
    Get all aliases that are loaded in the current environment.
    .PARAMETER ModuleFullName
    The name of the modules that should be investigated. Wildcards are allowed.
    .PARAMETER AliasName
    The name of the aliases to investigate. Wildcards are allowed.
    .OUTPUTS
    An array of EnvironmentModules.AliasInfo objects.
    #>

    $modules = Get-LoadedEnvironmentModules

    foreach($module in $modules) {
        if(-not ($module.FullName -like $ModuleFullName)) {
            continue
        }
        $aliases = $module.Aliases
        Write-Verbose "Handling module '$module' with $($aliases.Count) aliases"
        foreach($alias in $aliases.Keys) {
            if(-not ($alias -like $AliasName)) {
                continue
            }
            $definition = $aliases[$alias]
            New-Object "EnvironmentModuleCore.AliasInfo" -ArgumentList @($alias, $module.FullName, $definition.Definition, $definition.Description)
        }
    }
}

function Get-EnvironmentModulePath([String] $ModuleFullName = "*", [String] $PathName = "*", [EnvironmentModuleCore.PathType] $PathType = [EnvironmentModuleCore.PathType]::UNKNOWN)
{
    <#
    .SYNOPSIS
    Get all paths that are loaded in the current environment.
    .PARAMETER ModuleFullName
    The name of the modules that should be investigated. Wildcards are allowed.
    .PARAMETER PathName
    The name of the environment variables to investigate. Wildcards are allowed.
    .PARAMETER PathType
    The type of the paths to investigate. UNKNOWN if all types should be considered.
    .OUTPUTS
    An array of EnvironmentModules.AliasInfo objects.
    #>

    $modules = Get-LoadedEnvironmentModules

    foreach($module in $modules) {
        if(-not ($module.FullName -like $ModuleFullName)) {
            continue
        }
        $paths = $module.Paths
        Write-Verbose "Handling module '$module' with $($paths.Count) paths"
        foreach($pathInfo in $paths) {
            if(-not ($pathInfo.Variable -like $PathName)) {
                continue
            }
            if(([EnvironmentModuleCore.PathType]::UNKNOWN -ne $PathType) -and ($pathInfo.PathType -ne $PathType)) {
                continue
            }

            $pathInfo
        }
    }
}