resayaji
resayaji

Reputation: 11

Formatting output of foreach command

I'm new to Powershell and I can't figure out how to format the output of this foreach loop oneliner.

foreach ($user in cat C:\list.txt) {Get-ADUser $user | select -Property             
GivenName,Surname,SamAccountName}

GivenName Surname    SamAccountName
--------- -------    --------------
Bob       Smith      SmithB
Fred      Williams   WilliamsF
Ann       Jones      JonesA
Joan      Scott      ScottJ
Eve       Wood       WoodE
George    Peters     PetersG
Alice     Watt       Watt

The C:\list.txt contains a list of the SamAccountName, one per line.

What I'm looking for is to have the output look like this:

Bob Smith SmithB; Fred Williams WilliamsF; Ann Jones JonesA; Joan Scott ScottJ; Eve Wood WoodE; George Peters PetersG; Alice Watt Watt

I would also like to avoid creating any new files in the process.

Upvotes: 1

Views: 1885

Answers (2)

mklement0
mklement0

Reputation: 440357

A concise solution (PSv2+):

(Get-Content C:\list.txt | Get-ADUser | ForEach-Object {
  '{0} {1} {2}' -f $_.GivenName, $_.SurName, $_.SamAccountName
}) -join ';'
  • Get-Content C:\list.txt | Get-ADUser uses the pipeline to provide the user names to Get-ADUser (which implicitly binds the input strings to its -Identity parameter); the result is an array of AD users objects.

    • Use of the pipeline vs. a foreach loop has trade-offs (memory consumption vs. speed); unless there is a known performance problem, however, the pipeline offers more concise, elegant solutions.
  • Piping the result to the ForEach-Object (%) cmdlet allows processing the resulting AD user objects one by one, via a script block ({ ... }) in which $_ represents the input object at hand.

  • '{0} {1} {2}' -f $_.GivenName, $_.SurName, $_.SamAccountName uses -f, PowerShell's string-formatting operator, to build a string from the properties of the given user object. Note how there's no need for an intermediate select (Select-Object) call, given that you can access the properties of interest directly on the AD user object.

  • Enclosing the entire pipeline in (...) results in an array of strings[1], which -join then joins to form a single output string with ; as the separator.


[1] Strictly speaking, if C:\list.txt contained just 1 name, the output would be a scalar, i.e. a single string. However, the -join operator also accepts a scalar as the LHS, in which case the operation is a no-op (nothing to join).

Upvotes: 1

Tany3450
Tany3450

Reputation: 338

A simple solution would be:

$result = '';
foreach ($user in cat C:\list.txt) {
  $adUser = Get-ADUser $user | select -Property GivenName,Surname,SamAccountName
  $result += [string]::Format("{0} {1} {2}; ", $adUser.GivenName, $adUser.Surname, $adUser.SamAccountName)
}
$result

Upvotes: 2

Related Questions