1

I am trying to write a script to pull all e-mail addresses but I am finding that the output of my first get command is adding alot of white space to the result text file

Get-AdUser -Filter * -Properties * | Select EmailAddress | Out-File "C:\T2\EMailAddresses.txt"

Can anyone tell me what I am doing wrong here?

2
  • @mklement0 I tried that second suggestion one-liner you have, what does .Trim() do exactly? Is that supposed to take out the blanks or just the extra whitespace before and after all the content? Thanks for the input. Commented Sep 7, 2021 at 19:30
  • 1
    @cet51, .Trim() removes leading and trailing whitespace (all forms), so it wouldn't solve the problem of interior blanks. Commented Sep 7, 2021 at 19:33

2 Answers 2

1

You are seeing whitespace because not every AD account has a value assigned to that property in your environment so it appears as a blank line, I get the same thing upon a quick test.

This should help.

$Emails = Get-ADUser -Filter * -Properties EmailAddress
$Emails | select EmailAddress | Where {$_.EmailAddress -ne $null} | Out-File "C:\T2\EMailAddresses.txt"
Sign up to request clarification or add additional context in comments.

7 Comments

A quibble: While it doesn't matter here, it's a good habit to form to place $null on the LHS of equality / inequality operations, because it makes a difference with collections; compare $null -eq (1, 2) to (1, 2) -eq $null, for instance.
On a loosely related note: strings created in PowerShell code are never $null; if they have "no value", their value is the empty string; e.g.: [string] $str = $null; $null -eq $str yields $false. String-typed object properties, however, may contain a true $null, and it sounds like that is the case here with the objects output by Get-ADUser, right? (I can't personally verify).
Although the solution provided does remove entries with no values it still does not resolve the white space issue for objects with values so for example [email protected] comes out as jsmith@ms.comXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (where X is a white space) I have to then manually remove all of the Xs or white spaces or it breaks the next line of code. Any advice??
@JRN I would recommend giving mklement0 's answer a try, I believe it is better than what I threw together.
@cet51, yes, the implication is that the .EmailAddress property contains an actual $null when not set. In my answer, by casting to an array of[string]s first, $null is converted to '', which is why using -ne '' to filter out unset properties works.
|
1

td;dr

The following writes all email addresses to the target file, ignoring AD users that don't have one:

([string[]] (Get-AdUser -Filter * -Properties EmailAddress).EmailAddress) -ne '' |
  Set-Content C:\T2\EMailAddresses.txt

By writing just the - non-empty - .EmailAddress property values to the file, you're avoiding the problems that stem from saving for-display formatted object representations, which is what your attempt does (see below).

Note that -ne '' acts as a filter here, because its LHS operand is an array; that is, the result of the operation is the sub-array of those LHS elements that aren't the empty string ('').


As for what you tried:

By using Out-File in combination with objects subject to PowerShell's output formatting system, you're saving a for-display representation of your objects to a file, which, in the case at hand includes a table header, a leading and a trailing blank line and - in Windows PowerShell (but no longer in PowerShell (Core) 7+) - right-space-padding to the full console-line width of each line.

  • Even though you're only asking for one property - EmailAddress - Select-Object outputs not just that property's value for each input object, but a [pscustomobject] instance with an .EmailAddress property, and the resulting objects are implicitly formatted with Format-Table.

  • To get just the EmailAddress property values, use Select-Object -ExpandProperty EmailAddress. The resulting string values are not subject to formatting, so your command would work as intended except that it would still include $null values from those AD users who happen not to have a value stored in their .EmailAddress property.

    • While it often won't matter, for string input it's slightly faster to use Set-Content than Out-File / >; note that in Windows PowerShell you'll end up with different character encodings by default (ANSI vs. UTF-16 LE a.k.a "Unicode") - use the -Encoding parameter as needed; PowerShell Core 7+ fortunately now consistently defaults to BOM-less UTF-8.

    • The - faster, but more potentially memory-intensive - alternative to using Select-Object -ExpandProperty EmailAddress for extracting the EmailAddress property values is to use member-access enumeration ((...).EmailAddress, as shown above).

2 Comments

Love the depth and knowledge here. This is great! Maybe someday i'll move on from PS 5.1
Glad to hear it, @cet51; just to be clear: the solution in this answer works just fine in PS 5.1 (Windows PowerShell) too, but the answer points to some general improvements in PS 6+ (PowerShell (Core)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.