2. Lexical Structure

2.1 Grammars

This specification shows the syntax of the PowerShell language using two grammars. The lexical grammar (§B.1) shows how Unicode characters are combined to form line terminators, comments, white space, and tokens. The syntactic grammar (§B.2) shows how the tokens resulting from the lexical grammar are combined to form PowerShell scripts.

For convenience, fragments of these grammars are replicated in appropriate places throughout this specification.

Any use of the characters 'a' through 'z' in the grammars is case insensitive. This means that letter case in variables, aliases, function names, keywords, statements, and operators is ignored. However, throughout this specification, such names are written in lowercase, except for some automatic and preference variables.

2.2 Lexical analysis

2.2.1 Scripts

Syntax:

Tip

The ~opt~ notation in the syntax definitions indicates that the lexical entity is optional in the syntax.

input:
    input-elements~opt~   signature-block~opt~

input-elements:
    input-element
    input-elements   input-element

input-element:
    whitespace
    comment
    token

signature-block:
    signature-begin   signature   signature-end

signature-begin:
    new-line-character   # SIG # Begin signature block   new-line-character

signature:
    base64 encoded signature blob in multiple single-line-comments

signature-end:
    new-line-character   # SIG # End signature block   new-line-character

Description:

The input source stream to a PowerShell translator is the input in a script, which contains a sequence of Unicode characters. The lexical processing of this stream involves the reduction of those characters into a sequence of tokens, which go on to become the input of syntactic analysis.

A script is a group of PowerShell commands stored in a script-file. The script itself has no name, per se, and takes its name from its source file. The end of that file indicates the end of the script.

A script may optionally contain a digital signature. A host environment is not required to process any text that follows a signature or anything that looks like a signature. The creation and use of digital signatures are not covered by this specification.

2.2.2 Line terminators

Syntax:

new-line-character:
    Carriage return character (U+000D)
    Line feed character (U+000A)
    Carriage return character (U+000D) followed by line feed character (U+000A)

new-lines:
    new-line-character
    new-lines new-line-character

Description:

The presence of new-line-characters in the input source stream divides it into lines that can be used for such things as error reporting and the detection of the end of a single-line comment.

A line terminator can be treated as white space (§2.2.4).

2.2.3 Comments

Syntax:

comment:
    single-line-comment
    requires-comment
    delimited-comment

single-line-comment:
    # input-characters~opt~

input-characters:
    input-character
    input-characters input-character

input-character:
    Any Unicode character except a new-line-character

requires-comment:
    #requires whitespace command-arguments

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

dashdash:
    dash dash

delimited-comment:
    < # delimited-comment-text~opt~ hashes >

delimited-comment-text:
    delimited-comment-section
    delimited-comment-text delimited-comment-section

delimited-comment-section:
    >
    hashes~opt~  not-greater-than-or-hash

hashes:
    #
    hashes #

not-greater-than-or-hash:
    Any Unicode character except > or #

Description:

Source code can be annotated by the use of comments.

A single-line-comment begins with the character # and ends with a new-line-character.

A delimited-comment begins with the character pair <# and ends with the character pair #>. It can occur as part of a source line, as a whole source line, or it can span any number of source lines.

A comment is treated as white space.

The productions above imply that

  • Comments do not nest.
  • The character sequences <# and #> have no special meaning in a single-line comment.
  • The character # has no special meaning in a delimited comment.

The lexical grammar implies that comments cannot occur inside tokens.

(See §A for information about creating script files that contain special-valued comments that are used to generate documentation from script files.)

A requires-comment specifies the criteria that have to be met for its containing script to be allowed to run. The primary criterion is the version of PowerShell being used to run the script. The minimum version requirement is specified as follows:

#requires -Version N[.n]

Where N is the (required) major version and n is the (optional) minor version.

A requires-comment can be present in any script file; however, it cannot be present inside a function or cmdlet. It must be the first item on a source line. A script can contain multiple requires-comments.

A character sequence is only recognized as a comment if that sequence begins with # or <#. For example, hello#there is considered a single token whereas hello #there is considered the token hello followed by a single-line comment. As well as following white space, the comment start sequence can also be preceded by any expression-terminating or statement-terminating character (such as ), }, ], ', ", or ;).

