1

I am trying to create a loop in HTML in PowerShell ISE, like this:

{foreach $obj in $objects}
   <h1>$obj.Name<h1>
{/foreach}

But it only prints the last one in the list of objects. What do?

3
  • are you sure there are more than one items in $objects? Commented Oct 24, 2022 at 18:54
  • 2
    Is that an html foreach? Cause it definitely isn’t valid powershell foreach Commented Oct 24, 2022 at 19:41
  • @DougMaurer Can you point me in the right direction? It is an html foreach, technically, being done in a powershell script Commented Oct 24, 2022 at 19:52

1 Answer 1

1

Use an expandable (interpolating) here-string and embed a foreach statement via $(...), the subexpression operator:

# Sample objects.
$objects = [pscustomobject] @{ name = 'foo1' },
           [pscustomobject] @{ name = 'foo2' }

# Use an expandable (double-quoted) here-string to construct the HTML.
# The embedded $(...) subexpressions are *instantly* expanded.
@"
<html>
$(
  $(
    foreach ($obj in $objects) {
      "  <h1>$($obj.Name)<h1>"
    }
  ) -join "`n"
)
</html>
"@

Output:

<html>
  <h1>foo1<h1>
  <h1>foo2<h1>
</html>

If you want to define the above strings as a template, so you can perform expansion (string interpolation) repeatedly, on demand, use a verbatim here-string, and expand on demand - based on the then-current variable values via $ExecutionContext.InvokeCommand.ExpandString():

# Use a verbatim (single-quoted) here-string as a *template*:
# Note the @' / @' instead of @" / @"
$template = @'
<html>
$(
  $(
    foreach ($obj in $objects) {
      "  <h1>$($obj.Name)<h1>"
    }
  ) -join "`n"
)
</html>
'@

# Sample objects.
$objects = [pscustomobject] @{ name = 'foo1' },
           [pscustomobject] @{ name = 'foo2' }


# Expand the template now.
$ExecutionContext.InvokeCommand.ExpandString($template)

'---'

# Define different sample objects.
$objects = [pscustomobject] @{ name = 'bar1' },
           [pscustomobject] @{ name = 'bar2' }

 
# Expand the template again, using the new $objects objects.
$ExecutionContext.InvokeCommand.ExpandString($template)

Output:

<html>
  <h1>foo1<h1>
  <h1>foo2<h1>
</html>
---
<html>
  <h1>bar1<h1>
  <h1>bar2<h1>
</html>

Note:

  • Given that $ExecutionContext.InvokeCommand.ExpandString() is a bit obscure, it would be nice to have a cmdlet that provides the same functionality, named, say, Expand-String or Expand-Template, as proposed in GitHub issue #11693.
Sign up to request clarification or add additional context in comments.

Comments

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.