Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 从一个函数到另一个函数的内部管道_Powershell - Fatal编程技术网

Powershell 从一个函数到另一个函数的内部管道

Powershell 从一个函数到另一个函数的内部管道,powershell,Powershell,我有一个模块,它有以下两个功能,几乎相同: <# .SYNOPSIS Retrieves a VApp from VCloud. #> Function Get-VApp { [CmdletBinding()] [OutputType([System.Xml.XmlElement])] Param( [Parameter(Mandatory = $true)] [System.Xml.XmlElement] $S

我有一个模块,它有以下两个功能,几乎相同:

<#
    .SYNOPSIS
    Retrieves a VApp from VCloud.
#>
Function Get-VApp
{
    [CmdletBinding()]
    [OutputType([System.Xml.XmlElement])]
    Param(
        [Parameter(Mandatory = $true)]
        [System.Xml.XmlElement] $Session,
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]] $VAppName
    )
    Begin {
        [System.Xml.XmlElement] $queryList = $Session.GetQueryList();
        [System.Xml.XmlElement[]] $vAppRecords = $queryList.GetVAppsByRecords().VAppRecord;
    }
    Process {
        ForEach ($VAN in $VAppName)
        {
            $vAppRecords |
            Where-Object { $_.name -eq $VAN } |
            ForEach-Object { $_.Get(); }
        }
    }
    End
    {
        #
    }
}
但很明显,管道把事情搞砸了。为了提高效率,我不会多次调用Begin块中的代码,我希望找到一种方法,在不必批处理记录的情况下“很好地”处理管道。

该类旨在包装启用管道的命令,而不会破坏管道支持

你甚至不需要知道如何设置它,它将生成脚手架

因此,让我们首先为
Get-VAppRecord
创建一个代理函数:

$GetVAppRecordCommand = Get-Command Get-VAppRecord
$GetVAppRecordCommandMetadata = [System.Management.Automation.CommandMetadata]::new($GetVAppRecordCommand)

# returns the body of the new proxy functions
[System.Management.Automation.ProxyCommand]::Create($GetVAppRecordCommandMetadata)
。。。然后我们只需要在它的
进程
块中添加
Get()
调用:

function Get-VApp {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, Position=0)]
        [System.Xml.XmlElement]
        ${Session},

        [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true)]
        [string[]]
        ${VAppName})

    begin
    {
        try {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
            {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-VAppRecord', [System.Management.Automation.CommandTypes]::Function)
            $scriptCmd = {& $wrappedCmd @PSBoundParameters }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline()
            $steppablePipeline.Begin($MyInvocation.ExpectingInput) # Many examples use $PSCmdlet; however setting this ensures that $steppablePipeline.Process() returns the output of the inner function.
        } catch {
            throw
        }
    }

    process
    {
        try {
            $steppablePipeline.Process($_) |ForEach-Object {
                # call Get() on the record
                $_.Get()
            }
        } catch {
            throw
        }
    }

    end
    {
        try {
            $steppablePipeline.End()
        } catch {
            throw
        }
    }
}

为什么需要
ForEach对象
调用?要明确。这看起来就像我要找的。我到家后去看看。PowerShell的最低版本是什么?好的-我已经尝试了代码,但问题是内部函数将其输出直接返回到外部函数的管道,而Process()函数的输出是一个空数组。@MarkBertenshaw我还不完全清楚这是什么意思。你看到了什么影响?有错误吗?我对此做了更多的研究,我还没有找到一个不使用上述锅炉板代码的SteppablePipeline示例。在我看到的所有示例中,其目的基本上是重新定义现有命令,并且进程块中没有条件分支。我想做的唯一方法是通过脚本级变量将输出发送回。这是一种糟糕的方法,因为现在我必须检测如何调用内部函数,并根据是通过外部函数调用还是直接调用来进行不同的处理。在阅读了一些糟糕的文档和大量实验后,我发现缺少的信息是Begin()方法应给定一个布尔参数。特别是,该值应为$MyInvocation.ExpectingInput。这可以处理通过管道或指定参数获取值的外部函数。
$GetVAppRecordCommand = Get-Command Get-VAppRecord
$GetVAppRecordCommandMetadata = [System.Management.Automation.CommandMetadata]::new($GetVAppRecordCommand)

# returns the body of the new proxy functions
[System.Management.Automation.ProxyCommand]::Create($GetVAppRecordCommandMetadata)
function Get-VApp {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, Position=0)]
        [System.Xml.XmlElement]
        ${Session},

        [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true)]
        [string[]]
        ${VAppName})

    begin
    {
        try {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
            {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-VAppRecord', [System.Management.Automation.CommandTypes]::Function)
            $scriptCmd = {& $wrappedCmd @PSBoundParameters }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline()
            $steppablePipeline.Begin($MyInvocation.ExpectingInput) # Many examples use $PSCmdlet; however setting this ensures that $steppablePipeline.Process() returns the output of the inner function.
        } catch {
            throw
        }
    }

    process
    {
        try {
            $steppablePipeline.Process($_) |ForEach-Object {
                # call Get() on the record
                $_.Get()
            }
        } catch {
            throw
        }
    }

    end
    {
        try {
            $steppablePipeline.End()
        } catch {
            throw
        }
    }
}