Argument-transformation attribute classes

Argument-transformation attributes may be added to parameters used in scripts and functions. An argument-transformation attribute is used to convert the value of an argument for a parameter. The transformation operation is carried out before PowerShell completes the assignment to the variable, side-stepping type mismatch errors.

A class must be created that inherits from System.Management.Automation.ArgumentTransformationAttribute. The class must implement a Transform method.

The Transform method must accept two arguments with the System.Object and System.Management.Automation.EngineIntrinsics types. The argument names are arbitrary, the names used in the following example follow the naming used in the .NET reference: https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.argumenttransformationattribute.transform?view=powershellsdk-1.1.0.

Abstract methods must be implemented in inheriting classes. That the Transform method must be implemented in this class is indicated by the abstract modifier shown in the .NET documentation. The abstract modifier is discussed in the C# reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract.

The following example implements an argument-transformation attribute that converts a date string in the yyyyMMddHHmmss format back to DateTime before the assignment to the parameter is completed:

using namespace System.Management.Automation

class DateTimeStringTransformationAttribute : ArgumentTransformationAttribute {
[Object] Transform(
[EngineIntrinsics]$engineIntrinsics,
[Object]$inputData
) {
$date = Get-Date
if ($InputData -is [String] -and
[DateTime]::TryParseExact($inputData, 'yyyyMMddHHmmss', $null, 'None', [Ref]$date)) {

return $date
} elseif ($inputData -is [DateTime]) {
return $inputData
} else {
throw 'Unexpected date format'
}
}
}

The class does not need to contain anything other than the Transform method implementation. If the transformation is more complex, it may implement other helper methods. The following example moves DateTime.TryParseExact into a new method:

using namespace System.Management.Automation

class DateTimeStringTransformationAttribute : ArgumentTransformationAttribute {
Hidden [DateTime] $date

Hidden [Boolean] tryParseExact([String]$value) {
$parsedDate = Get-Date
$parseResult = [DateTime]::TryParseExact(
$value,
'yyyyMMddHHmmss',
$null,
'None',
[Ref]$parsedDate
)
$this.date = $parsedDate

return $parseResult
}

[Object] Transform(
[EngineIntrinsics]$engineIntrinsics,
[Object]$inputData
) {
if ($inputData -is [String] -and $this.TryParseExact($inputData)) {
return $this.date
} elseif ($inputData -is [DateTime]) {
return $inputData
} else {
throw 'Unexpected date format'
}
}
}

The new class may be used with a parameter, as shown here. Note that the Attribute string at the end of the class name may be omitted when it is used:

function Test-Transform {
param (
[DateTimeStringTransformation()]
[DateTime]$Date
)

Write-Host $Date
}

With this attribute in place, the function can be passed a date and time in a format that would not normally convert:

PS> Test-Transform -Date '20190210090000'
10/02/2019 09:00:00

As implementing a transformation attribute requires either restricting a command to PowerShell 5 or newer, or an implementation using C#, they rarely appear in code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.135.224