0

My question is little be stupid but i'm a beginner and i didn't found on the web and forum what i want to do.

$Servers = $(Window.FindName("Server_list").SelectedItems

When i return this var, i have all my servers i had selected but on line like this

server1 server2 server3 server4 ...

For me i need to do a Foreach like this

Foreach ($element in $Servers)
{
*element of my var* {"`r"}
}

The result i should have is

server1
server2
server3
etc

I think i'm not to far of the answer but my brain start to burn with my beginner level.

Thank you for your idea and answer.

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
YannM
  • 13
  • 3

1 Answers1

1

From $Window.FindName("Server_list").SelectedItems (note that I've removed what I presume to be an extraneous () I infer that you're getting a WPF list view's .SelectedItems property value.

This value is a collection (strictly speaking: an object that implements the IList interface)[1], which has two implications in PowerShell:

  • You can enumerate the collection (iterate over its elements) in a foreach loop or, implicitly, in the pipeline (see bottom section for a ForEach-Object example). Additionally, many PowerShell operators either operate exclusively on or can also operate on collections (typically, on the LHS), in which case the collection is also implicitly enumerated and the operation performed on each element, such as shown with the -join operator below.

  • When you print the collection to the console (host), PowerShell's default output formatting system prints each element on its own line by default (see bottom section).

It sounds like you truly need to build a multi-line string programmatically:

To create a plain-text multi-line string, Mathias R. Jessen's solution based on the -join operator is the right one:

# Note: Since -join is a *string* operator, any LHS elements
#       that aren't already strings are automatically stringified with .ToString()
$Servers -join "`n"

Note that I'm using "`n", a Unix-format LF newline, which is usually sufficient. If you want to use Windows-format CRLF newlines, use "`r`n". For the platform-native newline sequence, use [Environment]::NewLine.

However, if the text is to be rendered as HTML, actual newlines aren't sufficient: they get converted to spaces. Instead, you must join the server names with <br> elements:

# Create a multi-line *HTML* string
$Servers -join '<br>'

Console-output considerations:

The following array-based example demonstrates the default to-display behavior with string collections (arrays):

PS> $Servers = 'server1', 'server2', 'server3'; $Servers # output
server1
server2
server3

Note that $Servers by itself is essentially the same as Write-Output $Servers, thanks to PowerShell's implicit output behavior.

If the elements of collection $Servers aren't actually strings, you'll get different, richer output: depending on the number of properties of the objects, you'll get table-formatted (<= 4 properties) or list-formatted (5 or more properties, each property on its own line) output by default.

If you just want the string representations of these elements, as reported by their .ToString() method, use the following:

$Servers | ForEach-Object ToString

By contrast, using Write-Host - which is meant for to-display output, not for data output - stringifies collections differently (and often unhelpfully); it outputs a single line, with the (stringified) collection elements joined with spaces, and uses simple .ToString() stringification, not PowerShell's rich output-formatting system.

PS> Write-Host $Servers
server1 server2 server3

However, you can instruct Write-Host to use newlines (line breaks) instead:

PS> Write-Host -Separator "`n" $Servers
server1
server2
server3

However, remember that this generates for-display output, not data (see below).


[1] For a summary of which types PowerShell enumerates by default, see the bottom section of this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • What does this question have to do with WPF? – Joe Mar 10 '22 at 22:18
  • @Joe, WPF is ultimately _incidental_ to this answer, but `$Windows.FindName(...)` suggests the use of the [`FrameworkElement.FindName()`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.frameworkelement.findname#system-windows-frameworkelement-findname(system-string)) method, which the derived [`System.Windows.Windows`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.window) WPF class inherits. What matters is that `$Servers` contains, loosely speaking, a _collection_ of items. – mklement0 Mar 10 '22 at 22:38
  • @Joe, and I only just now saw there's an explicit `wpf` _tag_ on the question... The only aspect that matters somewhat is what type of objects the collection returned by `.SelectedItems` contains - given the abstract, non-generic `IList` interface, I couldn't tell. Knowing WPF only superficially: can the type vary? – mklement0 Mar 10 '22 at 22:43
  • No worries. I just missed the reference. – Joe Mar 10 '22 at 22:55
  • Sorry for the comprehension of WPF in this code. My script as 340line and with my job i can't upload the whole code. However i had try ` $Servers -join "`n" ` On console pane i have multiline but on my wpf i have one line. I try to do : ` $Test = $($Server) -join "`n" ` And call $Test but same result, only one line. I had try to do this one too: ` Foreach ($element in $Servers) { $element -join "`n" } ` However same result. I probably miss understanding something :/ – YannM Mar 11 '22 at 09:59
  • @YannM, it sounds like the multi-line string is rendered _as HTML_, in which case regular newlines aren't enough - please see my update (I've moved the console considerations to a separate section at the bottom). – mklement0 Mar 11 '22 at 13:48