Вопрос
Есть ли простой способ добавить обработку исключений в функциональность процесса прокси-команды?
Как вы можете видеть ниже, я нашел способ сделать это, но я подозреваю, что есть гораздо более чистое решение.
Полная история
Я хочу создать прокси-функцию для 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
#>
}