web-dev-qa-db-fra.com

Impression des propriétés d'un objet dans Powershell

Lorsque je travaille dans la console interactive si je définis un nouvel objet et lui attribue des valeurs de propriété comme ceci:

$obj = New-Object System.String
$obj | Add-Member NoteProperty SomeProperty "Test"

Ensuite, lorsque je tape le nom de ma variable dans la fenêtre interactive, Powershell me fournit un résumé des propriétés et des valeurs de l'objet:

PS C:\demo> $obj
SomeProperty                                                                                                                                                                                  
------------                                                                                                                                                                                  
Test

Je veux fondamentalement faire juste cela, mais à partir d'une fonction dans un script. La fonction crée un objet et définit certaines valeurs de propriété. Je souhaite qu’elle affiche un résumé des valeurs d’objet dans la fenêtre Powershell avant de renvoyer. J'ai essayé d'utiliser Write-Host dans la fonction:

Write-Host $obj

Mais cela ne fait que sortir le type de l'objet et non le résumé:

System.Object

Comment ma fonction peut-elle générer un résumé des valeurs de propriété de l'objet dans la fenêtre Powershell?

93
John

Essaye ça:

Write-Host ($obj | Format-Table | Out-String)

ou

Write-Host ($obj | Format-List | Out-String)
153
mjolinor

Ma solution à ce problème consistait à utiliser le bloc $ () sub-expression block .

Add-Type -Language CSharp @"
public class Thing{
    public string Name;
}
"@;

$x = New-Object Thing

$x.Name = "Bill"

Write-Output "My name is $($x.Name)"
Write-Output "This won't work right: $x.Name"

Donne:

My name is Bill
This won't work right: Thing.Name
22
David Peters

Imprimer les propriétés et les valeurs des objets dans Powershell. Ci-dessous exemples fonctionnent bien pour moi.

$ pool = Get-Item "IIS:\AppPools.NET v4.5"

$ pool | Get-Member

   TypeName: Microsoft.IIs.PowerShell.Framework.ConfigurationElement#system.applicationHost/applicationPools#add

