Multiline to Singleline Conversion

Hey everyone,

So, I’m looking to take multiline output from an array and present it as a single line, pref comma seperated…

$i = 0
$processinfo = @[Get-WmiObject -class win32_process -ComputerName $Computer -EA "Stop"]
				if [$processinfo]
					$processinfo | Foreach-Object { $_.GetOwner[].User } |
					Where-Object { $_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM" } |
					Sort-Object -Unique |
					ForEach-Object { New-Object psobject -Property @{ Computer = $Computer; LoggedOn = $_ } } |
					Format-Table -wrap LoggedOn -HideTableHeaders| Out-String

Output looks like

User 1
User 2
User 3
User 4

Which is fine but I need it to look like


Any ideas?


So, the problem right now if that you’re moving everything through Format-Table and Out-String. Not sure I’d do that. If, instead, you did…

Select-Object -Expand LoggedOn

You should get the same visual result. From there, just use the -join operator.

… -join “,”

-Join will take (on the left side) an array (which is what you’re getting, that’s why it’s one piece of info per line) and (on the right side) a delimiter, and “join” the array elements, separating them with the delimiter. So in this case, I’m guessing “$processinfo -join ‘,’” would be roughly what you’re after?

But the Format- commands are more likely to cause you long-term problems if you’re using them that way. Once you format something, you should be “done” with it.

Mr. Jones,

Thank you for the cleanup tips and I like your point about the formatting. I am a little confused about the join operator however. If you execute that function and then try to recall the $processinfo variable, you lose the sort-object unique and return hundreds of results instead of a couple of user names. I understand how to use join but I guess I don’t understand where to use it in this case. Do I need to bring the entire array into a diff variable first?



I’m not really clear on what-all your code is trying to do - you’ve got a lot of stuff jammed into a one-liner. End story, the -join operator takes an array on one side, and a delimiter on the other. You’ll need to work out where to stick that into your process. I’m not sure I’d have built the command the same way. You’re correct in that it isn’t $processinfo - but I don’t see where you’re storing the output otherwise. You can’t pipe to the -join operator; it’d be easiest if you assigned your output to a variable, which you could then use with -join.



As usual, your words made me second guess myself…:slight_smile:

And as usual, I just threw away what I had and re-wrote in half of the time and now it works :stuck_out_tongue:

function Get-LoggedOnUser
	#Requires -Version 2.0
		[Parameter(Mandatory = $true)]
	)#End Param
		Write-Host "`n Checking Users . . . "
		$i = 0
 $processinfo = @(Get-WmiObject -class win32_process -ComputerName $Computer) | Foreach-Object {$_.GetOwner().User } |
    Where-Object { $_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM" } |
    Sort-Object -Unique

 $processinfo -join ","

The point of all of this is to return users that are currently logged onto a remote machine by finding process owners and returning a unique list.

Thanks again for the help!

Yeah, that’s definitely a little easier to follow. As a note, the #requires statement needs to go at the top of the script - it’s per-file not so much per-function, since the entire file has to be processed by the shell.

Consider Write-Verbose instead of Write-Host for that “status” information. [CmdletBinding()] gives you a “free” -verbose parameter that controls the output that way.

Not sure what $i is doing for ya ;).

You could simplify your comparison: $_ -notin @(“NETWORK SERVICE”,“LOCAL SERVICE”,“SYSTEM”) that’d constrain you to v3 (the -notin operator), though. You could do a v2-compatible version using -contains or -notcontains, if you were of a mind.

Good work!

You may also consider:

(Get-WmiObject Win32_LoggedOnUser -ComputerName $env:COMPUTERNAME | Select Antecedent -Unique).Antecedent | % {
} | where { $_ -notin 'system','local service','network service' }