tutorial script learn ise ejemplos ejecutar desde comandos powershell scripting

learn - ¿Cómo creo un tipo personalizado en PowerShell para que se utilicen mis scripts?



powershell scripting tutorial (7)

Me gustaría poder definir y usar un tipo personalizado en algunos de mis scripts de PowerShell. Por ejemplo, imaginemos que necesitaba un objeto que tuviera la siguiente estructura:

Contact { string First string Last string Phone }

¿Cómo podría crear esto para poder usarlo en una función como la siguiente?

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

¿Es posible algo así o incluso recomendado en PowerShell?


Antes de PowerShell 3

El sistema de tipos extensibles de PowerShell originalmente no le permitió crear tipos concretos que pueda probar en comparación con la forma en que lo hizo en su parámetro. Si no necesita esa prueba, está bien con cualquiera de los otros métodos mencionados anteriormente.

Si desea un tipo real con el que pueda realizar o verificar con, como en su script de ejemplo ... no se puede hacer sin escribirlo en C # o VB.net y compilar. En PowerShell 2, puede usar el comando "Agregar-Tipo" para hacerlo bastante simple:

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

Nota histórica : en PowerShell 1 fue aún más difícil. Debes usar CodeDom manualmente, hay una función muy antigua secuencia de comandos new-struct en PoshCode.org que te ayudará. Tu ejemplo se convierte en:

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

Usar Add-Type o New-Struct le permitirá probar la clase en su param([Contact]$contact) y crear nuevas usando $contact = new-object Contact y así sucesivamente ...

En PowerShell 3

Si no necesitas una clase "real" a la que puedas enviar contenido, no tienes que usar la forma Add-Member que Steven y otros han demostrado anteriormente.

Desde PowerShell 2, puede usar el parámetro -Property para New-Object:

$Contact = New-Object PSObject -Property @{ First=""; Last=""; Phone="" }

Y en PowerShell 3, tenemos la capacidad de usar el acelerador PSCustomObject para agregar un TypeName:

[PSCustomObject]@{ PSTypeName = "Contact" First = $First Last = $Last Phone = $Phone }

Todavía obtienes un solo objeto, por lo que debes crear una función de New-Contact para asegurarte de que todos los objetos salen iguales, pero ahora puedes verificar fácilmente que un parámetro "es" uno de esos tipos decorando un parámetro con el atributo PSTypeName :

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

En PowerShell 5

En PowerShell 5 todo cambia, y finalmente obtuvimos class y enum como palabras clave de lenguaje para definir tipos (no hay struct pero está bien):

class Contact { # Optionally, add attributes to prevent invalid values [ValidateNotNullOrEmpty()][string]$First [ValidateNotNullOrEmpty()][string]$Last [ValidateNotNullOrEmpty()][string]$Phone # optionally, have a constructor to # force properties to be set: Contact($First, $Last, $Phone) { $this.First = $First $this.Last = $Last $this.Phone = $Phone } }

También obtuvimos una nueva forma de crear objetos sin usar New-Object : [Contact]::new() - de hecho, si mantuviste la clase simple y no defines un constructor, puedes crear objetos mediante la conversión de una tabla hash. (aunque sin un constructor, no habría forma de exigir que se establezcan todas las propiedades):

class Contact { # Optionally, add attributes to prevent invalid values [ValidateNotNullOrEmpty()][string]$First [ValidateNotNullOrEmpty()][string]$Last [ValidateNotNullOrEmpty()][string]$Phone } $C = [Contact]@{ First = "Joel" Last = "Bennett" }


Aquí está la ruta difícil para crear tipos personalizados y almacenarlos en una colección.

$Collection = @() $Object = New-Object -TypeName PSObject $Object.PsObject.TypeNames.Add(''MyCustomType.Contact.Detail'') Add-Member -InputObject $Object -memberType NoteProperty -name "First" -value "John" Add-Member -InputObject $Object -memberType NoteProperty -name "Last" -value "Doe" Add-Member -InputObject $Object -memberType NoteProperty -name "Phone" -value "123-4567" $Collection += $Object $Object = New-Object -TypeName PSObject $Object.PsObject.TypeNames.Add(''MyCustomType.Contact.Detail'') Add-Member -InputObject $Object -memberType NoteProperty -name "First" -value "Jeanne" Add-Member -InputObject $Object -memberType NoteProperty -name "Last" -value "Doe" Add-Member -InputObject $Object -memberType NoteProperty -name "Phone" -value "765-4321" $Collection += $Object Write-Ouput -InputObject $Collection


Este es el método de acceso directo:

$myPerson = "" | Select-Object First,Last,Phone


Existe el concepto de PSObject y Add-Member que podrías usar.

$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"

Esto produce como:

[8] » $contact First Last Phone ----- ---- ----- John Doe 123-4567

La otra alternativa (de la que soy consciente) es definir un tipo en C # / VB.NET y cargar ese ensamblaje en PowerShell para usarlo directamente.

Este comportamiento definitivamente se recomienda porque permite que otros scripts o secciones de su script trabajen con un objeto real.


La creación de tipos personalizados se puede hacer en PowerShell.
Kirk Munro en realidad tiene dos grandes publicaciones que detallan el proceso a fondo.

El libro Windows PowerShell In Action de Manning también tiene un ejemplo de código para crear un lenguaje específico de dominio para crear tipos personalizados. El libro es excelente, así que realmente lo recomiendo.

Si solo está buscando una forma rápida de hacer lo anterior, podría crear una función para crear el objeto personalizado como

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 }


La respuesta de Steven Murawski es genial, sin embargo, me gusta el objeto de selección más corto (o más bien el más ordenado en lugar de utilizar la sintaxis de agregar miembro):

function New-Person() { param ($FirstName, $LastName, $Phone) $person = new-object PSObject | select-object First, Last, Phone $person.First = $FirstName $person.Last = $LastName $person.Phone = $Phone return $person }


Sorprendido, nadie mencionó esta opción simple (vs 3 o posterior) para crear objetos personalizados:

[PSCustomObject]@{ First = $First Last = $Last Phone = $Phone }

El tipo será PSCustomObject, aunque no es un tipo personalizado real. Pero es probablemente la forma más fácil de crear un objeto personalizado.