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).