PowerShell Proxy Function; Adding Exception Handling

*爱你&永不变心* 提交于 2019-12-24 14:54:33

问题


Question

Is there a simple way to add exception handling to a proxy cmd's process functionality?

As you can see below, I did find a way to do this, but I suspect there's a far cleaner solution.

Full Story

I want to create a proxy function for Get-ADUser which resolves the current issue with exceptions being thrown where an account cannot by found by identity. With the standard function the -ErrorAction parameter has no effect; my plan was simply to prevent such exceptions from being thrown.

I created a Proxy for Get-ADUser via the following: [System.Management.Automation.ProxyCommand]::Create((New-Object System.Management.Automation.CommandMetaData (Get-Command Get-ADUser))).

I then pasted the result into a function Get-AdUserNullIfNotExist { <# output of the above pasted here #> }.

If I alter the $ScriptCmd as below I get Exception calling "GetSteppablePipeliine ... Only a script block that contains exactly one pipeline or command can be converted. The same is try if I attempt to use trap instead of try-catch.

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

If instead I try to add this logic in the process block (as below) I get: Object reference not set to an instance of an object from $steppablePipeline.End(); presumably because the output from the proxy's pipeline isn't available to the $steppablePipeline's stream.

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

In the end I got this to work by copying the param block into a second $wrappedCmd variable and calling one from the other... but this feels horredously hacky.

$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} 

Full Code for Proxy Function

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

    #>
}

来源:https://stackoverflow.com/questions/37205808/powershell-proxy-function-adding-exception-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!