Skip to content

powershell

napt.powershell

PowerShell string quoting and file encoding for generated scripts.

Values written into PowerShell source (recipe fields, installer metadata, file paths) can be vendor-controlled, and a value that closes its string early runs as code on the endpoint or the build host.

PowerShell treats typographic quotes as string delimiters too: U+2018 to U+201B close a single-quoted string, U+201C to U+201E a double-quoted one. Both quoting functions escape the full sets. A value that lands outside a string, such as an app name in a comment line, needs a different guard: a line break ends the comment and the rest of the value runs as code, so strip_control_characters removes line breaks and the other control characters first.

ps_single_quote

ps_single_quote(value: str) -> str

Formats a value as a single-quoted PowerShell string literal.

Single-quoted strings are verbatim: no variable expansion, no subexpressions, no backtick escapes. The only characters with meaning are the quote delimiters, which are escaped by doubling. Prefer this form whenever the surrounding PowerShell allows it.

Parameters:

Name Type Description Default
value str

Raw text to embed.

required

Returns:

Type Description
str

The literal including its surrounding quotes.

Example

Quote an MSI product name:

ps_single_quote("Bob's App")  # Returns: "'Bob''s App'"

Source code in napt/powershell.py
def ps_single_quote(value: str) -> str:
    """Formats a value as a single-quoted PowerShell string literal.

    Single-quoted strings are verbatim: no variable expansion, no
    subexpressions, no backtick escapes. The only characters with meaning
    are the quote delimiters, which are escaped by doubling. Prefer this
    form whenever the surrounding PowerShell allows it.

    Args:
        value: Raw text to embed.

    Returns:
        The literal including its surrounding quotes.

    Example:
        Quote an MSI product name:
            ```python
            ps_single_quote("Bob's App")  # Returns: "'Bob''s App'"
            ```

    """
    return "'" + _SINGLE_QUOTE_RE.sub(lambda m: m.group(0) * 2, value) + "'"

ps_escape_double_quoted

ps_escape_double_quoted(value: str) -> str

Escapes a value for use inside a double-quoted PowerShell string.

Backticks, dollar signs, and every double-quote delimiter are prefixed with a backtick so the value reads as literal text instead of closing the string, expanding a variable, or running a $(...) subexpression.

Parameters:

Name Type Description Default
value str

Raw text destined for the inside of a double-quoted string.

required

Returns:

Type Description
str

The escaped text, without surrounding quotes.

Example

Escape an app name for a template placeholder in double quotes:

ps_escape_double_quoted('5" Floppy $1')  # Returns: '5`" Floppy `$1'

Source code in napt/powershell.py
def ps_escape_double_quoted(value: str) -> str:
    """Escapes a value for use inside a double-quoted PowerShell string.

    Backticks, dollar signs, and every double-quote delimiter are prefixed
    with a backtick so the value reads as literal text instead of closing
    the string, expanding a variable, or running a ``$(...)`` subexpression.

    Args:
        value: Raw text destined for the inside of a double-quoted string.

    Returns:
        The escaped text, without surrounding quotes.

    Example:
        Escape an app name for a template placeholder in double quotes:
            ```python
            ps_escape_double_quoted('5" Floppy $1')  # Returns: '5`" Floppy `$1'
            ```

    """
    return _DOUBLE_QUOTED_SPECIAL_RE.sub(lambda m: "`" + m.group(0), value)

strip_control_characters

strip_control_characters(value: str) -> str

Removes line breaks and other control characters from a value.

Quoting keeps a value safe inside a string, but an app name is also written into a comment line and a script filename, where a line break ends the comment (the remainder runs as code) or makes the filename invalid. Each run of control characters becomes a single space.

Parameters:

Name Type Description Default
value str

Raw text, typically an app name from installer metadata or a recipe.

required

Returns:

Type Description
str

The text with every run of control characters replaced by a space

str

and surrounding whitespace trimmed.

Example

Clean a display name read from an installer manifest:

app_name = strip_control_characters(metadata.display_name)

Source code in napt/powershell.py
def strip_control_characters(value: str) -> str:
    """Removes line breaks and other control characters from a value.

    Quoting keeps a value safe inside a string, but an app name is also
    written into a comment line and a script filename, where a line break
    ends the comment (the remainder runs as code) or makes the filename
    invalid. Each run of control characters becomes a single space.

    Args:
        value: Raw text, typically an app name from installer metadata or
            a recipe.

    Returns:
        The text with every run of control characters replaced by a space
        and surrounding whitespace trimmed.

    Example:
        Clean a display name read from an installer manifest:
            ```python
            app_name = strip_control_characters(metadata.display_name)
            ```

    """
    return _CONTROL_RE.sub(" ", value).strip()