прокси-функция PowerShell; Добавление обработки исключений

Вопрос

Есть ли простой способ добавить обработку исключений в функциональность процесса прокси-команды?

Как вы можете видеть ниже, я нашел способ сделать это, но я подозреваю, что есть гораздо более чистое решение.

Полная история

Я хочу создать прокси-функцию для Get-ADUser, которая решает текущую проблему с созданием исключений, когда учетная запись не может быть найдена по идентификатору. В стандартной функции параметр -ErrorAction не действует; мой план состоял в том, чтобы просто предотвратить создание таких исключений.

Я создал прокси для Get-ADUser с помощью следующего: [System.Management.Automation.ProxyCommand]::Create((New-Object System.Management.Automation.CommandMetaData (Get-Command Get-ADUser))).

Затем я вставил результат в функцию Get-AdUserNullIfNotExist { <# output of the above pasted here #> }.

Если я изменю $ScriptCmd, как показано ниже, я получу Exception calling "GetSteppablePipeliine ... Only a script block that contains exactly one pipeline or command can be converted. То же самое, если я попытаюсь использовать trap вместо try-catch.

#$scriptCmd = {& $wrappedCmd @PSBoundParameters} 
$scriptCmd = {
    try {
        & $wrappedCmd @PSBoundParameters
    } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
        write-output $null
    } catch {
        throw
    }
} 

Если вместо этого я попытаюсь добавить эту логику в блок процесса (как показано ниже), я получу: Object reference not set to an instance of an object from $steppablePipeline.End(); предположительно потому, что вывод конвейера прокси недоступен для потока $steppablePipeline.

process
{
    try {
        $steppablePipeline.Process($_)
    } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
        $null #I've tried both with and without this line
    } catch {
        throw
    }
}

В конце концов я заставил это работать, скопировав блок param во вторую переменную $wrappedCmd и вызвав одну из другой... но это кажется ужасно хакерским.

