Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use custom PowerShell defined type for parameter type specification

Tags:

powershell

I define a custom PowerShell type with New-Object. I would like a parameter to be of my defined type, is it possible to specify this type in a declarative way? The following code gives me the error: "Unable to find type [BuildActionContext]: make sure that the assembly containing this type is loaded."

Can we specify the type declarative, or should I just test the type of the specified object?

Not working code:

$buildActionContext = New-Object -TypeName PSObject -Property @{
# Given properties
BuildAction = "Build"; 
}
$buildActionContext.PSObject.TypeNames.Insert(0, 'BuildActionContext')

function DoSomethingWithBuildActionContext
{
[CmdletBinding()]
param
(
    [Parameter(Mandatory=$true)][BuildActionContext]$Context
)

Write-Host "Build action: $($Context.BuildAction)"
}

DoSomethingWithBuildActionContext -Context $buildActionContext

Working code, but can it be done differently:

$buildActionContext = New-Object -TypeName PSObject -Property @{
        # Given properties
        BuildAction = "Build"; 
    }
    $buildActionContext.PSObject.TypeNames.Insert(0, 'BuildActionContext')

function DoSomethingWithBuildActionContext
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true)]$Context
    )

    if ($Context.PSObject.TypeNames[0] -ne 'BuildActionContext')
    {
        throw "Context parameter not of type 'BuildActionContext'"
    }

    Write-Host "Build action: $($Context.BuildAction)"
}

DoSomethingWithBuildActionContext -Context $buildActionContext
DoSomethingWithBuildActionContext -Context "Hello world"

Note: Second call gives the exception message.

like image 401
Serge van den Oever Avatar asked Sep 03 '10 11:09

Serge van den Oever


1 Answers

I would expect that only real .NET types can be used to specify parameter type. According to Essential PowerShell: Name your custom object types the custom type names are mainly used for formatting.

You can check the type names manually via ValidateScript attribute:

function DoSomethingWithBuildActionContext { 
  param(
    [Parameter()]
    [ValidateScript({ $_.PSObject.TypeNames[0] -eq 'BuildActionContext' })]
    $context
  )
  Write-Host "Build action: $($Context.BuildAction)"
}
like image 154
stej Avatar answered Oct 05 '22 03:10

stej