A requires-comment cannot be present inside a snap-in.

There are four other forms of a requires-comment:

#requires --Assembly AssemblyId
#requires --Module ModuleName
#requires --PsSnapIn PsSnapIn [ -Version *N* [.n] ]
#requires --ShellId ShellId

2.2.4 White space

Syntax:

whitespace:
    Any character with Unicode class Zs, Zl, or Zp
    Horizontal tab character (U+0009)
    Vertical tab character (U+000B)
    Form feed character (U+000C)
    ` (The backtick character U+0060) followed by new-line-character

Description:

White space consists of any sequence of one or more whitespace characters.

Except for the fact that white space may act as a separator for tokens, it is ignored.

Unlike some popular languages, PowerShell does not consider line-terminator characters (§2.2.2) to be white space. However, a line terminator can be treated as white space by preceding it immediately by a backtick character, ` (U+0060). This is necessary when the contents of a line are complete syntactically, yet the following line contains tokens intended to be associated with the previous line. For example,

$number = 10 # assigns 10 to $number; nothing is written to the pipeline
+ 20 # writes 20 to the pipeline
- 50 # writes -50 to the pipeline
$number # writes $number's value, 10, to the pipeline

In this example, the backtick indicates the source line is continued. The following expression is equivalent to $number = 10 + 20 - 50.

$number = 10 `
+ 20 `
- 50
$number # writes $number's value to the pipeline
-20

2.3 Tokens

Syntax:

token:
    keyword
    variable
    command
    command-parameter
    command-argument-token
    integer-literal
    real-literal
    string-literal
    type-literal
    operator-or-punctuator

Description:

A token is the smallest lexical element within the PowerShell language.

Tokens can be separated by new-lines, comments, white space, or any combination thereof.

2.3.1 Keywords

Syntax:

keyword: one of
    begin          break          catch       class
    continue       data           define      do
    dynamicparam   else           elseif      end
    exit           filter         finally     for
    foreach        from           function    if
    in             inlinescript   parallel    param
    process        return         switch      throw
    trap           try            until       using
    var            while          workflow

Description:

A keyword is a sequence of characters that has a special meaning when used in a context-dependent place. Most often, this is as the first token in a statement; however, there are other locations, as indicated by the grammar. (A token that looks like a keyword, but is not being used in a keyword context, is a command-name or a command-argument.)

The keywords class, define, from, using, and var are reserved for future use.

Note

Editor's Note: The class and using keywords were introduced in PowerShell 5.0. See about_Classes and about_Using.

2.3.2 Variables

Syntax:

variable:
    $$
    $?
    $^
    $   variable-scope~opt~  variable-characters
    @   variable-scope~opt~  variable-characters
    braced-variable


braced-variable:
    ${   variable-scope~opt~   braced-variable-characters   }

variable-scope:
    global:
    local:
    private:
    script:
    using:
    workflow:
    variable-namespace

variable-namespace:
    variable-characters   :

variable-characters:
    variable-character
    variable-characters   variable-character

variable-character:
    A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nd
    _   (The underscore character U+005F)
    ?

braced-variable-characters:
    braced-variable-character
    braced-variable-characters   braced-variable-character

braced-variable-character:
    Any Unicode character except
        }   (The closing curly brace character U+007D)
        `   (The backtick character U+0060)
    escaped-character

escaped-character:
    `   (The backtick character U+0060) followed by any Unicode character

Description:

Variables are discussed in detail in (§5). The variable $? is discussed in §2.3.2.2. Scopes are discussed in §3.5.

The variables $$ and $^ are reserved for use in an interactive environment, which is outside the scope of this specification.

There are two ways of writing a variable name: A braced variable name, which begins with $, followed by a curly bracket-delimited set of one or more almost-arbitrary characters; and an ordinary variable name, which also begins with $, followed by a set of one or more characters from a more restrictive set than a braced variable name allows. Every ordinary variable name can be expressed using a corresponding braced variable name.

$totalCost
$Maximum_Count_26

$végösszeg # Hungarian
$итог # Russian
$総計 # Japanese (Kanji)

