functions/meta/Get-PSFPipeline.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
function Get-PSFPipeline
{
<#
    .SYNOPSIS
        Generates meta-information for the pipeline from the calling command.
     
    .DESCRIPTION
        Generates meta-information for the pipeline from the calling command.
     
    .EXAMPLE
        PS C:\> Get-Pipeline
     
        Generates meta-information for the pipeline from the calling command.
#>

    [OutputType([PSFramework.Meta.Pipeline])]
    [CmdletBinding()]
    param (
        
    )
    
    begin
    {
        function Get-PrivateProperty
        {
            [CmdletBinding()]
            param (
                $Object,
                
                [string]
                $Name,
                
                [ValidateSet('Any', 'Field', 'Property')]
                [string]
                $Type = 'Any'
            )
            
            if ($null -eq $Object) { return }
            
            $typeObject = $Object.GetType()
            [System.Reflection.BindingFlags]$flags = "NonPublic, Instance"
            switch ($Type)
            {
                'Field'
                {
                    $field = $typeObject.GetField($Name, $flags)
                    $field.GetValue($Object)
                }
                'Property'
                {
                    $property = $typeObject.GetProperty($Name, $flags)
                    $property.GetValue($Object)
                }
                'Any'
                {
                    $field = $typeObject.GetField($Name, $flags)
                    if ($field) { return $field.GetValue($Object) }
                    $property = $typeObject.GetProperty($Name, $flags)
                    $property.GetValue($Object)
                }
            }
        }
    }
    process
    {
        $callerCmdlet = (Get-PSCallStack)[1].GetFrameVariables()["PSCmdlet"].Value
        
        $commandRuntime = Get-PrivateProperty -Object $callerCmdlet -Name _commandRuntime -Type Field
        $pipelineProcessor = Get-PrivateProperty -Object $commandRuntime -Name PipelineProcessor -Type Property
        $localPipeline = Get-PrivateProperty -Object $pipelineProcessor -Name LocalPipeline -Type Property
        
        $pipeline = New-Object PSFramework.Meta.Pipeline -Property @{
            InstanceId = $localPipeline.InstanceId
            StartTime  = Get-PrivateProperty -Object $localPipeline -Name _pipelineStartTime -Type Field
            Text       = Get-PrivateProperty -Object $localPipeline -Name HistoryString -Type Property
            PipelineItem = $localPipeline
        }
        
        if ($pipeline.Text)
        {
            $tokens = $null
            $errorItems = $null
            $ast = [System.Management.Automation.Language.Parser]::ParseInput($pipeline.Text, [ref]$tokens, [ref]$errorItems)
            $pipeline.Ast = $ast
            
            $baseItem = $ast.EndBlock.Statements[0]
            if ($baseItem -is [System.Management.Automation.Language.AssignmentStatementAst])
            {
                $pipeline.OutputAssigned = $true
                $pipeline.OutputAssignedTo = $baseItem.Left
                $baseItem = $baseItem.Right.PipelineElements
            }
            else { $baseItem = $baseItem.PipelineElements }
            
            if ($baseItem[0] -is [System.Management.Automation.Language.CommandExpressionAst])
            {
                if ($baseItem[0].Expression -is [System.Management.Automation.Language.VariableExpressionAst])
                {
                    $pipeline.InputFromVariable = $true
                    $pipeline.InputVariable = $baseItem[0].Expression.VariablePath.UserPath
                }
                else { $pipeline.InputDirect = $true }
                if ($baseItem[0].Expression -is [System.Management.Automation.Language.ConstantExpressionAst])
                {
                    $pipeline.InputValue = $baseItem[0].Expression.Value
                }
                elseif ($baseItem[0].Expression -is [System.Management.Automation.Language.ArrayLiteralAst])
                {
                    $pipeline.InputValue = @()
                    foreach ($element in $baseItem[0].Expression.Elements)
                    {
                        if ($element -is [System.Management.Automation.Language.ConstantExpressionAst])
                        {
                            $pipeline.InputValue += $element.Value
                        }
                        else { $pipeline.InputValue += $element }
                    }
                }
                else { $pipeline.InputValue = $baseItem[0].Expression }
            }
        }
        
        $commands = Get-PrivateProperty -Object $pipelineProcessor -Name Commands -Type Property
        $index = 0
        foreach ($command in $commands)
        {
            $commandItem = Get-PrivateProperty -Object $command -Name Command
            $pipeline.Commands.Add((New-Object PSFramework.Meta.PipelineCommand($pipeline.InstanceId, $index, (Get-PrivateProperty -Object $command -Name CommandInfo), $commandItem.MyInvocation, $commandItem)))
            $index++
        }
        
        $pipeline
    }
}