$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-ADUser', [System.Management.Automation.CommandTypes]::Cmdlet)
$wrappedCmd2 = {
    [CmdletBinding(DefaultParameterSetName='Filter')]
    param(
        [Parameter(ParameterSetName='Filter', Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        ${Filter}
        ,
        [Parameter(ParameterSetName='LdapFilter', Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        ${LDAPFilter}
        ,
        [Alias('Property')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        ${Properties}
        ,
        [Parameter(ParameterSetName='Filter')]
        [Parameter(ParameterSetName='LdapFilter')]
        [ValidateRange(0, 2147483647)]
        [ValidateNotNullOrEmpty()]
        [int]
        ${ResultPageSize}
        ,
        [Parameter(ParameterSetName='LdapFilter')]
        [Parameter(ParameterSetName='Filter')]
        [System.Nullable[int]]
        ${ResultSetSize}
        ,
        [Parameter(ParameterSetName='LdapFilter')]
        [Parameter(ParameterSetName='Filter')]
        [ValidateNotNull()]
        [string]
        ${SearchBase}
        ,
        [Parameter(ParameterSetName='Filter')]
        [Parameter(ParameterSetName='LdapFilter')]
        [ValidateNotNullOrEmpty()]
        [Microsoft.ActiveDirectory.Management.ADSearchScope]
        ${SearchScope}
        ,
        [Parameter(ParameterSetName='Identity', Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [ValidateNotNull()]
        [Microsoft.ActiveDirectory.Management.ADUser]
        ${Identity}
        ,
        [Parameter(ParameterSetName='Identity')]
        [ValidateNotNullOrEmpty()]
        [string]
        ${Partition}
        ,
        [ValidateNotNullOrEmpty()]
        [string]
        ${Server}
        ,
        [ValidateNotNullOrEmpty()]
        [pscredential]
        [System.Management.Automation.CredentialAttribute()]
        ${Credential}
        ,
        [Microsoft.ActiveDirectory.Management.ADAuthType]
        ${AuthType}
    )
    try {
        & $wrappedCmd @PSBoundParameters 
    } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
        $null
    }
} 
$scriptCmd = {& $wrappedCmd2 @PSBoundParameters} 

Полный код функции прокси

function Get-AdUserNullIfNotExist {
    [CmdletBinding(DefaultParameterSetName='Filter')]
    param(
        [Parameter(ParameterSetName='Filter', Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        ${Filter}
        ,
        [Parameter(ParameterSetName='LdapFilter', Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        ${LDAPFilter}
        ,
        [Alias('Property')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        ${Properties}
        ,
        [Parameter(ParameterSetName='Filter')]
        [Parameter(ParameterSetName='LdapFilter')]
        [ValidateRange(0, 2147483647)]
        [ValidateNotNullOrEmpty()]
        [int]
        ${ResultPageSize}
        ,
        [Parameter(ParameterSetName='LdapFilter')]
        [Parameter(ParameterSetName='Filter')]
        [System.Nullable[int]]
        ${ResultSetSize}
        ,
        [Parameter(ParameterSetName='LdapFilter')]
        [Parameter(ParameterSetName='Filter')]
        [ValidateNotNull()]
        [string]
        ${SearchBase}
        ,
        [Parameter(ParameterSetName='Filter')]
        [Parameter(ParameterSetName='LdapFilter')]
        [ValidateNotNullOrEmpty()]
        [Microsoft.ActiveDirectory.Management.ADSearchScope]
        ${SearchScope}
        ,
        [Parameter(ParameterSetName='Identity', Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [ValidateNotNull()]
        [Microsoft.ActiveDirectory.Management.ADUser]
        ${Identity}
        ,
        [Parameter(ParameterSetName='Identity')]
        [ValidateNotNullOrEmpty()]
        [string]
        ${Partition}
        ,
        [ValidateNotNullOrEmpty()]
        [string]
        ${Server}
        ,
        [ValidateNotNullOrEmpty()]
        [pscredential]
        [System.Management.Automation.CredentialAttribute()]
        ${Credential}
        ,
        [Microsoft.ActiveDirectory.Management.ADAuthType]
        ${AuthType}
    )
    begin
    {
        try 
        {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) 
            {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-ADUser', [System.Management.Automation.CommandTypes]::Cmdlet)
            $wrappedCmd2 = {
                [CmdletBinding(DefaultParameterSetName='Filter')]
                param(
                    [Parameter(ParameterSetName='Filter', Mandatory=$true)]
                    [ValidateNotNullOrEmpty()]
                    [string]
                    ${Filter}
                    ,
                    [Parameter(ParameterSetName='LdapFilter', Mandatory=$true)]
                    [ValidateNotNullOrEmpty()]
                    [string]
                    ${LDAPFilter}
                    ,
                    [Alias('Property')]
                    [ValidateNotNullOrEmpty()]
                    [string[]]
                    ${Properties}
                    ,
                    [Parameter(ParameterSetName='Filter')]
                    [Parameter(ParameterSetName='LdapFilter')]
                    [ValidateRange(0, 2147483647)]
                    [ValidateNotNullOrEmpty()]
                    [int]
                    ${ResultPageSize}
                    ,
                    [Parameter(ParameterSetName='LdapFilter')]
                    [Parameter(ParameterSetName='Filter')]
                    [System.Nullable[int]]
                    ${ResultSetSize}
                    ,
                    [Parameter(ParameterSetName='LdapFilter')]
                    [Parameter(ParameterSetName='Filter')]
                    [ValidateNotNull()]
                    [string]
                    ${SearchBase}
                    ,
                    [Parameter(ParameterSetName='Filter')]
                    [Parameter(ParameterSetName='LdapFilter')]
                    [ValidateNotNullOrEmpty()]
                    [Microsoft.ActiveDirectory.Management.ADSearchScope]
                    ${SearchScope}
                    ,
                    [Parameter(ParameterSetName='Identity', Mandatory=$true, Position=0, ValueFromPipeline=$true)]
                    [ValidateNotNull()]
                    [Microsoft.ActiveDirectory.Management.ADUser]
                    ${Identity}
                    ,
                    [Parameter(ParameterSetName='Identity')]
                    [ValidateNotNullOrEmpty()]
                    [string]
                    ${Partition}
                    ,
                    [ValidateNotNullOrEmpty()]
                    [string]
                    ${Server}
                    ,
                    [ValidateNotNullOrEmpty()]
                    [pscredential]
                    [System.Management.Automation.CredentialAttribute()]
                    ${Credential}
                    ,
                    [Microsoft.ActiveDirectory.Management.ADAuthType]
                    ${AuthType}
                )
                try {
                    & $wrappedCmd @PSBoundParameters 
                } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
                    $null
                }
            } 
            $scriptCmd = {& $wrappedCmd2 @PSBoundParameters} 
            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
            $CopyOfSP = $steppablePipeline
        } catch {
            throw
        }
    }
    process
    {
        try {
            $steppablePipeline.Process($_)
        } catch {
            throw
        }
    }

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

    .ForwardHelpTargetName Get-ADUser
    .ForwardHelpCategory Cmdlet

    #>
}

person JohnLBevan    schedule 13.05.2016    source источник
comment
Извините, если это будет проверка кода; когда я начал задавать вопрос, я не нашел решения, и, поскольку решение, которое я нашел, кажется очень хакерским, я чувствовал, что оно подходит для любого сообщества.   -  person JohnLBevan    schedule 13.05.2016
comment
Я голосую за то, чтобы закрыть этот вопрос как не относящийся к теме, потому что этот вопрос относится к codereview.stackoverflow.com   -  person Johan    schedule 14.05.2016
comment
@Johan Почему вы считаете, что этот вопрос относится к Code Review? И, что более важно, какое правило в справочном центре нарушается так, что не соответствует теме переполнения стека?   -  person 200_success    schedule 14.05.2016
comment
нет MCVE, OP уже нашел решение, и это не похоже на практическую проблему, на которую можно ответить.   -  person Johan    schedule 14.05.2016