${Maximum_Count_26}
${Name with`twhite space and `{punctuation`}}
${E:\\File.txt}

There is no limit on the length of a variable name, all characters in a variable name are significant, and letter case is not distinct.

There are several different kinds of variables: user-defined (§2.3.2.1), automatic (§2.3.2.2), and preference (§2.3.2.3). They can all coexist in the same scope (§3.5).

Consider the following function definition and calls:

function Get-Power ([long]$base, [int]$exponent) { ... }

Get-Power 5 3 # $base is 5, $exponent is 3
Get-Power -exponent 3 -base 5 # " " "

Each argument is passed by position or name, one at a time. However, a set of arguments can be passed as a group with expansion into individual arguments being handled by the runtime environment. This automatic argument expansion is known as splatting. For example,

$values = 5,3 # put arguments into an array
Get-Power @values

$hash = @{ exponent = 3; base = 5 } # put arguments into a Hashtable
Get-Power @hash

function Get-Power2 { Get-Power @args } # arguments are in an array

Get-Power2 --exponent 3 --base 5 # named arguments splatted named in
@args
Get-Power2 5 3 # position arguments splatted positionally in @args

This is achieved by using @ instead of $ as the first character of the variable being passed. This notation can only be used in an argument to a command.

Names are partitioned into various namespaces each of which is stored on a virtual drive (§3.1). For example, variables are stored on Variable:, environment variables are stored on Env:, functions are stored on Function:, and aliases are stored on Alias:. All of these names can be accessed as variables using the variable-namespace production within variable-scope. For example,

function F { "Hello from F" }
$Function:F # invokes function F

Set-Alias A F
$Alias:A # invokes function F via A

$Count = 10
$Variable:Count # accesses variable Count
$Env:Path # accesses environment variable Path

Any use of a variable name with an explicit Variable: namespace is equivalent to the use of that same variable name without that qualification. For example, $v and $Variable:v are interchangeable.

As well as being defined in the language, variables can also be defined by the cmdlet New-Variable.

2.3.2.1 User-defined variables

Any variable name allowed by the grammar but not used by automatic or preference variables is available for user-defined variables.

User-defined variables are created and managed by user-defined script.

2.3.2.2 Automatic variables

Automatic variables store state information about the PowerShell environment. Their values can be read in user-written script but not written.

Note

The table originally found in this document was removed to reduce duplication. For a complete list of automatic variables, see about_Automatic_Variables.

2.3.2.3 Preference variables

Preference variables store user preferences for the session. They are created and initialized by the PowerShell runtime environment. Their values can be read and written in user-written script.

Note

The table originally found in this document was removed to reduce duplication. For a complete list of preference variables, see about_Preference_Variables.

2.3.3 Commands

Syntax:

generic-token:
    generic-token-parts

generic-token-parts:
    generic-token-part
    generic-token-parts generic-token-part

generic-token-part:
    expandable-string-literal
    verbatim-here-string-literal
    variable
    generic-token-char

generic-token-char:
    Any Unicode character except
        {   }   (   )   ;   ,   |   &   $
        ` (The backtick character U+0060)
        double-quote-character
        single-quote-character
        whitespace
        new-line-character
        escaped-character

generic-token-with-subexpr-start:
    generic-token-parts $(

2.3.4 Parameters

Syntax:

command-parameter:
    dash first-parameter-char parameter-chars colon~opt~

first-parameter-char:
    A Unicode character of classes Lu, Ll, Lt, Lm, or Lo
    _ (The underscore character U+005F)
    ?

parameter-chars:
    parameter-char
    parameter-chars parameter-char

parameter-char:
    Any Unicode character except
        { } ( ) ; , \| & . [
        colon
        whitespace
        new-line-character

colon:
    : (The colon character U+003A)

verbatim-command-argument-chars:
    verbatim-command-argument-part
    verbatim-command-argument-chars verbatim-command-argument-part

verbatim-command-argument-part:
    verbatim-command-string
    & non-ampersand-character
    Any Unicode character except
        |
        new-line-character

non-ampersand-character:
    Any Unicode character except &

verbatim-command-string:
    double-quote-character non-double-quote-chars
    double-quote-character

non-double-quote-chars:
    non-double-quote-char
    non-double-quote-chars non-double-quote-char

non-double-quote-char:
    Any Unicode character except
        double-quote-character

Description:

When a command is invoked, information may be passed to it via one or more arguments whose values are accessed from within the command through a set of corresponding parameters. The process of matching parameters to arguments is called parameter binding.

There are three kinds of argument:

  • Switch parameter (§8.10.5) -- This has the form command-parameter where first-parameter-char and parameter-chars together make up the switch name, which corresponds to the name of a parameter (without its leading -) in the command being invoked. If the trailing colon is omitted, the presence of this argument indicates that the corresponding parameter be set to $true. If the trailing colon is present, the argument immediately following must designate a value of type bool, and the corresponding parameter is set to that value. For example, the following invocations are equivalent:

    Set-MyProcess -Strict
    Set-MyProcess -Strict: $true
    
  • Parameter with argument (§8.10.2) -- This has the form command-parameter where first-parameter-char and parameter-chars together make up the parameter name, which corresponds to the name of a parameter (without its leading -) in the command being invoked. There must be no trailing colon. The argument immediately following designates an associated value. For example, given a command Get-Power, which has parameters $base and $exponent, the following invocations are equivalent:

    Get-Power -base 5 -exponent 3
    Get-Power -exponent 3 -base 5
    
  • Positional argument (§8.10.2) - Arguments and their corresponding parameters inside commands have positions with the first having position zero. The argument in position 0 is bound to the parameter in position 0; the argument in position 1 is bound to the parameter in position 1; and so on. For example, given a command Get-Power, that has parameters $base and $exponent in positions 0 and 1, respectively, the following invokes that command:

    Get-Power 5 3
    

See §8.2 for details of the special parameters -- and --%.

When a command is invoked, a parameter name may be abbreviated; any distinct leading part of the full name may be used, provided that is unambiguous with respect to the names of the other parameters accepted by the same command.

For information about parameter binding see §8.14.

2.3.5 Literals

Syntax:

literal:
    integer-literal
    real-literal
    string-literal

2.3.5.1 Numeric literals

There are two kinds of numeric literals: integer (§2.3.5.1.1) and real (§2.3.5.1.2). Both can have multiplier suffixes (§2.3.5.1.3).

2.3.5.1.1 Integer literals

Syntax:

integer-literal:
    decimal-integer-literal
    hexadecimal-integer-literal

decimal-integer-literal:
    decimal-digits numeric-type-suffix~opt~ numeric-multiplier~opt~

decimal-digits:
    decimal-digit
    decimal-digit decimal-digits

decimal-digit: one of
    0  1  2  3  4  5  6  7  8  9

numeric-type-suffix:
    long-type-suffix
    decimal-type-suffix

hexadecimal-integer-literal:
    0x hexadecimal-digits long-type-suffix~opt~
    numeric-multiplier~opt~

hexadecimal-digits:
    hexadecimal-digit
    hexadecimal-digit decimal-digits

hexadecimal-digit: one of
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

long-type-suffix:
    l

numeric-multiplier: one of
    kb mb gb tb pb

Description:

The type of an integer literal is determined by its value, the presence or absence of long-type-suffix, and the presence of a numeric-multiplier (§2.3.5.1.3).

For an integer literal with no long-type-suffix

  • If its value can be represented by type int (§4.2.3), that is its type;
  • Otherwise, if its value can be represented by type long (§4.2.3), that is its type.
  • Otherwise, if its value can be represented by type decimal (§2.3.5.1.2), that is its type.
  • Otherwise, it is represented by type double (§2.3.5.1.2).

For an integer literal with long-type-suffix

  • If its value can be represented by type long (§4.2.3), that is its type;
  • Otherwise, that literal is ill formed.

In the twos-complement representation of integer values, there is one more negative value than there is positive. For the int type, that extra value is ‑2147483648. For the long type, that extra value is ‑9223372036854775808. Even though the token 2147483648 would ordinarily be treated as a literal of type long, if it is preceded immediately by the unary - operator, that operator and literal are treated as a literal of type int having the smallest value. Similarly, even though the token 9223372036854775808 would ordinarily be treated as a real literal of type decimal, if it is immediately preceded by the unary - operator, that operator and literal are treated as a literal of type long having the smallest value.

Some examples of integer literals are 123 (int), 123L (long), and 200000000000 (long).

There is no such thing as an integer literal of type byte.

2.3.5.1.2 Real literals

Syntax:

real-literal:
    decimal-digits . decimal-digits exponent-part~opt~ decimal-type-suffix~opt~ numeric-multiplier~opt~
    . decimal-digits exponent-part~opt~ decimal-type-suffix~opt~ numeric-multiplier~opt~
    decimal-digits exponent-part decimal-type-suffix~opt~ numeric-multiplier~opt~

exponent-part:
    e sign~opt~  decimal-digits

sign: one of
    +
    dash

decimal-type-suffix:
    d
    l

numeric-multiplier: one of
    kb mb gb tb pb

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

Description:

A real literal may contain a numeric-multiplier (§2.3.5.1.3).

There are two kinds of real literal: double and decimal. These are indicated by the absence or presence, respectively, of decimal-type-suffix. (There is no such thing as a float real literal.)

A double real literal has type double (§4.2.4.1). A decimal real literal has type decimal (§4.2.4.2). Trailing zeros in the fraction part of a decimal real literal are significant.

If the value of exponent-part's decimal-digits in a double real literal is less than the minimum supported, the value of that double real literal is 0. If the value of exponent-part's decimal-digits in a decimal real literal is less than the minimum supported, that literal is ill formed. If the value of exponent-part's decimal-digits in a double or decimal real literal is greater than the maximum supported, that literal is ill formed.

Some examples of double real literals are 1., 1.23, .45e35, 32.e+12, and 123.456E-231.

Some examples of decimal real literals are 1d (which has scale 0), 1.20d (which has scale 2), 1.23450e1d (i.e., 12.3450, which has scale 4), 1.2345e3d (i.e., 1234.5, which has scale 1), 1.2345e-1d (i.e., 0.12345, which has scale 5), and 1.2345e-3d (i.e., 0.0012345, which has scale 7).

Note

Because a double real literal need not have a fraction or exponent part, the grouping parentheses in (123).M are needed to ensure that the property or method M is being selected for the integer object whose value is 123. Without those parentheses, the real literal would be ill-formed.

Note

Although PowerShell does not provide literals for infinities and NaNs, double real literal-like equivalents can be obtained from the static read-only properties PositiveInfinity, NegativeInfinity, and NaN of the types float and double (§4.2.4.1).

The grammar permits what starts out as a double real literal to have an l or L type suffix. Such a token is really an integer literal whose value is represented by type long.

Note

This feature has been retained for backwards compatibility with earlier versions of PowerShell. However, programmers are discouraged from using integer literals of this form as they can easily obscure the literal's actual value. For example, 1.2L has value 1, 1.2345e1L has value 12, and 1.2345e-5L has value 0, none of which is immediately obvious.

2.3.5.1.3 Multiplier suffixes

Syntax:

numeric-multiplier: *one of*
    kb mb gb tb pb

Description:

For convenience, integer and real literals can contain a numeric-multiplier, which indicates one of a set of commonly used powers of 10. numeric-multiplier can be written in any combination of upper- or lowercase letters.

Multiplier Meaning Example
kb kilobyte (1024) 1kb ≡ 1024
mb megabyte (1024 x 1024) 1.30Dmb ≡ 1363148.80
gb gigabyte (1024 x 1024 x 1024) 0x10Gb ≡ 17179869184
tb terabyte (1024 x 1024 x 1024 x 1024) 1.4e23tb ≡ 1.5393162788864E+35
pb petabyte (1024 x 1024 x 1024 x 1024 x 1024) 0x12Lpb ≡ 20266198323167232

2.3.5.2 String literals

Syntax:

string-literal:
    expandable-string-literal
    expandable-here-string-literal
    verbatim-string-literal
    verbatim-here-string-literal

expandable-string-literal:
    double-quote-character expandable-string-characters~opt~  dollars~opt~ double-quote-character

double-quote-character:
    " (U+0022)
    Left double quotation mark (U+201C)
    Right double quotation mark (U+201D)
    Double low-9 quotation mark (U+201E)

expandable-string-characters:
      expandable-string-part
      expandable-string-characters
      expandable-string-part

expandable-string-part:
    Any Unicode character except
        $
        double-quote-character
        ` (The backtick character U+0060)
    braced-variable
    $ Any Unicode character except
        (
        {
        double-quote-character
        ` (The backtick character U+0060)*
    $ escaped-character
    escaped-character
    double-quote-character double-quote-character

dollars:
    $
    dollars $

expandable-here-string-literal:
    @  double-quote-character  whitespace~opt~  new-line-character
        expandable-here-string-characters~opt~  new-line-character  double-quote-character  @

expandable-here-string-characters:
    expandable-here-string-part
    expandable-here-string-characters  expandable-here-string-part

expandable-here-string-part:
    Any Unicode character except
        $
        new-line-character
    braced-variable
    $ Any Unicode character except
        (
        new-line-character
    $ new-line-character  Any Unicode character except double-quote-char
    $ new-line-character double-quote-char  Any Unicode character except @
    new-line-character  Any Unicode character except double-quote-char
    new-line-character double-quote-char  Any Unicode character except @

expandable-string-with-subexpr-start:
    double-quote-character  expandable-string-chars~opt~  $(

expandable-string-with-subexpr-end:
    double-quote-char

expandable-here-string-with-subexpr-start:
    @  double-quote-character  whitespace~opt~  new-line-character  expandable-here-string-chars~opt~  $(

expandable-here-string-with-subexpr-end:
    new-line-character  double-quote-character  @

verbatim-string-literal:
    single-quote-character verbatim-string-characters~opt~ single-quote-char

single-quote-character:
    ' (U+0027)
    Left single quotation mark (U+2018)
    Right single quotation mark (U+2019)
    Single low-9 quotation mark (U+201A)
    Single high-reversed-9 quotation mark (U+201B)

verbatim-string-characters:
    verbatim-string-part
    verbatim-string-characters verbatim-string-part

verbatim-string-part:
    *Any Unicode character except* single-quote-character
    single-quote-character  single-quote-character

verbatim-here-string-literal:
    @ single-quote-character whitespace~opt~  new-line-character
        verbatim-here-string-characters~opt~  new-line-character
            single-quote-character *@*

verbatim-*here-string-characters:
    verbatim-here-string-part
    verbatim-here-string-characters  verbatim-here-string-part

verbatim-here-string-part:
    Any Unicode character except* new-line-character
    new-line-character  Any Unicode character except single-quote-character
    new-line-character  single-quote-character  Any Unicode character except @

Description:

There are four kinds of string literals:

  • verbatim-string-literal (single-line single-quoted), which is a sequence of zero or more characters delimited by a pair of single-quote-characters. Examples are '' and 'red'.

  • expandable-string-literal (single-line double-quoted), which is a sequence of zero or more characters delimited by a pair of double-quote-characters. Examples are "" and "red".

  • verbatim-here-string-literal (multi-line single-quoted), which is a sequence of zero or more characters delimited by the character pairs @single-quote-character and single-quote-character@, respectively, all contained on two or more source lines. Examples are:

    @'
    '@
    
    @'
    line 1
    '@
    
    @'
    line 1
    line 2
    '@
    
  • expandable-here-string-literal (multi-line double-quoted), which is a sequence of zero or more characters delimited by the character pairs @double-quote-character and double-quote-character@, respectively, all contained on two or more source lines. Examples are:

    @"
    "@
    
    @"
    line 1
    "@
    
    @"
    line 1
    line 2
    "@
    

For verbatim-here-string-literals and expandable-here-string-literals, except for white space (which is ignored) no characters may follow on the same source line as the opening delimiter-character pair, and no characters may precede on the same source line as the closing delimiter character pair.

The body of a verbatim-here-string-literal or an expandable-here-string-literal begins at the start of the first source line following the opening delimiter, and ends at the end of the last source line preceding the closing delimiter. The body may be empty. The line terminator on the last source line preceding the closing delimiter is not part of that literal's body.

A literal of any of these kinds has type string (§4.3.1).

The character used to delimit a verbatim-string-literal or expandable-string-literal can be contained in such a string literal by writing that character twice, in succession. For example, 'What''s the time?' and "I said, ""Hello"".". However, a single-quote-character has no special meaning inside an expandable-string-literal, and a double-quote-character has no special meaning inside a verbatim-string-literal.

An expandable-string-literal and an expandable-here-string-literal may contain escaped-characters (§2.3.7). For example, when the following string literal is written to the pipeline, the result is as shown below:

"column1`tcolumn2`nsecond line, `"Hello`", ```Q`5`!"
column1<horizontal-tab>column2<new-line>
second line, "Hello", `Q5!

If an expandable-string-literal or expandable-here-string-literal contains the name of a variable, unless that name is preceded immediately by an escape character, it is replaced by the string representation of that variable's value (§6.7). This is known as variable substitution.

Note

If the variable name is part of some larger expression, only the variable name is replaced. For example, if $a is an array containing the elements 100 and 200, ">$a.Length<" results in >100 200.Length< while ">$($a.Length)<" results in >2<. See sub-expression expansion below.

For example, the source code

$count = 10
"The value of `$count is $count"

results in the expandable-string-literal

The value of $count is 10.

Consider the following:

$a = "red","blue"
"`$a[0] is $a[0], `$a[0] is $($a[0])" # second [0] is taken literally

The result is

$a[0] is red blue[0], $a[0] is red

expandable-string-literals and expandable-here-string-literals also support a kind of substitution called sub-expression expansion, by treating text of the form $( ... ) as a sub-expression (§7.1.6). Such text is replaced by the string representation of that expression's value (§6.8). Any white space used to separate tokens within sub-expression's statement-list is ignored as far as the result string's construction is concerned.

The examples,

$count = 10
"$count + 5 is $($count + 5)"
"$count + 5 is `$($count + 5)"
"$count + 5 is `$(`$count + 5)"

result in the following expandable-string-literals:

10 + 5 is 15
10 + 5 is $(10 + 5)
10 + 5 is $($count + 5)

The following source,

$i = 5; $j = 10; $k = 15
"`$i, `$j, and `$k have the values $( $i; $j; $k )"

results in the following expandable-string-literal:

$i, $j, and $k have the values 5 10 15

These four lines could have been written more succinctly as follows:

"`$i, `$j, and `$k have the values $(($i = 5); ($j = 10); ($k = 15))"

In the following example,

"First 10 squares: $(for ($i = 1; $i -le 10; ++$i) { "$i $($i*$i) " })"

the resulting expandable-string-literal is as follows:

First 10 squares: 1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100

As shown, a sub-expression can contain string literals having both variable substitution and sub-expression expansion. Note also that the inner expandable-string-literal's delimiters need not be escaped; the fact that they are inside a sub-expression means they cannot be terminators for the outer expandable-string-literal.

An expandable-string-literal or expandable-here-string-literal containing a variable substitution or sub-expression expansion is evaluated each time that literal is used; for example,

$a = 10
$s1 = "`$a = $($a; ++$a)"
"`$s1 = >$s1<"
$s2 = "`$a = $($a; ++$a)"
"`$s2 = >$s2<"
$s2 = $s1
"`$s2 = >$s2<"

which results in the following expandable-string-literals:

$s1 = >$a = 10<
$s2 = >$a = 11<
$s2 = >$a = 10<

The contents of a verbatim-here-string-literal are taken verbatim, including any leading or trailing white space within the body. As such, embedded single-quote-characters need not be doubled-up, and there is no substitution or expansion. For example,

$lit = @'
That's it!
2 * 3 = $(2*3)
'@

which results in the literal

That's it!
2 * 3 = $(2*3)

The contents of an expandable-here-string-literal are subject to substitution and expansion, but any leading or trailing white space within the body but outside any sub-expressions is taken verbatim, and embedded double-quote-characters need not be doubled-up. For example,

$lit = @"
That's it!
2 * 3 = $(2*3)
"@

which results in the following literal when expanded:

That's it!
2 * 3 = 6

For both verbatim-here-string-literals and expandable-here-string-literals, each line terminator within the body is represented in the resulting literal in an implementation-defined manner. For example, in

$lit = @"
abc
xyz
"@

the second line of the body has two leading spaces, and the first and second lines of the body have line terminators; however, the terminator for the second line of the body is not part of that body. The resulting literal is equivalent to: "abc<implementation-defined character sequence>xyz".

Note

To aid readability of source, long string literals can be broken across multiple source lines without line terminators being inserted. This is done by writing each part as a separate literal and concatenating the parts with the + operator (§7.7.2). This operator allows its operands to designate any of the four kinds of string literal.

Note

Although there is no such thing as a character literal per se, the same effect can be achieved by accessing the first character in a 1-character string, as follows: [char]"A" or "A"[0].

For both verbatim-here-string-literals and expandable-here-string-literals, each line terminator within the body is represented exactly as it was provided.

2.3.5.3 Null literal

See the automatic variable $null (§2.3.2.2).

2.3.5.4 Boolean literals

See the automatic variables $false and $true (§2.3.2.2).

2.3.5.5 Array literals

PowerShell allows expressions of array type (§9) to be written using the unary comma operator (§7.2.1), array-expression (§7.1.7), the binary comma operator (§7.3), and the range operator (§7.4).

2.3.5.6 Hash literals

PowerShell allows expressions of type Hashtable (§10) to be written using a hash-literal-expression (§7.1.9)

2.3.5.7 Type names

Syntax:

type-name:
    type-identifier
    type-name . type-identifier

type-identifier:
    type-characters

type-characters:
    type-character
    type-characters type-character

type-character:
    A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nd
    _ (The underscore character U+005F)

array-type-name:
    type-name [

generic-type-name:
    type-name [

2.3.6 Operators and punctuators

Syntax:

operator-or-punctuator: one of
    {   }   [   ]   (   )   @(   @{   $(   ;
    &&  ||  &   |   ,   ++  ..   ::   .
    !   *   /   %   +   -   --
    -and   -band   -bnot   -bor
    -bxor   -not   -or     -xor
    assignment-operator
    merging-redirection-operator
    file-redirection-operator
    comparison-operator
    format-operator

assignment-operator: one of
    =  -=  +=  *=  /=  %=

file-redirection-operator: one of
    >  >>  2>  2>>  3>  3>>  4>  4>>
    5>  5>>  6>  6>>  *>  *>>  <

merging-redirection-operator: one of
    *>&1  2>&1  3>&1  4>&1  5>&1  6>&1
    *>&2  1>&2  3>&2  4>&2  5>&2  6>&2

comparison-operator: *one of
    -as           -ccontains      -ceq
    -cge          -cgt            -cle
    -clike        -clt            -cmatch
    -cne          -cnotcontains   -cnotlike
    -cnotmatch    -contains       -creplace
    -csplit       -eq             -ge
    -gt           -icontains      -ieq
    -ige          -igt            -ile
    -ilike        -ilt            -imatch
    -in           -ine            -inotcontains
    -inotlike     -inotmatch      -ireplace
    -is           -isnot          -isplit
    -join         -le             -like
    -lt           -match          -ne
    -notcontains  -notin         -notlike
    -notmatch     -replace       -shl*
    -shr          -split

format-operator:
    -f

Description:

&& and || are reserved for future use.

Note

Editor's Note: The pipeline chain operators && and || were introduced in PowerShell 7. See about_Pipeline_Chain_Operators.

The name following dash in an operator is reserved for that purpose only in an operator context.

An operator that begins with dash must not have any white space between that dash and the token that follows it.

2.3.7 Escaped characters

Syntax:

escaped-character:
    ` (The backtick character U+0060) followed by any Unicode character

Description:

An escaped character is a way to assign a special interpretation to a character by giving it a prefix Backtick character (U+0060). The following table shows the meaning of each escaped-character:

Escaped Character Meaning
`a Alert (U+0007)
`b Backspace (U+0008)
`f Form-feed (U+000C)
`n New-line (U+000A)
`r Carriage return (U+000D)
`t Horizontal tab (U+0009)
`v Vertical tab (U+0009)
`' Single quote (U+0027)
`" Double quote (U+0022)
`` Backtick (U+0060)
`0 NUL (U+0000)
`x If x is a character other than those characters shown above, the backtick character is ignored and x is taken literally.

The implication of the final entry in the table above is that spaces that would otherwise separate tokens can be made part of a token instead. For example, a file name containing a space can be written as Test` Data.txt (as well as 'Test Data.txt' or "Test Data.txt").