Tout ce que vous vouliez savoir sur PSCustomObject

author
9 minutes, 24 seconds Read
  • 10/05/2020
  • 8 minutes à lire
    • j
    • .

    • m
    • s
    • j
    • c

PSCustomObjects sont un excellent outil à ajouter à votre ceinture d’outils PowerShell. Commençons par les principes de base et progressons vers les fonctionnalités plus avancées. L’idée derrière l’utilisation d’un PSCustomObject est d’avoir un moyen simple de créer des données structurées. Jetez un œil au premier exemple et vous aurez une meilleure idée de ce que cela signifie.

Note

La version originale de cet article est apparue sur le blog écrit par @KevinMarquette. L’équipe dePowerShell remercie Kevin d’avoir partagé ce contenu avec nous. Veuillez consulter son blog àPowerShellExplained.com.

Création d’un PSCustomObject

J’adore utiliser dans PowerShell. Créer un objet utilisable n’a jamais été aussi facile.Pour cette raison, je vais passer en revue toutes les autres façons dont vous pouvez créer un objet, mais je dois mentionner que la plupart de ces exemples sont PowerShell v3.0 et plus récents.

$myObject = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

Cette méthode fonctionne bien pour moi parce que j’utilise des hashtables pour à peu près tout. Mais il y a des moments où j’aimerais que PowerShell traite les hashtables plus comme un objet. Le premier endroit où vous remarquez la différence est lorsque vous voulez utiliser Format-Table ou Export-CSV et que vous réalisez que le ahashtable est juste une collection de paires clé/valeur.

Vous pouvez alors accéder et utiliser les valeurs comme vous le feriez avec un objet normal.

$myObject.Name

Conversion d’un hashtable

Pendant que je suis sur le sujet, saviez-vous que vous pouviez faire ceci :

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = $myHashtable

Je préfère effectivement créer l’objet dès le début mais il y a des fois où vous devez travailler avec ahashtable d’abord. Cet exemple fonctionne parce que le constructeur prend un hashtable pour les objectproperties. Il est important de noter que si cette méthode fonctionne, elle n’est pas exactement équivalente. La plus grande différence est que l’ordre des propriétés n’est pas préservé.

Approche héritée

Vous avez peut-être vu des gens utiliser New-Object pour créer des objets personnalisés.

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = New-Object -TypeName PSObject -Property $myHashtable

Cette façon est assez lente mais elle peut être votre meilleure option sur les premières versions de PowerShell.

Enregistrement dans un fichier

Je trouve que la meilleure façon d’enregistrer une table de hachage dans un fichier est de l’enregistrer en JSON. Vous pouvez le réimporter dans un

$myObject | ConvertTo-Json -depth 1 | Set-Content -Path $Path$myObject = Get-Content -Path $Path | ConvertFrom-Json

Je couvre d’autres façons d’enregistrer des objets dans un fichier dans mon article surLes nombreuses façons de lire et d’écrire dans des fichiers.

Travailler avec les propriétés

Ajouter des propriétés

Vous pouvez toujours ajouter de nouvelles propriétés à votre PSCustomObject avec Add-Member.

$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'$myObject.ID

Supprimer des propriétés

Vous pouvez également supprimer des propriétés d’un objet.

$myObject.psobject.properties.remove('ID')

Le psobject est une propriété cachée qui vous donne accès aux métadonnées de l’objet de base.

Enumération des noms de propriétés

Parfois, vous avez besoin d’une liste de tous les noms de propriétés sur un objet.

$myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name

On peut aussi obtenir cette même liste à partir de la propriété psobject.

$myobject.psobject.properties.name

Accès dynamique aux propriétés

J’ai déjà mentionné que vous pouvez accéder directement aux valeurs des propriétés.

$myObject.Name

Vous pouvez utiliser une chaîne de caractères pour le nom de la propriété et cela fonctionnera toujours.

$myObject.'Name'

