Nelson Monserrate
Nelson Monserrate

Reputation: 33

How to convert parameter type into a different object type

I'm doing some scripting in PowerShell, and I was wondering if there's a way to "declare" a parameter "X" the same way parameter "-Credential" is declared, for example in Get-WMIObject cmdlet.

Let me be more specific. The Credential parameter in almost all cmdlets is a PSCredential Object. But, the argument can be either a PSCredential Object or, a String Object with the username.

[CmdletBinding()]
param ([Parameter(Mandatory = $false)]
       [System.Management.Automation.PSCredential]
       $Credential)

The problem comes when passing a string. Of course, an argument transformation on the parameter cannot be done. Cannot convert the type "System.String" into a type PSCrendential.

Upvotes: 2

Views: 7143

Answers (4)

Nelson Monserrate
Nelson Monserrate

Reputation: 33

A bit more of info :)

PowerShell has one of these argument transformations included for use with credentials, so whenever you write a script that has a PSCredential parameter, you should decorate it with the CredentialAttribute like this:

param([Parameter(Mandatory = $false)]
      [System.Management.Automation.PSCredential]
      [System.Management.Automation.Credential()]$Credential =  [System.Management.Automation.PSCredential]::Empty)

That one’s a little confusing because you leave off the “Attribute” part of the attribute’s name (ie: you don’t have to specify [System.Management.Automation.CredentialAttribute()]), so at first glance, it looks like you’re specifying the Credential type twice. Of course, in reality this is another use of parenthesis in PowerShell. To specify an attribute, you use square braces as with types, but with parenthesis in them (even if the attribute doesn’t require any parameters).

http://huddledmasses.org/more-custom-attributes-for-powershell-parameters/

Upvotes: 1

Jeffery Hicks
Jeffery Hicks

Reputation: 943

This is how I have done it. I declare the parameter like this:

[Parameter(Position=2)] [object]$Credential

Then at the beginning of the script:

begin {
        Write-Verbose -Message "Starting  $($myinvocation.mycommand)"
        write-verbose -Message "Using volume $($volume.toUpper())"
        #convert credential to a PSCredential if a string was passed.
        if ( $credential -is [system.management.automation.psCredential]) {
            Write-Verbose "Using PSCredential for $($credential.username)"
        }
        ElseIf ($Credential) {
            Write-Verbose "Getting PSCredential for $credential"
            $Credential=Get-Credential $credential
        }
    } #Begin

Upvotes: 0

Shay Levy
Shay Levy

Reputation: 126712

Give this a try:

param(
    [System.Management.Automation.Credential()]
    $Credential=[System.Management.Automation.PSCredential]::Empty
)

As to parameter argument transformation, check this awesome script:

http://poshcode.org/3024

Upvotes: 5

OldFart
OldFart

Reputation: 2479

If you declare a function parameter to have type [T], when you invoke the function you can supply any object of type [X] where [T] has a single-parameter constructor that takes type [X].

In other words, if you can construct a [T] from a [String], you can invoke the function with either a [T] or a [String].

Upvotes: 0

Related Questions