skip to Main Content

Html portion


$html = @($htm)

$html = @"

<!doctype html>

<html lang="en">
<head>
<body>
text
$computername
$username
text
</body>
</html>
"@

 $html | out-file c:scriptstempReport.html

I have html language in the $html variable. When I decide to change the HTML code I need to go back into the PowerShell script. I’d rather just have the html in a separate file. How can I use get-content to place the contents of separate file into the $html = @"..."@ variable.
I am using powershell $variables in the html portion to make dynamic emails!

3

Answers


  1. Dependent on your use case, a simple string replacement might work:

    # read the content of the file
    [string]$html = Get-Content `
        -Path 'c:pathtotemplate.html' `
        -Encoding 'UTF8' `
        -Raw;
    
    # replace the strings
    $html = $html.Replace('$computername', $computername);
    $html = $html.Replace('$username', $username);
    
    # write the result to the output file
    $html | Out-File 'c:pathtoreport.html';
    
    Login or Signup to reply.
  2. If you need to have a HTML template where several variables need to be inserted, I would rather use a structured CSV file than a simple text file to read the variable values needed.

    Lets say your csv file looks like this:

    "ComputerName","UserName"
    "PC0123","Roger Rabbit"
    "PC8769","Daffy Duck"
    "PC5544","Yosemite Sam"
    

    Option 1: Use a HTML template with numeric placeholders to use with the -f Format operator

    $html = @"
    <!doctype html>
    
    <html lang="en">
    <head>
    <body>
    text
    {0}
    {1}
    text
    </body>
    </html>
    "@
    

    Then use like

    Import-Csv -Path 'X:SomewhereUsersAndComputers.csv' | ForEach-Object {
        # replace the placeholder strings {0} and {1} etc. with values from the csv
        $newHtml = $html -f $_.ComputerName, $_.UserName
        # create a path and filename for the filled-in html
        $newFile = 'C:scriptstempReport_{0}.html' -f $_.UserName
        # write the file
        $newHtml | Set-Content -Path $newFile -Encoding UTF8
    }
    

    Option 2: Use a HTML template with string placeholders to use with .Replace() or -replace

    $html = @"
    <!doctype html>
    
    <html lang="en">
    <head>
    <body>
    text
    @@COMPUTERNAME@@
    @@USERNAME@@
    text
    </body>
    </html>
    "@
    
    
    Import-Csv -Path 'X:SomewhereUsersAndComputers.csv' | ForEach-Object {
        # replace the placeholder strings with values from the csv
        $newHtml = $html.Replace('@@COMPUTERNAME@@', $_.ComputerName).Replace('@@USERNAME@@', $_.UserName)
        # create a path and filename for the filled-in html
        $newFile = 'C:scriptstempReport_{0}.html' -f $_.UserName
        # write the file
        $newHtml | Set-Content -Path $newFile -Encoding UTF8
    }
    

    Note:
    Instead of the string .Replace() method you could also use -replace or -creplace regex operators like

        $newHtml = $html -replace '@@COMPUTERNAME@@', $_.ComputerName -replace '@@USERNAME@@', $_.UserName
    

    where -replace is a case-insensitive operator. If you need it to work case-sensitively, then use -creplace

    When you need to insert many variables, option 1 would be my preferred way..

    Login or Signup to reply.
  3. You’re looking for string templating, i.e. the ability to expand a string with placeholders on demand, based on the then-current values that the placeholders (variables) represent.

    PowerShell offers such a feature via the (little-known) .InvokeCommand.ExpandString() method of the automatic $ExecutionContext variable:

    • Save your HTML template string via a verbatim string ('...'), i.e., a single-quoted one, so as to prevent instant expansion of embedded variable references such as $computer:
    # Note the use of *single* quotes, to ensure
    # that $computername and $username *aren't* expanded.
    @'
    <!doctype html>
    <html lang="en">
    <head>
    <body>
    text
    $computername
    $username
    text
    </body>
    </html>
    '@ | Out-File c:scriptstempReport.html
    
    • Then use the template as follows:
    # Read the template in full (-Raw)
    $htmlTemplate = Get-Content -Raw c:scriptstempReport.html
    
    # Perform sample instantiations of the template.
    1..2 | ForEach-Object {
      # Set the variable values to use in the template.
      $computername = "computer$_"
      $username = "user2"
      # Now instantiate the template
      $ExecutionContext.InvokeCommand.ExpandString($htmlTemplate)
      "---`n" 
    }
    

    This outputs the following – note how $computer and $username were expanded to the then-current values of these variables:

    <!doctype html>
    <html lang="en">
    <head>
    <body>
    text
    computer1
    user2
    text
    </body>
    </html>
    
    ---
    
    <!doctype html>
    <html lang="en">
    <head>
    <body>
    text
    computer2
    user2
    text
    </body>
    </html>
    
    ---
    

    Caveat:

    • The above assumes that you either fully control or implicitly trust the content of your HTML template file, given that it is possible to inject arbitrary commands into the template, using $(...), the subexpression operator
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search