PSModuleUtils/Functions/ScriptBlock.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
# ===========================================================================
# ScriptBlock.ps1 ---------------------------------------------------------
# ===========================================================================

# function ----------------------------------------------------------------
# ---------------------------------------------------------------------------
function Get-ArgumentList {

    [CmdletBinding(PositionalBinding)]

    [OutputType([Void])]

    Param(        
        [Parameter(HelpMessage="Specifies parameters or parameter values to use when this cmdlet starts the process. If parameters or parameter values contain a space, they need surrounded with escaped double quotes.")]
        [System.String[]] $ArgumentList
    )

    Process{
        if ($ArgumentList.Count -eq 1) {
            return $ArgumentList -split " " | Where-Object {$_}
        }

        return $ArgumentList
    }
}

# function ----------------------------------------------------------------
# ---------------------------------------------------------------------------
function Join-ScriptBlock {
    
    <#
    .DESCRIPTION
        Join several scriptblocks and move existing 'using' directives at the beginning of the script.
 
    .OUTPUTS
        ScriptBlock. Joint scriptblocks.
    #>


    [CmdletBinding(PositionalBinding)]

    [OutputType([ScriptBlock])]

    Param(
        [Parameter(Position=1, Mandatory, ValueFromPipeline, HelpMessage="Array with objects of type [ScriptBlock] which are to be combined.")]
        [ScriptBlock[]] $Scripts
    )
    
    Process {

        # get all script blocks, convert them to strings as well as join these
        $script_joint = ""
        foreach ($script in $Scripts) {
            $script_joint += $script.ToString()
        }

        # search for 'using module' and 'using namespace' directives and get only unique ones
        $using_directive = ""
        $using_directive_search = "\s*(using\s+[a-z]+\s+[a-z\.]+)"
        [Regex]::Matches($script_joint, $using_directive_search, "IgnoreCase").Groups | Where-Object { $_.Name -eq 1} | Select-Object -ExpandProperty Value -Unique | ForEach-Object{
            $using_directive += "$_`n"
        }

        # generate a script block from singular script blocks and add 'using'-directives at its beginning
        $script_joint = $script_joint -replace $using_directive_search, ""
        return [ScriptBlock]::Create(
            $using_directive + $script_joint
        )
    }
}