Nous pouvons faire un pas de plus et utiliser une variable pour le nom de la propriété.

$property = 'Name'$myObject.$property

Je sais que cela semble étrange, mais cela fonctionne.

Convertir PSCustomObject en une table de hachage

Pour continuer sur la dernière section, vous pouvez marcher dynamiquement sur les propriétés et créer une table de hachage à partir de celles-ci.

$hashtable = @{}foreach( $property in $myobject.psobject.properties.name ){ $hashtable = $myObject.$property}

Tester les propriétés

Si vous avez besoin de savoir si une propriété existe, vous pourriez simplement vérifier que cette propriété a une valeur.

if( $null -ne $myObject.ID )

Mais si la valeur peut être $null, vous pouvez vérifier si elle existe en vérifiant lepsobject.properties pour elle.

if( $myobject.psobject.properties.match('ID').Count )

Ajouter des méthodes d’objet

Si vous avez besoin d’ajouter une méthode de script à un objet, vous pouvez le faire avec Add-Member et unScriptBlock. Vous devez utiliser la variable automatique this référençant l’objet courant. Voici unscriptblock pour transformer un objet en une table de hachage. (même code form le dernier exemple)

Puis nous l’ajoutons à notre objet comme une propriété de script.

Puis nous pouvons appeler notre fonction comme ceci:

$myObject.ToHashtable()

Objets vs Types de valeur

Les objets et les types de valeur ne gèrent pas les affectations de variables de la même manière. Si vous assignez des types de valeur l’un à l’autre, seule la valeur est copiée dans la nouvelle variable.

$first = 1$second = $first$second = 2

Dans ce cas, $first vaut 1 et $second vaut 2.

Les variables d’objet contiennent une référence à l’objet réel. Lorsque vous assignez un objet à une nouvelle variable, ils font toujours référence au même objet.

$third = @{Key=3}$fourth = $third$fourth.Key = 4

Parce que $third et $fourth font référence à la même instance d’un objet, $third.key et$fourth.Key valent tous deux 4.

psobject.copy()

Si vous avez besoin d’une vraie copie d’un objet, vous pouvez le cloner.

$third = @{Key=3}$fourth = $third.psobject.copy()$fourth.Key = 4

Clone crée une copie superficielle de l’objet. Ils ont maintenant des instances différentes et $third.key est 3et $fourth.Key est 4 dans cet exemple.

J’appelle cela une copie superficielle car si vous avez des objets imbriqués. (où les propriétés contiennent d’autres objets). Seules les valeurs de niveau supérieur sont copiées. Les objets enfants feront référence les uns aux autres.

PSTypeName pour les types d’objets personnalisés

Maintenant que nous avons un objet, il y a quelques choses supplémentaires que nous pouvons faire avec lui qui peuvent ne pas être aussi évidentes. La première chose que nous devons faire est de lui donner un PSTypeName. C’est la façon la plus courante dont je vois les gens le faire :

$myObject.PSObject.TypeNames.Insert(0,"My.Object")

J’ai récemment découvert une autre façon de le faire grâce à ce post de /u/markekraus. J’ai fait un peu de recherche et plus de posts sur l’idée d’Adam Bertram et Mike Shepard où ils parlent de cette approche qui vous permet de le définir en ligne.

