0

The following code (at the bottom) produces one of the following outputs in the file

4/12/2019 = (get-date).AddDays(2).ToShortDateString();
4/13/2019 = (get-date).AddDays(2 + 1).ToShortDateString();

or if I haven't initialized the variable

 = (get-date).AddDays(2).ToShortDateString();
 = (get-date).AddDays(2 + 1).ToShortDateString();

This is the code block, I would like the parent ps1 file to write the child ps1 file verbatim.

$multiLineScript2 = @"

    $startDate2 = (get-date).AddDays($resultOfSubtraction).ToShortDateString();
    $endDate2 = (get-date).AddDays($resultOfSubtraction + 1).ToShortDateString();
"@

$multiLineScript2 | Out-File "c:\file2.ps1";
Bbb
  • 517
  • 6
  • 27
  • 1
    Use single quotes for the here string (not script block) to have the variables **NOT** expanded. –  Apr 10 '19 at 12:22

2 Answers2

4

tl;dr:

To create a verbatim multi-line string (i.e., a string with literal contents), use a single-quoted here-string:

$multiLineScript2 = @'

    $startDate2 = (get-date).AddDays($resultOfSubtraction).ToShortDateString();
    $endDate2 = (get-date).AddDays($resultOfSubtraction + 1).ToShortDateString();
'@

Note the use of @' and '@ as the delimiters.

Use a double-quoted here-string only if string expansion (interpolation) is needed; to selectively suppress expansion, escape $ chars. to be included verbatim as `$, as shown in your own answer.


String Literals in PowerShell

Get-Help about_quoting rules discusses the types of string literals supported by PowerShell:

  • To get a string with literal content (no interpolation, what C# would call a verbatim string), use single quotes: '...'

    • To embed ' chars. inside a '...' string, double them (''); all other chars. can be used as-is.
  • To get an expandable string (string interpolation), i.e., a string in which variable references (e.g., $var or ${var}) and expressions (e.g., $($var.Name)) can be embedded that are replaced with their values, use double quotes: "..."

    • To selectively suppress expansion, backtick-escape $ chars.; e.g., to prevent $var from being interpolated (expanded to its value) inside a "..." string, use `$var; to embed a literal backtick, use ``
    • For an overview of the rules of string expansion, see this answer.

Both fundamental types are also available as here-strings - in the forms @'<newline>...<newline>'@ and @"<newline>...<newline>"@ respectively (<newline> stands for an actual newline (line break)) - which make defining multi-line strings easier.

  • Important:
    • Nothing (except whitespace) must follow the opening delimiter - @' or @" - on the same line - the string's content must be defined on the following lines.
    • The closing delimiter - '@ or "@ (matching the opening delimiter) - must be at the very start of a line.
    • Here-strings defined in files invariably use the newline format of their enclosing file (CRLF vs. LF), whereas interactively defined ones always use LF only.

Examples:

# Single-quoted: literal:
PS> 'I am $HOME'
I am $HOME

# Double-quoted: expandable
PS> "I am $HOME"
I am C:\Users\jdoe

# Here-strings:

# Literal
PS> @'
I am
  $HOME
'@
I am
  $HOME

# Expandable
PS> @"
I am
  $HOME
"@
I am
  C:\Users\jdoe
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

I couldn't find this anywhere, but it appears every single variable in the script (string literal) has to be escaped with a tick like so. Instead of deleting the question I'll leave it up for a search hit.

$multiLineScript2 = @"

`$startDate2 = (get-date).AddDays($resultOfSubtraction).ToShortDateString();
`$endDate2 = (get-date).AddDays($resultOfSubtraction + 1).ToShortDateString();

"@
Bbb
  • 517
  • 6
  • 27
  • 1
    As @LotPings stated earlier, change your here string to use `@' '@` instead of `@" "@`. Then you don't need to escape variables. – AdminOfThings Apr 10 '19 at 13:34
  • 2
    @AdminOfThings It looks like OP want to expand some (`$resultOfSubtraction`), but not all variables. – user4003407 Apr 10 '19 at 15:02
  • As PetSerAl states, it seems that _selective_ suppression of expansion (interpolation) is the goal, which makes the phrase "every single variable in the script" confusing. The only good reason to use a double-quoted here-string (`@"..."@`) to begin with is if at least _some_ expansion is needed. – mklement0 Aug 08 '19 at 19:50