views:

1988

answers:

4

I would like to be able to define and use a custom type in some of my PowerShell scripts. For example, let's pretend I had a need for an object that had the following structure:

Contact
{
    string First
    string Last
    string Phone
}

How would I go about creating this so that I could use it in function like the following:

function PrintContact
{
    param( [Contact]$contact )
    "Customer Name is " + $contact.First + " " + $contact.Last
    "Customer Phone is " + $contact.Phone 
}

Is something like this possible, or even recommended in PowerShell?

+4  A: 

There is the concept of PSObject and Add-Member that you could use.

$contact = New-Object PSObject

$contact | Add-Member -memberType NoteProperty -name "First" -value "John"
$contact | Add-Member -memberType NoteProperty -name "Last" -value "Doe"
$contact | Add-Member -memberType NoteProperty -name "Phone" -value "123-4567"

This outputs like:

[8] » $contact

First                                       Last                                       Phone
-----                                       ----                                       -----
John                                        Doe                                        123-4567

The other alternative (that I'm aware of) is to define a type in C#/VB.NET and load that assembly into PowerShell for use directly.

This behavior is definitely encouraged because it allows other scripts or sections of your script work with an actual object.

David Mohundro
+7  A: 

Creating custom types can be done in PowerShell.
Kirk Munro actually has two great posts that detail the process thoroughly.

The book Windows PowerShell In Action by Manning also has a code sample for creating a domain specific language to create custom types. The book is excellent all around, so I really recommend it.

If you are just looking for a quick way to do the above, you could create a function to create the custom object like

function New-Person()
{
  param ($FirstName, $LastName, $Phone)

  $person = new-object PSObject

  $person | add-member -type NoteProperty -Name First -Value $FirstName
  $person | add-member -type NoteProperty -Name Last -Value $LastName
  $person | add-member -type NoteProperty -Name Phone -Value $Phone

  return $person
}
Steven Murawski
+1  A: 

This is the shortcut method:

$myPerson = "" | Select-Object First,Last,Phone
EBGreen
+4  A: 

PowerShell's Adaptive Type System doesn't let you create concrete types you can test against the way you did in your parameter. If you don't need that test, you're fine with any of the methods mentioned above.

If you want an actual type that you can cast to or type-check with, as in your example script ... it can't be done without compiling. In the v2 CTP2 they have an "add-Type" command which would let you do it that simply:

add-type @"
public struct contact {
   public string First;
   public string Last;
   public string Phone;
}
"@

Until then, you need to use CodeDom, there is a new-struct script on PoshCode.org which will help. Your example becomes:

New-Struct Contact @{
    First=[string];
    Last=[string];
    Phone=[string];
}

Using the New-Struct script will let you actually test the class in your param([Contact]$contact) and make new ones using $contact = new-object Contact and so on...

Jaykul