Name                        MemberType            Definition
----                        ----------            ----------
Recycle                     CodeMethod            void Recycle()
Start                       CodeMethod            void Start()
Stop                        CodeMethod            void Stop()
applicationPoolSid          CodeProperty          Microsoft.IIs.PowerShell.Framework.CodeProperty
state                       CodeProperty          Microsoft.IIs.PowerShell.Framework.CodeProperty
ClearLocalData              Method                void ClearLocalData()
Copy                        Method                void Copy(Microsoft.IIs.PowerShell.Framework.ConfigurationElement ...
Delete                      Method                void Delete()
...

$ pool | Select-Object -Property * # Vous pouvez omettre -Property

name                        : .NET v4.5
queueLength                 : 1000
autoStart                   : True
enable32BitAppOnWin64       : False
managedRuntimeVersion       : v4.0
managedRuntimeLoader        : webengine4.dll
enableConfigurationOverride : True
managedPipelineMode         : Integrated
CLRConfigFile               :
passAnonymousToken          : True
startMode                   : OnDemand
state                       : Started
applicationPoolSid          : S-1-5-82-271721585-897601226-2024613209-625570482-296978595
processModel                : Microsoft.IIs.PowerShell.Framework.ConfigurationElement
...
14
cateyes

Conseil n ° 1

Ne jamais utiliser Write-Host.

Conseil n ° 12

La méthode appropriée pour générer des informations à partir d'une cmdlet ou d'une fonction PowerShell consiste à créer un objet contenant vos données, puis à écrire cet objet dans le pipeline à l'aide de Write-Output.

- Don Jones: Maître PowerShell

Idéalement, votre script devrait créer vos objets ($obj = New-Object -TypeName psobject -Property @{'SomeProperty'='Test'}), puis il suffit de faire un Write-Output $objects. Vous dirigeriez la sortie vers Format-Table.

PS C:\> Run-MyScript.ps1 | Format-Table

Ils devraient vraiment appeler PowerShell PowerObjectandPipingShell.

10
E.V.I.L.
# Json to object
$obj = $obj | ConvertFrom-Json
Write-Host $obj.PropertyName
1
Ramanujam Allam

Quelques notes générales.


$obj | Select-Object  $obj | Select-Object -Property *

Ce dernier affichera all propriétés non-intrinsèques, non générées par le compilateur. L'ancien ne pas semble afficher (toujours) tout ​​Types de propriétés (dans mes tests, il apparaît toujours que CodePropertyMemberType est cohérent - aucune garantie ici).


Certains commutateurs à connaître pour Get-Member

  • Get-Member ne not ​​obtenir des membres statiques par défaut. Vous avez également ne peut pas (directement) les obtenir avec les membres non statiques. En d’autres termes, l’utilisation du commutateur entraîne uniquement le renvoi de membres statiques:

    PS Y:\Power> $obj | Get-Member -Static
    
       TypeName: System.IsFire.TurnUpProtocol
    
    Name        MemberType Definition
    ----        ---------- ----------
    Equals      Method     static bool Equals(System.Object objA, System.Object objB)
    ...
    
  • Utilisez le -Force.

    La commande Get-Member utilise le paramètre Force pour ajouter les membres intrinsèques et les membres générés par le compilateur des objets à l'affichage. Get-Member récupère ces membres, mais les masque par défaut.

    PS Y:\Power> $obj | Get-Member -Static
    
       TypeName: System.IsFire.TurnUpProtocol
    
    Name          MemberType     Definition
    ----          ----------     ----------
    ...
    pstypenames   CodeProperty   System.Collections.ObjectModel.Collection...
    psadapted     MemberSet      psadapted {AccessRightType, AccessRuleType,...
    ...
    

Utilisez ConvertTo-Json pour une "sérialisation" lisible

Je fais pas nécessaire recommande de sauvegarder les objets en utilisant JSON (utilisez plutôt Export-Clixml). Cependant, vous pouvez obtenir une sortie plus ou moins lisible de ConvertTo-Json, ce qui vous permet également de spécifier la profondeur.

Notez que ne pas spécifier Depth implique -Depth 2

PS Y:\Power> ConvertTo-Json $obj -Depth 1
{
    "AllowSystemOverload":  true,
    "AllowLifeToGetInTheWay":  false,
    "CantAnyMore": true,
    "LastResortOnly": true,
...

Et si vous n’avez pas l’intention de le lire, vous pouvez -Compress le supprimer

PS Y:\Power> ConvertTo-Json $obj -Depth 420 -Compress

Utilisez -InputObject si vous le pouvez (et si vous le souhaitez)

99,9% du temps d'utilisation de PowerShell: soit la performance importera peu, soit vous ne vous souciez pas de la performance. Cependant, il convient de noter que le fait d'éviter le tuyau lorsque vous n'en avez pas besoin peut vous faire économiser un temps système et augmenter votre vitesse (la tuyauterie, en général, n'est pas très efficace).

C'est-à-dire que si vous n'avez qu'un seul $obj pratique pour imprimer (et n'êtes pas trop paresseux comme moi parfois pour taper -InputObject):

# select is aliased (hardcoded) to Select-Object
PS Y:\Power> select -Property * -InputObject $obj
# gm is aliased (hardcoded) to Get-Member
PS Y:\Power> gm -Force -InputObject $obj

Mise en garde pour Get-Member -InputObject: Si $ obj est un collection (par exemple System.Object[]), vous terminez obtenir des informations sur l'objet de collection lui-même:

PS Y:\Power> gm -InputObject $obj,$obj2
   TypeName: System.Object[]

Name        MemberType            Definition
----        ----------            ----------
Count       AliasProperty         Count = Length
...

Si vous voulez Get-Member pour chaque TypeName de la collection (NB pour chaque TypeName, pas pour chaque objet - une collection de N objets avec tous les mêmes TypeName n’imprimera qu’une table pour cette TypeName et non pas N tables pour chaque objet) ...... collez-la simplement avec un passepoil directement.

0
YenForYang

Le dessous a vraiment bien fonctionné pour moi. J'ai corrigé ensemble toutes les réponses ci-dessus, ainsi que des informations sur l'affichage des propriétés des objets dans le lien suivant et suis venu avec ce qui suit petite lecture sur l'impression des objets

ajoutez le texte suivant à un fichier nommé print_object.ps1:

$date = New-Object System.DateTime
Write-Output $date | Get-Member
Write-Output $date | Select-Object -Property *

ouvrez la commande powershell Invite, allez dans le répertoire où ce fichier existe et tapez ce qui suit:

powershell -ExecutionPolicy ByPass -File is_port_in_use.ps1 -Elevated

Il suffit de remplacer 'System.DateTime' par l'objet que vous souhaitez imprimer. Si l'objet est null, rien ne sera imprimé.

0
Fractal