$myObject = @{ PSTypeName = 'My.Object' Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

J’aime comment joliment cela s’intègre juste dans le langage. Maintenant que nous avons un objet avec un typename approprié, nous pouvons faire d’autres choses.

Note

Vous pouvez également créer des types PowerShell personnalisés en utilisant des classes PowerShell. Pour plus d’informations, voirPowerShell Class Overview.

Utilisation de DefaultPropertySet (le long chemin)

PowerShell décide pour nous des propriétés à afficher par défaut. Beaucoup de commandes natives ont un.ps1xml fichier de formatage qui fait tout le travail lourd. D’après ce post de Boe Prox, il y a un autre moyen pour nous de faire cela sur notre objet personnalisé en utilisant seulement PowerShell. Nous pouvons lui donner unMemberSet pour qu’il l’utilise.

Maintenant quand mon objet tombe juste dans le shell, il ne montrera que ces propriétés par défaut.

Update-TypeData avec DefaultPropertySet

C’est bien mais j’ai récemment vu une meilleure façon en regardantPowerShell unplugged 2016 avec Jeffrey Snover & Don Jones. Jeffrey utilisaitUpdate-TypeData pour spécifier les propriétés par défaut.

$TypeData = @{ TypeName = 'My.Object' DefaultDisplayPropertySet = 'Name','Language'}Update-TypeData @TypeData

C’est assez simple pour que je puisse presque m’en souvenir si je n’avais pas ce post comme référence rapide. Maintenant, je peux facilement créer des objets avec beaucoup de propriétés et toujours leur donner une belle vue propre en les regardant depuis le shell. Si j’ai besoin d’accéder ou de voir ces autres propriétés, elles sont toujours là.

$myObject | Format-List *

Update-TypeData avec ScriptProperty

Autre chose que j’ai retirée de cette vidéo, c’est la création de propriétés de script pour vos objets. Ce serait un bon moment pour souligner que cela fonctionne aussi pour les objets existants.

Vous pouvez faire cela avant que votre objet soit créé ou après et cela fonctionnera toujours. C’est ce qui rend ceci différent de l’utilisation de Add-Member avec une propriété de script. Lorsque vous utilisez Add-Member de la manière Ireferenced plus tôt, il n’existe que sur cette instance spécifique de l’objet. Celle-ci s’applique à tous les objets avec ce TypeName.

Paramètres de fonction

Vous pouvez maintenant utiliser ces types personnalisés pour les paramètres dans vos fonctions et vos scripts. Vous pouvez faire en sorte qu’unefonction crée ces objets personnalisés et les passe ensuite dans d’autres fonctions.

param( $Data )

PowerShell exige que l’objet soit du type que vous avez spécifié. Il jette une erreur de validation si le type ne correspond pas automatiquement pour vous épargner l’étape de test pour cela dans votre code. Un excellent exemple de laisser PowerShell faire ce qu’il fait le mieux.

Function OutputType

Vous pouvez également définir un OutputType pour vos fonctions avancées.

function Get-MyObject{ param ( ...

La valeur de l’attribut OutputType est seulement une note de documentation. Elle n’est pas dérivée du code de la fonction ou comparée à la sortie réelle de la fonction.

La principale raison pour laquelle vous utiliseriez un type de sortie est que les méta-informations sur votre fonctionreflètent vos intentions. Des choses comme Get-Command et Get-Help dont votre environnement de développement peut tirer parti. Si vous voulez plus d’informations, alors jetez un coup d’œil à l’aide pour cela:about_Functions_OutputTypeAttribute.

Avec cela dit, si vous utilisez Pester pour tester l’unité de vos fonctions, alors ce serait une bonne idée de valider les objets de sortie correspondent à votre OutputType. Cela pourrait attraper les variables qui tombent juste sur le tuyau quand elles ne devraient pas.

Pensées finales

Le contexte de ceci était tout au sujet de , mais beaucoup de ces informations s’appliquent aux objets en général.

J’ai vu la plupart de ces fonctionnalités en passant avant mais je ne les ai jamais vues présentées comme une collection d’informations sur PSCustomObject. Juste la semaine dernière, je suis tombé sur une autre et j’ai été surpris de ne pas l’avoir vue avant. J’ai voulu rassembler toutes ces idées pour que vous puissiez, je l’espère, voir la vue d’ensemble et en être conscient lorsque vous aurez l’occasion de les utiliser. J’espère que vous avez appris quelque chose et que vous pourrez trouver un moyen d’intégrer ces idées dans vos scripts.

Similar Posts

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.