web-dev-qa-db-fra.com

PowerShell: Format-Table sans en-têtes

Dans un script PowerShell, j'ai certains objets que je passe au Format-Table CmdLet.
Voici le résultat de mon script:

Something...

Operation AttributeName  AttributeValue
--------- -------------  --------------
Delete    Member         John Doe

Something else...

Puisque la signification des champs est assez explicite, je voudrais supprimer les en-têtes, les séparateurs '---' et les lignes vides au début et à la fin de la sortie de Format-Table.
Je ne pense pas que le CmdLet le supporte (ou du moins s’il existe un paramètre pour le faire, je n’ai pas pu le trouver).

Quel serait le meilleur moyen de ne laisser que les lignes contenant les valeurs réelles de la sortie de Format-Table?

9
Paolo Tedesco

Essayez le paramètre -HideTableHeaders à Format-Table:

gci | ft -HideTableHeaders

(J'utilise PowerShell v2. Je ne sais pas s'il s'agissait de v1.)

23
Jay Bazuzi

Le paramètre -HideTableHeaders provoque malheureusement toujours l'impression des lignes vides (et les en-têtes de tableau sont apparemment toujours pris en compte pour la largeur de colonne). Le seul moyen que je connaisse qui puisse fonctionner ici serait de formater vous-même la sortie:

| % { '{0,10} {1,20} {2,20}' -f $_.Operation,$_.AttributeName,$_.AttributeValue }
7
Joey

Essayez -ExpandProperty. Par exemple, j'utilise ceci pour envoyer la variable de nettoyage à Out-Gridview -PassThru, sinon la variable contient les informations d'en-tête. Notez que ceux-ci ne sont pas intéressants si vous souhaitez renvoyer plusieurs propriétés.

Un exemple:

Get-ADUser -filter * | select name -expandproperty name

Alternativement, vous pouvez faire ceci:

(Get-ADUser -filter * ).name
6
KERR

Voici comment je résous ceci. Je dirige juste la sortie vers Out-String, puis passe cette sortie à la fonction .NET Trim:

(gci | ft -HideTableHeaders | Out-String).Trim()

Cela supprimera les sauts de ligne avant et après la table.

Vous pouvez également utiliser TrimStart pour prendre en charge le saut de ligne de l'en-tête si vous voulez toujours les sauts de ligne de fin.

(gci | ft -HideTableHeaders | Out-String).TrimStart()
3
user1769153

Une autre approche consiste à utiliser ForEach-Object pour projeter des éléments individuels dans une chaîne, puis à l'aide de Out-String CmdLet pour projeter les résultats finaux dans une chaîne ou un tableau de chaînes:

gci Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | foreach { "CID Key {0}" -f $_.Name } | Out-String

#Result: One multi-line string equal to:
@"
CID Key HKEY_CLASSES_ROOT\CID\2a621c8a-7d4b-4d7b-ad60-a957fd70b0d0
CID Key HKEY_CLASSES_ROOT\CID\2ec6f5b2-8cdc-461e-9157-ffa84c11ba7d
CID Key HKEY_CLASSES_ROOT\CID\5da2ceaf-bc35-46e0-aabd-bd826023359b
CID Key HKEY_CLASSES_ROOT\CID\d13ad82e-d4fb-495f-9b78-01d2946e6426
"@

gci Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | foreach { "CID Key {0}" -f $_.Name } | Out-String -Stream

#Result: An array of single line strings equal to:
@(
"CID Key HKEY_CLASSES_ROOT\CID\2a621c8a-7d4b-4d7b-ad60-a957fd70b0d0",
"CID Key HKEY_CLASSES_ROOT\CID\2ec6f5b2-8cdc-461e-9157-ffa84c11ba7d",
"CID Key HKEY_CLASSES_ROOT\CID\5da2ceaf-bc35-46e0-aabd-bd826023359b",
"CID Key HKEY_CLASSES_ROOT\CID\d13ad82e-d4fb-495f-9b78-01d2946e6426")

L'avantage de cette approche est que vous pouvez stocker le résultat dans une variable sans qu'il y ait de lignes vides.

1
Greg Bray

Je sais qu'il a 2 ans de retard, mais ces réponses m'ont aidé à formuler une fonction de filtrage pour sortir les objets et couper les chaînes résultantes. Comme je dois tout mettre en forme dans une chaîne dans ma solution finale, les choses se sont déroulées un peu différemment. Main longue, mon problème est très similaire, et ressemble un peu à ceci

$verbosepreference="Continue"
write-verbose (ls | ft | out-string) # this generated too many blank lines

Voici mon exemple:

ls | Out-Verbose # out-verbose formats the (pipelined) object(s) and then trims blanks

Ma fonction Out-Verbose ressemble à ceci:

filter Out-Verbose{
Param([parameter(valuefrompipeline=$true)][PSObject[]]$InputObject,
      [scriptblock]$script={write-verbose "$_"})
  Begin {
    $val=@()
  }
  Process {
    $val += $inputobject
  }
  End {
    $val | ft -autosize -wrap|out-string |%{$_.split("`r`n")} |?{$_.length} |%{$script.Invoke()}
  }
}

Remarque 1: cette solution ne s'adapte pas à des millions d'objets (elle ne gère pas le pipeline en série).

Note2: Vous pouvez toujours ajouter une option -noheaddings. Si vous vous demandez pourquoi j'ai utilisé un script de blocage ici, c'est pour permettre la surcharge, comme l'envoi sur un fichier disque ou d'autres flux de sortie.

0
Conrad B