J'écris un script dans Powershell
qui exporte tous les securitygroups
et leurs members
de Active Directory
. Maintenant, je veux formater la sortie du .csv
.
Le code:
$Groups = Get-ADGroup -Properties * -Filter * -SearchBase "OU=SERVICES,DC=XXXXXX,DC=XXXXX"
$Table = @()
$Record = @{
"Group Name" = ""
"Name" = ""
"Username" = ""
}
Foreach($G In $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $G -recursive | select name,samaccountname
Foreach ($Member in $Arrayofmembers)
{
$Record."Group Name" = $G.Name
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
}
}
$Table | export-csv "C:\temp\SecurityGroups.csv" -NoTypeInformation
Le résultat:
"Username","Name","Group Name"
"aman","Ani Manoukian","Commercial"
"adan","Aurelia Danneels","Commercial"
"kdeb","Kathleen De Backer","Commercial"
"TVGR","Thijs Van Grimbergen","Commercial"
"SVDE","Sofie Van den Eynde","Commercial"
Maintenant, je veux que la sortie soit formatée en:
"Group Name","Name","Username"
au lieu de "Username","Name","Group Name"
Quelqu'un peut-il m'aider s'il-vous-plaît?
Merci d'avance.
Cela devrait fonctionner ...
$Table |
Select-Object "Group Name", "Name", "Username" |
Export-Csv "C:\temp\SecurityGroups.csv" -NoTypeInformation
réponse utile de gvee est une solution pragmatique qui garantit que les colonnes apparaissent dans l'ordre souhaité, car l'ordre dans lequel vous passez les noms de propriété à Select-Object
est l'ordre dans lequel les propriétés sont ajoutées aux instances [pscustomobject]
résultantes.
Il est cependant inefficace , car l'ordre des colonnes souhaité peut être assuré au moment $Record
est défini, sans avoir besoin d'une étape de pipeline supplémentaire qui duplique efficacement les objets de résultat:
Définissez $Record
Comme ordonné table de hachage comme suit (nécessite PSv3 + ):
$Record = [ordered] @{
"Group Name" = ""
"Name" = ""
"Username" = ""
}
Cela garantit que les instances [pscustomobject]
Créées ultérieurement par les appels New-Object PSObject -property $Record
Contiennent des propriétés dans le même ordre que les clés ont été définies dans $Record
.
Deux côtés:
* New-Object PSObject -property $Record
Pourrait être simplifié en [pscustomobject] $Record
* La création incrémentielle d'un grand tableau est plus efficacement gérée avec une instance de [System.Collections.ArrayList]
À laquelle vous ajoutez des éléments avec .Add()
plutôt que d'utiliser les tableaux intégrés de PowerShell avec +=
, Qui crée à chaque fois une copie du tableau. Encore mieux, et PowerShell crée le tableau pour vous, simplement en capturant la sortie de votre boucle foreach
dans une variable ($Table = foreach ...
- voir cette réponse )
La source du problème est que les tables de hachage régulières (instances [hashtable]
) Énumèrent leurs clés dans un ordre effectivement aléatoire (l'ordre est une implémentation détail), et lorsque vous créez un [pscustomobject]
à partir d'une table de hachage, cet ordre de clé imprévisible se reflète dans l'ordre des propriétés de l'objet résultant.
En revanche, dans PSv3 + vous pouvez créer une ordonnée table de hachage en plaçant le mot-clé [ordered]
devant un littéral de table de hachage, ce qui donne un [System.Collections.Specialized.OrderedDictionary]
instance dont clés sont ordonnées en fonction de l'ordre dans lequel elles ont été ajoutées.
La création d'une instance [pscustomobject]
À partir d'une table de hachage ordonnée préserve ensuite l'ordre des clés dans les propriétés de l'objet résultant.
Notez que PowerShell v3 + offre un raccourci pratique pour créer une instance [pscustomobject]
À partir d'une table de hachage à l'aide d'un cast; par exemple.:
PS> [pscustomobject] @{ a = 1; b = 2; c = 3 } # key order is PRESERVED
a b c
- - -
1 2 3
Notez comment l'ordre de définition des clés était préservé, même si [ordered]
N'a pas été spécifié.
En d'autres termes: Lorsque vous transtypez un littéral de table de hachage directement en [pscustomobject]
, [ordered]
Est = implicite, donc ce qui précède équivaut à:
[pscustomobject] [ordered] @{ a = 1; b = 2; c = 3 } # [ordered] is optional
Avertissement : cet ordre implicite seulement s'applique lorsqu'une table de hachage littérale est directly transtypé en [pscustomboject]
, donc l'ordre des clés/propriétés est pas conservé dans les variantes suivantes:
New-Object PSCustomObject -Property @{ a = 1; b = 2; c = 3 } # !! order NOT preserved
$ht = @{ a = 1; b = 2; c = 3 }; [pscustomobject] $ht # !! order NOT preserved
[pscustomobject] (@{ a = 1; b = 2; c = 3 }) # !! order NOT preserved, due to (...)
Par conséquent, lorsque vous ne convertissez pas un littéral de table de hachage directement en [pscustomobject]
, Définissez-le explicitement avec [ordered]
.