PowerShell 是一种用于自动化的命令行 shell 和脚本语言。 与其他 shell(如 Linux 上的 bash 或 Windows 命令行界面 ( cmd.exe ))类似,PowerShell 允许你运行系统上可用的任何命令,而不仅仅是 PowerShell 命令。

命令的类型

对于任何操作系统中的任何 shell,都有三种类型的命令:

  • shell 语言关键字是 shell 脚本语言的一部分。

  • bash 关键字的示例包括: if then else elif fi
  • cmd.exe 关键字的示例包括: dir copy move if echo
  • PowerShell 关键字的示例包括: for foreach try catch trap
  • shell 语言关键字只能在 shell 的运行时环境中使用。 shell 外部没有提供关键字功能的可执行文件。

  • OS 本机命令是操作系统中安装的可执行文件。 可执行文件可以从任何命令行 shell(如 PowerShell)运行。 其中包括可能需要其他 shell 才能正常工作的脚本文件。 例如,如果在 PowerShell 中运行 Windows 批处理脚本( .cmd 文件),PowerShell 将运行 cmd.exe 并传入批处理文件以供执行。

  • shell 环境特定的命令是在外部文件中定义的命令,只能在 shell 的运行时环境中使用。 其中包括脚本和函数,也可以是专门编译的模块,用于将命令添加到 shell 运行时。 在 PowerShell 中,这些命令称为 cmdlet(读作“command-let”)。

    运行本机命令

    任何本机命令都可以从 PowerShell 命令行运行。 通常,运行命令的方式与在 bash cmd.exe 中完全相同。 以下示例演示如何在 Ubuntu Linux 上的 bash 中运行 grep 命令。

    sdwheeler@circumflex:~$ grep sdwheeler /etc/passwd
    sdwheeler:x:1000:1000:,,,:/home/sdwheeler:/bin/bash
    sdwheeler@circumflex:~$ pwsh
    PowerShell 7.2.6
    https://aka.ms/powershell
    Type 'help' to get help.
    

    在 Ubuntu 上启动 PowerShell 后,可以从 PowerShell 命令行运行相同的命令:

    PS /home/sdwheeler> grep sdwheeler /etc/passwd
    sdwheeler:x:1000:1000:,,,:/home/sdwheeler:/bin/bash
    

    将自变量传递到本机命令

    大多数 shell 包括用于使用变量、计算表达式和处理字符串的功能。 但每个 shell 都以不同的方式执行这些操作。 在 PowerShell 中,所有参数都以连字符 (-) 字符开头。 在 cmd.exe 中,大多数参数使用斜杠 (/) 字符。 其他命令行工具可能没有用于参数的特殊字符。

    每个 shell 以其自己的方式在命令行上处理和计算字符串。 在 PowerShell 中运行需要以特定方式引用字符串的本机命令时,可能需要调整传递这些字符串的方式。

    有关详细信息,请参阅以下文章:

  • about_Parsing
  • about_Quoting_Rules
  • PowerShell 7.2 引入了一项新的实验性功能 PSnativeCommandArgumentPassing,它改进了本机命令处理。 有关详细信息,请参阅 PSnativeCommandArgumentPassing

    处理输出和错误

    PowerShell 的输出流也比其他 shell 多。 bashcmd.exe shell 有 stdout 和 stderr。 PowerShell 有六个输出流。 有关详细信息,请参阅 about_Redirectionabout_Output_Streams

    通常,通过本机命令发送到 stdout 的输出会发送到 PowerShell 中的 Success 流。 通过本机命令发送到 stderr 的输出会发送到 PowerShell 中的 Error 流。

    当本机命令包含非零的退出代码时,$? 会设置为 $false。 如果退出代码为零,$? 会设置为 $true

    但是,这一点在 PowerShell 7.2 中发生了更改。 从本机命令重定向的错误记录(例如,使用重定向运算符 (2>&1) 时)不会写入到 PowerShell 的 $Error 变量,并且首选项变量 $ErrorActionPreference 不会影响重定向的输出。

    许多本机命令都会写入到 stderr,来将其作为获取额外信息的备用流。 查找错误时,此行为可能会在 PowerShell 中导致混淆,如果将 $ErrorActionPreference 设置为静音输出的状态,则可能会丢失额外的输出信息。

    PowerShell 7.3 添加了一项新的实验性功能 PSnativeCommandErrorActionPreference,可用于控制是否将输出到 stderr 视为错误。 有关详细信息,请参阅 PSnativeCommandErrorActionPreference

    运行 PowerShell 命令

    如前所述,PowerShell 命令被称为 cmdlet。 cmdlet 收集在 PowerShell 模块中,可按需加载。 可以用任何编译的 .NET 语言或使用 PowerShell 脚本语言本身来编写 cmdlet。

    运行其他命令的 PowerShell 命令

    使用 PowerShell 调用运算符 (&),可以运行存储在变量中并由字符串或脚本块表示的命令。 可以使用此功能运行任何本机命令或 PowerShell 命令。 当你需要动态构造本机命令的命令行参数时,这在脚本中非常有用。 有关详细信息,请参阅调用运算符

    Start-Process cmdlet 可用于运行本机命令,但仅当需要控制命令的执行方式时才应使用。 该 cmdlet 具有支持以下场景的参数:

  • 使用不同的凭据运行命令
  • 隐藏由新进程创建的控制台窗口
  • 重定向 stdin、stdout 和 stderr 流
  • 对命令使用不同的工作目录
  • 以下示例使用重定向的输入流和输出流运行本机命令 sort.exe

    $processOptions = @{
        FilePath = "sort.exe"
        RedirectStandardInput = "TestSort.txt"
        RedirectStandardOutput = "Sorted.txt"
        RedirectStandardError = "SortError.txt"
        UseNewEnvironment = $true
    Start-Process @processOptions
    

    有关详细信息,请参阅 Start-Process

    在 Windows 上,Invoke-Item cmdlet 对指定项执行默认操作。 例如,它运行可执行文件或使用与某一文档文件类型关联的应用程序打开文档文件。 默认操作具体取决于项类型,并由提供对项的访问权限的 PowerShell 提供程序解析。

    以下示例在默认 Web 浏览器中打开 PowerShell 源代码存储库。

    Invoke-Item https://github.com/PowerShell/PowerShell
    

    有关详细信息,请参阅 Invoke-Item

  •