functions/utility/Get-PSFScriptblock.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
function Get-PSFScriptblock
{
<#
    .SYNOPSIS
        Access the scriptblocks stored with Set-PSFScriptblock.
     
    .DESCRIPTION
        Access the scriptblocks stored with Set-PSFScriptblock.
     
        Use this command to access scriptblocks designed for easy, processwide access.
     
    .PARAMETER Name
        The name of the scriptblock to request.
        It's mandatory for explicitly requesting a scriptblock, but optional to use with -List as a filter.
     
    .PARAMETER List
        Instead of requesting a specific scriptblock, list the available ones.
        This can be further filtered by using a wildcard supporting string as -Name.
 
    .PARAMETER Tag
        Filter scriptblocks by their tags.
        This can be further filtered by using a wildcard supporting string as -Name.
 
    .PARAMETER Description
        Filter scriptblocks by their description using wildcard characters.
        This can be further filtered by using a wildcard supporting string as -Name.
     
    .PARAMETER Container
        Return the scriptblock container item rather than the scriptblock directly.
     
    .EXAMPLE
        PS C:\> Get-PSFScriptblock -Name 'MyModule.TestServer'
     
        Returns the scriptblock stored as 'MyModule.TestServer'
     
    .EXAMPLE
        PS C:\> Get-PSFScriptblock -List
     
        Returns a list of all scriptblocks
     
    .EXAMPLE
        PS C:\> Get-PSFScriptblock -List -Name 'MyModule.TestServer'
     
        Returns scriptblock and meta information for the MyModule.TestServer scriptblock.
     
    .EXAMPLE
        PS C:\> Get-PSFScriptblock -Name 'MyModule.*' -Tag StateChanging, Networking
     
        Returns scriptblock and meta information for all scriptblocks tagged StateChanging
        or Networking and with a name starting with MyModule.
     
    .EXAMPLE
        PS C:\> Get-PSFScriptblock -Description '*Infrastructure Script*'
     
        Returns scriptblock and meta information for all script blocks containing the
        description '*Infrastructure Script*'.
#>

    [OutputType([PSFramework.Utility.ScriptBlockItem], ParameterSetName = 'Search')]
    [OutputType([PSFramework.Utility.ScriptBlockItem], ParameterSetName = 'Container')]
    [OutputType([System.Management.Automation.ScriptBlock], ParameterSetName = 'Name')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "")]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "")]
    [CmdletBinding(DefaultParameterSetName = 'Name')]
    param (
        [PsfArgumentCompleter('PSFramework.Utility.Scriptblock.Name')]
        [Parameter(ParameterSetName = 'Search', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Parameter(Mandatory = $true, ParameterSetName = 'Name', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Parameter(Mandatory = $true, ParameterSetName = 'Container', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string[]]
        $Name = '*',
        
        [Parameter(ParameterSetName = 'Search')]
        [switch]
        $List,

        [Parameter(ParameterSetName = 'Search')]
        [string]
        $Description,
        
        [PsfArgumentCompleter('PSFramework.Utility.Scriptblock.Tag')]
        [Parameter(ParameterSetName = 'Search')]
        [string[]]
        $Tag,
        
        [Parameter(ParameterSetName = 'Container')]
        [switch]
        $Container
    )
    
    begin
    {
        [System.Collections.ArrayList]$sent = @()
        $allItems = [PSFramework.Utility.UtilityHost]::ScriptBlocks.Values
    }
    process
    {
        :main foreach ($nameText in $Name)
        {
            switch ($PSCmdlet.ParameterSetName) {
                #region Retrieve by name
                { 'Name', 'Container' -contains $_ }
                {
                    if ($sent -contains $nameText) { continue main }
                    $null = $sent.Add($nameText)
                    $scriptBlock = [PSFramework.Utility.UtilityHost]::ScriptBlocks[$nameText]
                    if (-not $scriptBlock) { continue main }
                    # If not available in the current runspace, skip it
                    if (-not $scriptBlock.IsAvailable()) { continue main }
                    if ($Container) { $scriptBlock }
                    else { $scriptBlock.ScriptBlock }
                }
                #endregion Retrieve by name
                #region Search by filters
                'Search'
                {
                    foreach ($item in $allItems) {
                        # If not available in the current runspace, skip it
                        if (-not $item.IsAvailable()) { continue }
                        
                        if ($item.Name -notlike $nameText) { continue }
                        if ($sent -contains $item.Name) { continue }
                        
                        if ($Tag) {
                            $found = $false
                            foreach ($tagString in $Tag) {
                                if ($item.Tag -contains $tagString) { $found = $true }
                            }
                            if (-not $found) { continue }
                        }
                        if ($Description -and $item.Description -notlike $Description) { continue }
                        
                        $null = $sent.Add($item.Name)
                        $item
                    }
                }
                #endregion Search by filters
            }
        }
    }
}