I am attempting to determine if users in a CSV are active or not, additionally, I want to know if they are service accounts, user accounts, or machine accounts based on OU.
Everything is swell, until I try to output it... The output is on several lines (one for each var).
I would like the output to be on one line (with commas between so I will have a CSV when I am done)... I have tried this twenty different ways with forty different results O_o.
Bonus: add a message for any names that produce errors (i.e. user doesn't exist...) I am thinking of an if/else for that, but have not been able to get the basic output to behave.
I have tried enclosing in parenthesis, concatenating variables, nesting variables... beating my computer with a stick... quietly contemplating my life choices...
$Users = Get-Content C:\ActiveUsers.txt
ForEach ($User in $Users){
$properties = Get-ADUser -Identity $User | select SamAccountName,Enabled,DistinguishedName
if (Select-String -Pattern "UserMgt" -InputObject $properties) { $base = "User" }
if (Select-String -Pattern "ApplSec" -InputObject $properties) { $base = "Service Account" }
if (Select-String -Pattern "WkstnMgt" -InputObject $properties) { $base = "Machine Account" }
write-output $properties.SamAccountName $properties.Enabled $base
#$Output = Write-Output $properties.SamAccountName $properties.Enabled $base
#$Output #| out-file C:\UserStatus-OU2.csv -append
}
To focus on the general title of your question (see the bottom for the optimal solution in your specific case):
Given multiple variables, say $a
, $b
, $c
, how can I output them as a single-line string, with a configurable separator, say ,
?
In the following examples, assume values 'foo'
, 'bar'
, 'baz'
as the values of variables $a
, $b
, and $c
, respectively, which you can create with the following (destructuring) assignment: $a, $b, $c = 'foo', 'bar', 'baz'
.
-join
operator:PS> $a, $b, $c -join ','
foo,bar,baz
This approach has the advantage of working with arrays of any size as the LHS.
"..."
, string interpolation), as in your own solution:PS> "$a,$b,$c"
foo,bar,baz
-f
, the string-formatting operator:PS> '{0},{1},{2}' -f $a, $b, $c
foo,bar,baz
As for what you tried:
Write-Output $properties.SamAccountName $properties.Enabled $base
Passing multiple arguments to Write-Output
writes them to the pipeline one by one; if these arguments are strings, each string prints on its own line, which also applies if you send the output to Out-File
/ >
or Set-Content
.
That said, since you're creating rows for a CSV file, it's much better to create custom objects to represent the rows and serialize them to a file with Export-Csv
(based on the code in your question, not your answer:
Get-Content C:\ActiveUsers.txt |
ForEach-Object {
$properties = Get-ADUser -Identity $_ | Select-Object SamAccountName, Enabled, DistinguishedName
# Consider using `elseif` here, unless you really want to evaluate
# all conditions every time.
# Also, it's better to check a specific property value rather than
# searching the string representation of the entire object, e.g.
# if ($properties.DistinguishedName -match 'UserMgmt') ...
if (Select-String -Pattern "UserMgt" -InputObject $properties) { $base = "User" }
if (Select-String -Pattern "ApplSec" -InputObject $properties) { $base = "Service Account" }
if (Select-String -Pattern "WkstnMgt" -InputObject $properties) { $base = "Machine Account" }
# For each user, output a custom object.
# The custom objects' property names becomes the CSV column headers
# when Export-Csv processes the outputs.
[pscustomobject] @{
SamAccountName = $properties.SamAccountName
Enabled = $properties.SamAccountName
Base = $base
}
} | Export-Csv -NoTypeInformation C:\UserStatus-OU2.csv
Note the use of a single pipeline.