Различия между Windows PowerShell 5.1 и PowerShell 7.x

Windows PowerShell 5.1 разработан на базе платформы .NET Framework версии 4.5. Начиная с версии 6.0 PowerShell превратился в проект с открытым исходным кодом на базе .NET Core 2.0. Переход с платформы .NET Framework на .NET Core позволил использовать PowerShell в качестве кросс-платформенного решения. PowerShell поддерживается на платформах Windows, macOS и Linux.

В языке PowerShell есть ряд различий между Windows PowerShell и PowerShell. Самые серьезные различия наблюдаются в доступности и поведении командлетов PowerShell на платформах Windows и платформах, отличных от Windows, а также в изменениях, связанных с различиями между платформами .NET Framework и NET Core.

В этой статье перечислены значительные различия и критические изменения в текущей версии PowerShell по сравнению с Windows PowerShell. В эту сводку не включены добавленные новые функции или командлеты. Кроме того, в этой статье обсуждаются изменения по сравнению с предыдущими версиями. Цель этой статьи — продемонстрировать текущее состояние PowerShell и отличия новой версии от Windows PowerShell. Подробное обсуждение изменений в новых версиях и новых функций см. в статье Новые возможности для каждой из версий.

Платформы .NET Framework и .NET Core

PowerShell в Linux и macOS использует .NET Core, которая является частью полной платформы .NET Framework в Microsoft Windows. Это важно, так как PowerShell предоставляет прямой доступ к базовым типам, методам платформы. В результате скрипты, которые запускаются в Windows, могут не работать в других системах из-за различий в платформах. Дополнительные сведения об изменениях в .NET Core см. в разделе Критические изменения для миграции из .NET Framework в .NET Core.

Каждый новый выпуск PowerShell основан на более новой версии .NET. В .NET могут быть критические изменения, затрагивающие PowerShell.

  • PowerShell 7.5 . Создано на платформе .NET 9.0
  • PowerShell 7.4 — создано на платформе .NET 8.0
  • PowerShell 7.3 . Создано на платформе .NET 7.0
  • PowerShell 7.2 (текущий выпуск LTS) — на основе .NET 6.0 (текущий выпуск LTS)
  • PowerShell 7.1 — на основе .NET 5.0
  • PowerShell 7.0 (LTS) — на основе .NET Core 3.1 (LTS)
  • PowerShell 6.2 — на основе .NET Core 2.1
  • PowerShell 6.1 — на основе .NET Core 2.1
  • PowerShell 6.0 — на основе .NET Core 2.0

С появлением .NET Standard 2.0 PowerShell может загружать многие традиционные модули Windows PowerShell без изменений. Кроме того, PowerShell 7 включает функцию совместимости с Windows PowerShell, которая позволяет использовать модули Windows PowerShell, которым по-прежнему требуется полная версия платформы.

Дополнительные сведения см. в следующих разделах:

Помните об изменениях метода .NET

Хотя изменения методов .NET не относятся к PowerShell, они могут повлиять на скрипты, особенно если вы вызываете методы .NET напрямую. Кроме того, для конструкторов могут возникнуть новые перегрузки. Это может повлиять на способ создания объектов с помощью New-Object или [type]::new() метода.

Например, .NET добавил перегрузки в [System.String]::Split() метод, недоступный в платформа .NET Framework 4.5. В следующем списке показаны перегрузки для метода, доступного Split() в Windows PowerShell 5.1:

PS> "".Split

OverloadDefinitions
-------------------
string[] Split(Params char[] separator)
string[] Split(char[] separator, int count)
string[] Split(char[] separator, System.StringSplitOptions options)
string[] Split(char[] separator, int count, System.StringSplitOptions options)
string[] Split(string[] separator, System.StringSplitOptions options)
string[] Split(string[] separator, int count, System.StringSplitOptions options)

В следующем списке показаны перегрузки для метода, доступного Split() в PowerShell 7:

"".Split

OverloadDefinitions
-------------------
string[] Split(char separator, System.StringSplitOptions options)
string[] Split(char separator, int count, System.StringSplitOptions options)
string[] Split(Params char[] separator)
string[] Split(char[] separator, int count)
string[] Split(char[] separator, System.StringSplitOptions options)
string[] Split(char[] separator, int count, System.StringSplitOptions options)
string[] Split(string separator, System.StringSplitOptions options)
string[] Split(string separator, int count, System.StringSplitOptions options)
string[] Split(string[] separator, System.StringSplitOptions options)
string[] Split(string[] separator, int count, System.StringSplitOptions options)

В Windows PowerShell 5.1 можно передать массив символов (char[]) методу Split()stringв виде. Метод разбивает целевую строку при любом вхождения символа в массиве. Следующая команда разделяет целевую строку в Windows PowerShell 5.1, но не в PowerShell 7:

# PowerShell 7 example
"1111p2222q3333".Split('pq')
1111p2222q3333

Чтобы выполнить привязку к правильной перегрузке, необходимо ввести строку в массив символов:

# PowerShell 7 example
"1111p2222q3333".Split([char[]]'pq')
1111
2222
3333

В комплект поставки модулей больше не входит PowerShell

По различным причинам совместимости следующие модули больше не включаются в PowerShell.

  • ISE
  • Microsoft.PowerShell.LocalAccounts
  • Microsoft.PowerShell.ODataUtils
  • Microsoft.PowerShell.Operation.Validation
  • PSScheduledJob
  • PSWorkflow
  • PSWorkflowUtility

Рабочий процесс PowerShell

Рабочий процесс PowerShell — это компонент Windows PowerShell на основе Windows Workflow Foundation (WF). Он позволяет создавать надежные модули Runbook для долго выполняющихся или параллелизованных задач.

Из-за отсутствия поддержки Windows Workflow Foundation в .NET Core мы удалили рабочий процесс PowerShell из PowerShell.

В будущем мы хотели бы реализовать собственный параллелизм в языке PowerShell без необходимости использовать рабочий процесс PowerShell.

Если нужно возобновить выполнение скрипта после перезагрузки операционной системы с помощью контрольных точек, рекомендуем использовать планировщик задач. Он позволит запустить скрипт при запуске ОС. Но скрипт должен поддерживать свое собственное состояние (например, сохранять его в файле).

Командлеты, удаленные из PowerShell

Для модулей, включенных в PowerShell, следующие командлеты удалены из PowerShell в целях совместимости или для использования неподдерживаемых API.

CimCmdlets

  • Export-BinaryMiLog

Microsoft.PowerShell.Core

  • Add-PSSnapin
  • Export-Console
  • Get-PSSnapin
  • Remove-PSSnapin
  • Resume-Job
  • Suspend-Job

Microsoft.PowerShell.Diagnostics

  • Export-Counter
  • Import-Counter

Microsoft.PowerShell.Management

  • Add-Computer
  • Checkpoint-Computer
  • Clear-EventLog
  • Complete-Transaction
  • Disable-ComputerRestore
  • Enable-ComputerRestore
  • Get-ComputerRestorePoint
  • Get-ControlPanelItem
  • Get-EventLog
  • Get-Transaction
  • Get-WmiObject
  • Invoke-WmiMethod
  • Limit-EventLog
  • New-EventLog
  • New-WebServiceProxy
  • Register-WmiEvent
  • Remove-Computer
  • Remove-EventLog
  • Remove-WmiObject
  • Reset-ComputerMachinePassword
  • Restore-Computer
  • Set-WmiInstance
  • Show-ControlPanelItem
  • Show-EventLog
  • Start-Transaction
  • Test-ComputerSecureChannel
  • Undo-Transaction
  • Use-Transaction
  • Write-EventLog

Microsoft.PowerShell.Utility

  • Convert-String
  • ConvertFrom-String

PSDesiredStateConfiguration

  • Disable-DscDebug
  • Enable-DscDebug
  • Get-DscConfiguration
  • Get-DscConfigurationStatus
  • Get-DscLocalConfigurationManager
  • Publish-DscConfiguration
  • Remove-DscConfigurationDocument
  • Restore-DscConfiguration
  • Set-DscLocalConfigurationManager
  • Start-DscConfiguration
  • Stop-DscConfiguration
  • Test-DscConfiguration
  • Update-DscConfiguration

Командлеты инструментария WMI версии 1

Следующие командлеты WMI версии 1 удалены из PowerShell:

  • Register-WmiEvent
  • Set-WmiInstance
  • Invoke-WmiMethod
  • Get-WmiObject
  • Remove-WmiObject

Командлеты модуля CimCmdlets (или WMI версии 2) выполняют ту же функцию и предоставляют новые функциональные возможности и переработанный синтаксис.

Командлет New-WebServiceProxy удален

.NET Core не поддерживает платформу Windows Communication Framework, которая предоставляет службы для использования протокола SOAP. Этот командлет удален, так как для него нужен протокол SOAP.

*-Transaction командлеты удалены

Эти командлеты использовали очень ограниченный объем использования. Было принято решение о прекращении их поддержки.

  • Complete-Transaction
  • Get-Transaction
  • Start-Transaction
  • Undo-Transaction
  • Use-Transaction

Командлеты *-EventLog

Из-за использования неподдерживаемых API командлеты *-EventLog были удалены из PowerShell. Get-WinEvent и New-WinEvent доступны для получения и создания событий в Windows.

Командлеты, использующие Windows Presentation Framework (WPF)

В .NET Core 3.1 реализована поддержка WPF, поэтому при выпуске PowerShell 7.0 восстановлены следующие функции Windows:

  • Командлет Show-Command
  • Командлет Out-GridView
  • Параметр ShowWindow для Get-Help

Изменения в PowerShell Desired State Configuration (DSC)

Invoke-DscResource восстановлена в качестве экспериментальной функции в PowerShell 7.0.

Начиная с версии PowerShell 7.2 модуль PSDesiredStateConfiguration удален из PowerShell и опубликован в коллекции PowerShell. Дополнительные сведения см. в объявлении в блоге, посвященном PowerShell Team.

Изменения исполняемого файла PowerShell

Переименование powershell.exe в pwsh.exe

Имя исполняемого файла для PowerShell было изменено с powershell(.exe) на pwsh(.exe). Это изменение позволяет пользователям детерминированно запускать PowerShell на компьютерах для поддержки параллельных установок Windows PowerShell и PowerShell.

Дополнительные изменения в pwsh(.exe) из powershell.exe:

  • Первый позиционный параметр изменен с -Command на -File. Это изменение устраняет использование #! в сценариях PowerShell, которые выполняются из оболочек, отличных от PowerShell, на платформах, отличных от Windows. Это также означает, что вы можете выполнять такие команды, как pwsh foo.ps1 или pwsh fooScript, без указания -File. Однако это изменение требует явно указать -c или -Command при попытке запуска таких команд, как pwsh.exe -Command Get-Command.
  • pwsh принимает параметр -i (или -Interactive) для определения интерактивной оболочки. Это позволяет использовать PowerShell в качестве оболочки по умолчанию для платформ Unix.
  • Удалены параметры -ImportSystemModules и -PSConsoleFile из pwsh.exe.
  • Изменены pwsh -version и встроенная справка для pwsh.exe для обеспечения согласованности с другими собственными средствами.
  • Сообщения о недопустимом аргументе для -File и -Command, и коды завершения соответствуют стандартам Unix
  • Добавлен параметр -WindowStyle в Windows. Аналогичным образом обновления для установок на основе пакета на платформах, отличных от Windows, являются обновлениями на месте.

Сокращенное имя также согласуется с именованием оболочек на платформах, отличных от Windows.

Поддержка выполнения скрипта PowerShell с использованием логического параметра

Ранее при использовании pwsh.exe для выполнения скрипта PowerShell с параметром -File было невозможно передать значения $true/$false в качестве значений параметра. Была добавлена поддержка $true/$false в качестве анализируемых значений. Также поддерживаются значения параметров.

Улучшенная обратная совместимость с Windows PowerShell

В Windows для командлета Import-Module добавлен новый параметр UseWindowsPowerShell. Он создает модуль прокси в PowerShell 7, который использует локальный процесс Windows PowerShell для неявного выполнения командлетов, содержащихся в этом модуле. Дополнительные сведения см. в разделе Import-Module.

Дополнительные сведения о модулях Майкрософт, работающих с PowerShell 7.0, см. в таблице совместимости модулей.

Поддержка Центра обновления Майкрософт для Windows

В PowerShell 7.2 была включена поддержка Центра обновления Майкрософт. При включении этой возможности вы будете получать последние обновления PowerShell 7 в традиционном потоке управления клиентского компонента Центра обновления Windows (WU), будь то Центр обновления Windows для бизнеса, WSUS, SCCM или интерактивное диалоговое окно WU в параметрах системы.

Пакет MSI для PowerShell 7.2 содержит следующие параметры командной строки:

  • USE_MU — Это свойство имеет два возможных значения:
    • 1 (по умолчанию) — соглашаться на обновление с помощью Центра обновления Майкрософт или WSUS.
    • 0 — не соглашаться на обновление с помощью Центра обновления Майкрософт или WSUS.
  • ENABLE_MU
    • 1 (по умолчанию) — разрешается использовать Центр обновления Майкрософт, автоматическое обновление или клиентский компонент Центра обновления Windows.
    • 0 — не соглашаться использовать Центр обновления Майкрософт, автоматическое обновление или клиентский компонент Центра обновления Windows.

Изменения подсистемы

Поддержка PowerShell как оболочки UNIX по умолчанию

В Unix оболочки по умолчанию принимают -i для интерактивной оболочки. Многие инструменты ожидают такого поведения (например, script и при установке PowerShell в качестве оболочки по умолчанию) и вызывают оболочку с помощью параметра -i. Это изменение является критическим, так как -i ранее можно было использовать как сокращение для сопоставления с параметром -inputformat, который теперь должен соответствовать -in.

Настраиваемые оснастки

Оснастки PowerShell являются предшественниками модулей PowerShell, которые не имеют широкого распространения в сообществе PowerShell.

Из-за сложности поддержки оснасток и отсутствия их использования в сообществе мы больше не поддерживаем настраиваемые оснастки в PowerShell.

Флаги экспериментальных функций

PowerShell 6.2 включает поддержку экспериментальных возможностей. Это позволяет разработчикам PowerShell предлагать новые функций и получать отзывы до завершения разработки новой версии. Благодаря этому мы можем не вносить критические изменения пока версия разрабатывается.

Используйте командлет Get-ExperimentalFeature, чтобы получить список доступных экспериментальных возможностей. Их можно включить и отключить с помощью Enable-ExperimentalFeature и Disable-ExperimentalFeature соответственно.

Сборка загружается из базового пути к модулю перед попыткой загрузить из глобального кэша сборок

Ранее, если двоичный модуль содержал сборку модуля в глобальном кэше сборок (GAC), мы загружали сборку из GAС и только после этого пытались загрузить ее из базового пути модуля.

Пропуск проверки элемента NULL для коллекций с типом элемента в виде типа значения

Для параметра Mandatory и атрибутов ValidateNotNull и ValidateNotNullOrEmpty пропускается проверка элемента NULL, если тип элемента коллекции является типом значения.

Сохраните $? для ParenExpression, SubExpression и ArrayExpression

Этот запрос на вытягивание изменяет способ компиляции частей конвейера (...), частей выражения $(...) и выражений массива @(), чтобы не присваивать $? значение true автоматически. Вместо этого значение $? будет зависеть от результата выполнения конвейера или операторов.

Исправлено ошибочное значение $false для $? при записи собственной команды в stderr

Для $? не задано значение $false при записи собственной команды в stderr. Обычно, когда собственные команды выполняют запись в stderr, им не нужно сообщать об ошибке. Для $? задается значение $false только тогда, когда собственная команда содержит ненулевой код выхода.

Теперь $ErrorActionPreference не влияет на выходные данные stderr собственных команд

Обычно, когда собственные команды выполняют запись в stderr, им не нужно сообщать об ошибке. В результате этого изменения выходные данные stderr по-прежнему фиксируются в объектах ErrorRecord, но среда выполнения больше не применяет $ErrorActionPreference, если ErrorRecord поступает от собственной команды.

Теперь $OutputEncoding использует кодирование UTF-8 NoBOM, а не ASCII

Предыдущая кодировка, ASCII (7 бит), в некоторых случаях приводила к неправильному изменению выходных данных. Если UTF-8 NoBOM становится кодировкой по умолчанию, выходные данные в Юникоде остаются в кодировке, поддерживаемой большинством инструментов и операционных систем.

Теперь командлеты с параметром -Encoding имеют тип System.Text.Encoding

Значение -EncodingByte было удалено из командлетов поставщика файловой системы. Новый параметр, -AsByteStream, теперь используется для указания того, что в качестве входного потока требуется поток байтов или что выходной поток представляет собой поток байтов.

Кодирование New-ModuleManifest изменено на UTF8NoBOM на платформах, отличных от Windows

Ранее New-ModuleManifest создавал манифесты psd1 в UTF-16 с меткой порядка байтов, создавая проблемы для инструментов Linux. Это критическое изменение, которое изменяет кодировку New-ModuleManifest на UTF (без метки порядка байтов) в платформах, отличных от Windows.

Атрибут AllScope удален из большинства псевдонимов по умолчанию

Чтобы ускорить создание области, атрибут AllScope был удален из большинства псевдонимов по умолчанию. Атрибут AllScope был оставлен для нескольких часто используемых псевдонимов, где поиск выполнялся быстрее.

-Verbose и -Debug больше не переопределяют $ErrorActionPreference

Ранее, если -Verbose или -Debug были указаны, поведение $ErrorActionPreference переопределялось. С этим изменением -Verbose и -Debug больше не влияют на поведение $ErrorActionPreference.

Кроме того, параметр -Debug теперь задает для $DebugPreference значение Continue вместо Inquire.

Теперь $PSCulture согласованно отражает изменения языка и региональных параметров в течение сеанса.

В Windows PowerShell текущее значение языка и региональных параметров кэшируется, что позволяет рассинхронизировать значение с настройками языка и региональных параметров после запуска сеанса. Это поведение кэширования исправлено в PowerShell Core.

Разрешено переопределять явно заданным именованным параметром аналогичный параметр из сплаттинга хэш-таблицы

В результате этого изменения именованные параметры, передаваемые через сплаттинг, перемещаются в конец списка параметров, так что они привязываются после привязки всех явно указанных именованных параметров. При привязке параметров в простых функциях не возникает ошибка, если не удается найти указанный именованный параметр. Неизвестные именованные параметры привязываются к параметру $args простой функции. Перемещение сплаттинга в конец списка аргументов приводит к изменению порядка, в котором параметры следуют в $args.

Например:

function SimpleTest {
    param(
        $Name,
        $Path
    )
    "Name: $Name; Path: $Path; Args: $args"
}

В предыдущем случае аргумент MyPath не привязан к -Path, так как он является третьим в списке аргументов. ## В результате он помещается в '$args' вместе с Blah = "World"

PS> $hash = @{ Name = "Hello"; Blah = "World" }
PS> SimpleTest @hash "MyPath"
Name: Hello; Path: ; Args: -Blah: World MyPath

В результате этого изменения аргументы из @hash перемещаются в конец списка аргументов. MyPath становится первым аргументом в списке, поэтому он привязывается к -Path.

PS> SimpleTest @hash "MyPath"
Name: Hello; Path: MyPath; Args: -Blah: World

Изменения языка

Оператор объединения со значением NULL ??

Оператор объединения со значением NULL ?? возвращает значение левого операнда, если оно не равно NULL. В противном случае он вычисляет правый операнд и возвращает результат. Оператор ?? не вычисляет правый операнд, если значение левого операнда отлично от NULL.

$x = $null
$x ?? 100
100

В следующем примере правый операнд не вычисляется.

[string] $todaysDate = '1/10/2020'
$todaysDate ?? (Get-Date).ToShortDateString()
1/10/2020

Оператор присваивания объединения со значением NULL ??=

Оператор назначения объединения со значением NULL ??= присваивает значение правого операнда левому операнду только в том случае, если левый операнд имеет значение NULL. Оператор ??= не вычисляет правый операнд, если значение левого операнда отлично от NULL.

$x = $null
$x ??= 100
$x
100

В следующем примере правый операнд не вычисляется.

[string] $todaysDate = '1/10/2020'
$todaysDate ??= (Get-Date).ToShortDateString()
1/10/2020

Условные операторы NULL

Примечание.

Эта функция была перенесена из экспериментальной в основную версию PowerShell 7.1.

Условный оператор со значением NULL применяет операцию доступ к операнду, являющемуся элементом (?.) или элементом (?[]), только если значение операнда отлично от NULL. В противном случае он возвращает значение NULL.

Так как в PowerShell символ ? может быть частью имени переменной, для использования этих операторов требуется формальное указание имени переменной. Поэтому имена переменных необходимо заключать в фигурные скобки {}, например ${a}, в том числе если имена содержат символ ?: ${a?}.

В следующем примере возвращается значение PropName.

$a = @{ PropName = 100 }
${a}?.PropName
100

В следующем примере возвращается значение NULL без попытки доступа к элементу PropName.

$a = $null
${a}?.PropName

Аналогичным образом будет возвращено значение элемента.

$a = 1..10
${a}?[0]
1

Если операнд имеет значение NULL, доступ к элементу не производится и возвращается значение NULL.

$a = $null
${a}?[0]

Примечание.

Синтаксис имени переменной ${<name>} не следует путать с оператором вложенных выражений $(). Дополнительные сведения см. в разделе "Имя переменной" about_Variables.

Добавлен оператор & для управления заданиями

Использование & в конце конвейера приводит к тому, что он выполняется как задание PowerShell. Когда конвейер выполняется в фоновом режиме, возвращается объект задания. После запуска конвейера как задания для управления им можно использовать все стандартные командлеты *-Job. Используемые в конвейере переменные (кроме переменных для конкретных процессов) автоматически копируются в это задание, поэтому Copy-Item $foo $bar & работает. Кроме того, задание выполняется в текущем каталоге, а не домашнем каталоге пользователя.

Новые методы и свойства в PSCustomObject

Мы добавили новые методы и свойства в PSCustomObject. PSCustomObject теперь включает свойство Count/Length, как и другие объекты.

$PSCustomObject = [pscustomobject]@{foo = 1}

$PSCustomObject.Length
1
$PSCustomObject.Count
1

Здесь также используются методы ForEach и Where методы, которые позволяют работать с элементами PSCustomObject и фильтровать их.

$PSCustomObject.ForEach({$_.foo + 1})
2
$PSCustomObject.Where({$_.foo -gt 0})
foo
---
  1

Преобразования из PSMethod в делегат

Можно преобразовать PSMethod в делегат. Это позволяет выполнять такие действия, как передача PSMethod[M]::DoubleStrLen в виде значения делегата в [M]::AggregateString.

class M {
    static [int] DoubleStrLen([string] $value) { return 2 * $value.Length }

    static [long] AggregateString([string[]] $values, [func[string, int]] $selector) {
        [long] $res = 0
        foreach($s in $values){
            $res += $selector.Invoke($s)
        }
        return $res
    }
}

[M]::AggregateString((gci).Name, [M]::DoubleStrLen)

Изменение в поведении при сравнении строк в PowerShell 7.1

Версия PowerShell 7.1 создана на основе версии .NET 5.0, в которой представлены следующие критические изменения:

Начиная с версии .NET 5.0, при сравнении неизменяемых строк не учитываются непечатаемые управляющие символы.

Например, следующие две строки считаются идентичными:

# Escape sequence "`a" is Ctrl-G or [char]7
'Food' -eq "Foo`ad"
True

Новые командлеты

Новый командлет Get-Uptime

Командлет Get-Uptime возвращает время, прошедшее с момента последней загрузки операционной системы. Командлет впервые появился в PowerShell 6.0.

Новый командлет Remove-Alias

Командлет Remove-Alias удаляет псевдоним из текущего сеанса PowerShell. Командлет впервые появился в PowerShell 6.0.

Новый командлет Remove-Service

Командлет Remove-Service удаляет службу Windows в реестре и в базе данных службы. Командлет Remove-Service впервые появился в PowerShell 6.0.

Новые командлеты Markdown

Markdown — это стандарт для создания документов с читаемым открытым текстом с базовым форматированием, которое может отображаться в формате HTML.

В PowerShell 6.1 были добавлены следующие командлеты:

  • ConvertFrom-Markdown — преобразование содержимого строки или файла в объект MarkdownInfo.
  • Get-MarkdownOption — возвращает текущие цвета и стили, используемые для отрисовки содержимого Markdown в консоли.
  • Set-MarkdownOption — задает цвета и стили, используемые для отрисовки содержимого Markdown в консоли.
  • Show-Markdown — отображает содержимое Markdown в консоли или в формате HTML

Новый командлет Test-Json

Командлет Test-Json проверяет, является ли строка допустимым документом нотации объектов JavaScript (JSON) и при необходимости может проверить этот документ JSON на соответствие предоставленной схеме.

Этот командлет впервые появился в PowerShell 6.1

Новые командлеты для поддержки экспериментальных функций

Следующие командлеты были добавлены в PowerShell 6.2 для поддержки экспериментальных функций.

Новый командлет Join-String

Командлет Join-String объединяет объекты из конвейера в одну строку. Этот командлет был добавлен в PowerShell 6.2.

Новое представление ConciseView и командлет Get-Error

PowerShell 7.0 использует новое представление ConciseView по умолчанию для сообщений об ошибках, которое улучшает читаемость интерактивных сообщений и ошибок скриптов. Пользователь может выбирать представление с помощью привилегированной переменной $ErrorView.

Если ошибка возникла не в скрипте и не в средстве синтаксического анализа, то в представлении ConciseView сообщение о ней выводится в одной строке:

Get-Childitem -Path c:\NotReal
Get-ChildItem: Cannot find path 'C:\NotReal' because it does not exist

Если ошибка возникла во время выполнения скрипта или синтаксического анализа, в PowerShell возвращается многострочное сообщение об ошибке. Оно содержит ошибку, указатель и описание ошибки с указанием места в строке, где она произошла. Если терминал не поддерживает цветовые escape-последовательности ANSI (VT100), цвета не отображаются.

В PowerShell 7 представление ConciseView используется по умолчанию. Ранее по умолчанию использовалось представление NormalView, и его можно выбрать с помощью переменной $ErrorView.

$ErrorView = 'NormalView' # Sets the error view to NormalView
$ErrorView = 'ConciseView' # Sets the error view to ConciseView

Примечание.

В $Host.PrivateData добавлено новое свойство ErrorAccentColor, позволяющее изменять контрастный цвет сообщения об ошибке.

Новый командлет Get-Error позволяет при необходимости получить полную ошибку со всеми подробными сведениями. По умолчанию этот командлет выводит полные сведения, включая внутренние исключения, о последней произошедшей ошибке.

Командлет Get-Error поддерживает входные данные из конвейера посредством встроенной переменной $Error. Get-Error выводит все ошибки из конвейера.

$Error | Get-Error

Командлет Get-Error поддерживает параметр Newest, позволяющий указывать, сколько ошибок из текущего сеанса нужно вывести.

Get-Error -Newest 3 # Displays the lst three errors that occurred in the session

Дополнительные сведения см. в разделе Get-Error.

Изменения в командлетах

Поддержка параллельного выполнения для ForEach-Object

Начиная с PowerShell 7.0 командлет ForEach-Object, который перебирает элементы в коллекции, теперь имеет встроенную поддержку параллелизма благодаря новому параметру Parallel.

По умолчанию параллельные блоки скриптов используют текущий рабочий каталог вызывающего объекта, который запустил параллельные задачи.

В этом примере извлекаются 50 000 записей из пяти системных журналов на локальном компьютере Windows:

$logNames = 'Security','Application','System','Windows PowerShell','Microsoft-Windows-Store/Operational'

$logEntries = $logNames | ForEach-Object -Parallel {
    Get-WinEvent -LogName $_ -MaxEvents 10000
} -ThrottleLimit 5

$logEntries.Count

50000

С помощью параметра Parallel для каждого входного имени журнала указывается блок скрипта, который выполняется параллельно.

Новый параметр ThrottleLimit ограничивает количество блоков скриптов, выполняющихся параллельно в определенный момент времени. Значение по умолчанию равно 5.

Используйте переменную $_ для представления текущего входного объекта в блоке скрипта. Используйте область $using: для передачи ссылок на переменные в выполняемый блок скрипта.

Дополнительные сведения см. в разделе ForEach-Object.

Проверка system32 на наличие совместимых встроенных модулей в Windows

В обновлении 1809 Windows 10 и Windows Server 2019 мы обновили несколько встроенных модулей PowerShell, и теперь они могут помечаться как совместимые с PowerShell.

При запуске PowerShell будет автоматически включать $windir\System32 как часть переменной среды PSModulePath. Однако она предоставляет модули в Get-Module и Import-Module, только если CompatiblePSEdition помечен как совместимый с Core.

С помощью параметра -SkipEditionCheck это поведение можно переопределить для отображения всех модулей. Мы также добавили свойство PSEdition в выходные данные таблицы.

Псевдоним -lp для всех параметров -LiteralPath

Мы создали псевдоним параметра -lp для всех встроенных командлетов PowerShell, у которых есть параметр -LiteralPath.

Теперь при обработке Get-Item -LiteralPath a*b возвращается ошибка, если a*b фактически не существует.

Раньше при указании подстановочного знака -LiteralPath обрабатывал его так же, как -Path, и если для подстановочного знака не было найдено файлов, автоматически выполнялся выход. Правильное поведение — -LiteralPath является литералом, поэтому, если файл не существует, должна возвращаться ошибка. С этим изменением подстановочные знаки, используемые с -Literal, рассматриваются в качестве литерала.

Установка текущего каталога в качестве рабочего в Start-Job

Теперь командлет Start-Job использует текущий каталог в качестве рабочего каталога для нового задания.

Параметр -Protocol удален из командлетов *-Computer

Из-за проблем с удаленным взаимодействием RPC в CoreFX (особенно на платформах не под управлением Windows) и обеспечением согласованного удаленного взаимодействия в PowerShell параметр -Protocol был удален из командлетов \*-Computer. DCOM больше не поддерживается для удаленного взаимодействия. Следующие командлеты поддерживают только удаленное взаимодействие через WSMAN.

  • Rename-Computer
  • Restart-Computer
  • Stop-Computer

Параметр -ComputerName удален из командлетов *-Service

Чтобы способствовать согласованному использованию PSRP, параметр -ComputerName был удален из командлетов *-Service.

Get-Content -Delimiter исправлен таким образом, чтобы в возвращенных строках не содержался разделитель

Ранее при использовании Get-Content -Delimiter выходные данные были несогласованными и неудобными, так как для удаления разделителя требовалась их дальнейшая обработка. Это изменение удаляет разделитель в возвращаемых строках.

Изменения в Format-Hex

Параметр -Raw теперь не выполняет никаких действий. При пересылке всех выходных данных отображается корректное числовое представление, которое содержит все байты своего типа. Именно эту функцию выполнял параметр -Raw до этого изменения.

Исправлена опечатка в имени свойства Get-ComputerInfo

BiosSerialNumber был написан с ошибкой (как BiosSeralNumber). Теперь ошибка исправлена.

Добавлены командлеты Get-StringHash и Get-FileHash

Это изменение заключается в том, что некоторые хэш-алгоритмы не поддерживаются CoreFX, поэтому они больше недоступны:

  • MACTripleDES
  • RIPEMD160

Добавлена проверка командлетов Get-*, в которых передача значения $null возвращала все объекты вместо ошибки

Передача $null в любой из следующих командлетов теперь вызывает ошибку:

  • Get-Credential -UserName
  • Get-Event -SourceIdentifier
  • Get-EventSubscriber -SourceIdentifier
  • Get-Help -Name
  • Get-PSBreakpoint -Script
  • Get-PSProvider -PSProvider
  • Get-PSSessionConfiguration -Name
  • Get-Runspace -Name
  • Get-RunspaceDebug -RunspaceName
  • Get-Service -Name
  • Get-TraceSource -Name
  • Get-Variable -Name

Добавлена поддержка расширенного формата файла журнала W3C в Import-Csv

Ранее командлет Import-Csv не мог использоваться для непосредственного импорта файлов журнала в расширенный формат журнала W3C и требовалось дополнительное действие. Благодаря этому изменению теперь поддерживается расширенный формат журнала W3C.

Import-Csv применяет PSTypeNames при импорте, если информация о типе присутствует в CSV

Ранее объекты, экспортированные с помощью Export-CSV с информацией TypeInformation, импортированной с помощью ConvertFrom-Csv, не сохраняли информацию о типе. Это изменение добавляет информацию о типе в элемент PSTypeNames, если она доступна в CSV-файле.

Значение -NoTypeInformation используется по умолчанию для Export-Csv

Ранее командлет Export-CSV выводил комментарий в качестве первой строки, содержащей имя типа объекта. Это изменение исключает сведения о типе по умолчанию, поскольку они не понятны большинству инструментов CSV. Это изменение внесено с учетом отзывов клиентов.

Используйте -IncludeTypeInformation, чтобы сохранить предыдущий режим работы.

Разрешено использовать * в пути реестра для Remove-Item

Раньше при указании подстановочного знака -LiteralPath обрабатывал его так же, как -Path, и если для подстановочного знака не было найдено файлов, автоматически выполнялся выход. Правильное поведение — -LiteralPath является литералом, поэтому, если файл не существует, должна возвращаться ошибка. С этим изменением подстановочные знаки, используемые с -Literal, рассматриваются в качестве литерала.

Командлет Group-Object теперь умеет сортировать группы

В рамках оптимизации производительности Group-Object возвращает отсортированный список групп. При этом порядок может быть произвольным, и может оказаться, что это не то, что вам нужно, если вам потребуется первая группа. Мы решили, что это изменение стоит реализовать из-за роста производительности и незначительной зависимости от прежнего поведения командлета.

Стандартное отклонение в Measure-Object

Выходные данные Measure-Object теперь содержат свойство StandardDeviation.

Get-Process | Measure-Object -Property CPU -AllStats
Count             : 308
Average           : 31.3720576298701
Sum               : 9662.59375
Maximum           : 4416.046875
Minimum           :
StandardDeviation : 264.389544720926
Property          : CPU

Get-PfxCertificate -Password

Get-PfxCertificate теперь содержит параметр Password, который принимает значение SecureString. Это позволяет вам использовать его не интерактивно.

$certFile = '\\server\share\pwd-protected.pfx'
$certPass = Read-Host -AsSecureString -Prompt 'Enter the password for certificate: '

$certThumbPrint = (Get-PfxCertificate -FilePath $certFile -Password $certPass ).ThumbPrint

Удаление функции more

Раньше в состав PowerShell входила функция Windows more, которая упаковывала more.com. Сейчас эта функция удалена.

Кроме того, функция help теперь использует команду more.com в Windows или системную команду просмотра по умолчанию, определяемую $env:PAGER, на других платформах.

Теперь cd DriveName: возвращает пользователей в текущий рабочий каталог на этом диске

Раньше при использовании Set-Location или cd для возврата на PSDrive пользователи отправлялись в расположение по умолчанию для этого диска. Теперь пользователи отправляются в последний известный текущий рабочий каталог для данного сеанса.

cd - возвращается в предыдущий каталог

C:\Windows\System32> cd C:\
C:\> cd -
C:\Windows\System32>

Или в Linux

PS /etc> cd /usr/bin
PS /usr/bin> cd -
PS /etc>

Кроме того, cd и cd -- изменяются на $HOME.

Запуск Update-Help без прав администратора

По многочисленным просьбам Update-Help больше не требуется запускать от имени администратора. Теперь Update-Help по умолчанию сохраняет справку в папку пользователя.

Where-Object -Not

После добавления параметра -Not в Where-Object вы можете отфильтровать объект в конвейере для получения отсутствия свойства или нулевого и пустого значения свойства.

Например, эта команда возвращает все службы, у которых нет зависимых служб.

Get-Service | Where-Object -Not DependentServices

Изменения в веб-командлетах

Базовый API .NET веб-командлетов был изменен на System.Net.Http.HttpClient. Это изменение предоставляет множество преимуществ. Тем не менее это изменение вместе с недостатком взаимодействия с Internet Explorer привело к нескольким критическим изменениям в Invoke-WebRequest и Invoke-RestMethod.

  • Invoke-WebRequest теперь поддерживает только основной анализ HTML. Invoke-WebRequest всегда возвращает объект BasicHtmlWebResponseObject. Свойства ParsedHtml и Forms были удалены.
  • Значения BasicHtmlWebResponseObject.Headers теперь имеют тип String[], а не String.
  • BasicHtmlWebResponseObject.BaseResponse теперь является объектом System.Net.Http.HttpResponseMessage.
  • Свойство Response в исключениях веб-командлетов теперь является объектом System.Net.Http.HttpResponseMessage.
  • Строгий анализ заголовка RFC теперь является поведением по умолчанию для параметров -Headers и -UserAgent. Это можно обойти с помощью -SkipHeaderValidation.
  • Схемы URI file:// и ftp:// больше не поддерживаются.
  • Параметры System.Net.ServicePointManager больше не обрабатываются.
  • В настоящее время в macOS нет проверки подлинности на основе сертификатов.
  • Использование -Credential в URI http:// завершится ошибкой. Используйте URI https:// или передайте параметр -AllowUnencryptedAuthentication, чтобы подавить ошибку.
  • -MaximumRedirection теперь создает неустранимую ошибку, если попытки перенаправления превышают указанный предел, вместо возвращения результатов последнего перенаправления.
  • В PowerShell 6.2 мы внесли изменения в кодировку UTF-8 по умолчанию для ответов JSON. Если для ответа JSON не указан набор символов, по умолчанию должна использоваться кодировка UTF-8 в соответствии с RFC 8259.
  • По умолчанию задана кодировка UTF-8 для ответов application-json
  • Параметр -SkipHeaderValidation, позволяющий использовать заголовки Content-Type, которые не соответствуют стандартам
  • Добавлен параметр -Form для упрощенной поддержки multipart/form-data
  • Соответствующая, не учитывающая регистр обработка ключей отношения
  • Добавлен параметр -Resume для веб-командлетов

Invoke-RestMethod возвращает полезные сведения, если данные не возвращаются.

Если API возвращал только значение null, Invoke-RestMethod сериализовал его в качестве строки "null", а не $null. Это изменение исправляет логику в Invoke-RestMethod, чтобы надлежащим образом сериализовать одно допустимое значение литерала JSON null как $null.

Теперь веб-командлеты выдают предупреждение, если -Credential отправляется по незашифрованным подключениям

При использовании HTTP содержимое, включая пароли, отправляется в виде открытого текста. В этом изменении такое поведение запрещено по умолчанию и возвращается ошибка, если учетные данные передаются небезопасно. Пользователи могут обойти это с помощью параметра -AllowUnencryptedAuthentication.

Параметр -OutFile теперь ведет себя в веб-командлетах как -LiteralPath

Начиная с PowerShell 7.1 параметр OutFile веб-командлетов работает как LiteralPath и не обрабатывает подстановочные знаки.

Изменения API

Удален класс AddTypeCommandBase

Класс AddTypeCommandBase был удален из Add-Type для повышения производительности. Этот класс используется только командлетом Add-Type и не должен влиять на пользователей.

Удален VisualBasic как поддерживаемый язык в Add-Type

Раньше для компиляции кода Visual Basic использовался командлет Add-Type. Visual Basic редко использовался с Add-Type. Мы удалили эту функцию, чтобы уменьшить размер PowerShell.

Удалена поддержка RunspaceConfiguration

Ранее при создании пространства выполнения PowerShell программными средствами с помощью API можно было использовать прежние версии RunspaceConfiguration или более новые версии классов InitialSessionState. Это изменение удалило поддержку RunspaceConfiguration, и теперь поддерживается только InitialSessionState.

CommandInvocationIntrinsics.InvokeScript — привязка аргументов к $input, а не к $args

Из-за неверного положения параметра аргументы передавались в качестве входных данных, а не аргументов.

Удаление свойств ClrVersion и BuildVersion из $PSVersionTable

Свойство ClrVersion объекта $PSVersionTable не рекомендуется использовать с CoreCLR. Конечные пользователи не должны использовать это значение для определения совместимости.

Свойство BuildVersion было привязано к версии сборки Windows, однако эта функция недоступна на платформах, отличных от Windows. Используйте свойство GitCommitId, чтобы получить точную версию сборки PowerShell.

Реализован анализ escape-символов в Юникоде

`u#### или `u{####} преобразуются в соответствующий символ Юникода. Для вывода литерала `u добавьте escape-символ в виде обратного апострофа: ``u.

Проблема привязки параметра с ValueFromRemainingArguments в функциях PS

ValueFromRemainingArguments теперь возвращает значения в виде массива, а не одного значения, которое само по себе являлось массивом.

Отменено использование CommandTypes.Workflow и WorkflowInfoCleaned

Очистка кода, связанного с использованием CommandTypes.Workflow и WorkflowInfo в System. Management. Automation.

Эти незначительные критические изменения в основном влияют на код поставщика справки.

  • Измените общедоступные конструкторы WorkflowInfo на внутренние конструкторы. Мы больше не поддерживаем рабочий процесс, поэтому имеет смысл запретить пользователям создавать экземпляры Workflow.
  • Удалите тип System. Management. Automation.DebugSource, так как он используется только для отладки рабочего процесса.
  • Удалите перегрузку SetParent из отладчика абстрактного класса, который используется только для отладки рабочего процесса.
  • Удалите ту же перегрузку SetParent из производного класса RemotingJobDebugger.

Устранен перенос возвращаемого результата в PSObject при преобразовании ScriptBlock в делегат

Когда ScriptBlock преобразуется в тип делегата для использования в контексте C#, перенос результата в PSObject приводит к ненужным проблемам.

  • Когда значение преобразуется в возвращаемый тип-делегат, PSObject по сути разворачивается. Поэтому PSObject не требуется.
  • Если возвращаемый тип-делегат — object, он переносится в PSObject, что затрудняет работу с ним в коде C#.

В результате этого изменения возвращается базовый объект.

Поддержка удаленного взаимодействия

Для удаленного взаимодействия PowerShell (PSRP) с помощью WinRM на платформах UNIX требуется проверка подлинности NTLM/Negotiate или базовая проверка подлинности по протоколу HTTPS. PSRP на macOS поддерживает только базовую проверку подлинности по протоколу HTTPS. Проверка подлинности на основе Kerberos не поддерживается для платформ, отличных от Windows.

PowerShell также поддерживает PSRP через SSH на всех платформах (Windows, macOS и Linux). Дополнительные сведения см. в разделе Удаленное взаимодействие по SSH в PowerShell.

PowerShell Direct для контейнеров сначала пытается использовать pwsh

PowerShell Direct входит в состав PowerShell и Hyper-V и позволяет подключаться к виртуальной машине Hyper-V или контейнеру без сетевого соединения или других служб удаленного управления PowerShell.

В прошлом для подключения PowerShell Direct использовался встроенный экземпляр Windows PowerShell в контейнере. Теперь PowerShell Direct сначала пытается подключиться с помощью любого доступного pwsh.exe в переменной средыPATH. Если pwsh.exe недоступен, PowerShell Direct переключается на использование powershell.exe.

Enable-PSRemoting теперь создает отдельные конечные точки удаленного взаимодействия для предварительных версий

Enable-PSRemoting теперь создает две конфигурации сеанса удаленного взаимодействия.

  • Одна для основного номера версии PowerShell. Например, PowerShell.6. Эта конечная точка может быть основной в обновлениях дополнительного номера версии как конфигурация сеанса PowerShell 6 на уровне системы.
  • Одна конфигурация сеанса для конкретной версии, например: PowerShell.6.1.0

Это полезно, если вы хотите, чтобы на одном компьютере было установлено и доступно несколько версий PowerShell 6.

Кроме того, теперь в предварительных версиях PowerShell доступны собственные конфигурации сеанса удаленного взаимодействия после выполнения командлета Enable-PSRemoting.

C:\WINDOWS\system32> Enable-PSRemoting

Если вы еще не настроили WinRM, выходные данные могут отличаться.

WinRM is already set up to receive requests on this computer.
WinRM is already set up for remote management on this computer.

Затем вы увидите отдельные конфигурации сеанса PowerShell для предварительных и стабильных сборок PowerShell 6, а также для каждой конкретной версии.

Get-PSSessionConfiguration
Name          : PowerShell.6.2-preview.1
PSVersion     : 6.2
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name          : PowerShell.6-preview
PSVersion     : 6.2
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name          : powershell.6
PSVersion     : 6.1
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name          : powershell.6.1.0
PSVersion     : 6.1
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Синтаксис user@host:port, поддерживаемый для SSH

SSH-клиенты обычно поддерживают строки подключения в формате user@host:port. С появлением SSH как протокола для удаленного взаимодействия PowerShell мы добавили поддержку этого формата строки подключения.

Enter-PSSession -HostName fooUser@ssh.contoso.com:2222

Данные телеметрии можно отключить только с помощью переменной среды

PowerShell отправляет основные данные телеметрии в корпорацию Microsoft при запуске. В эти данные входят имя ОС, версия ОС и версия PowerShell. Они позволяют нам лучше понимать среды, где используется PowerShell, а также приоритизировать новые функции и исправления.

Чтобы отказаться от использования данных телеметрии, задайте для переменной среды POWERSHELL_TELEMETRY_OPTOUT значение true, yes или 1. Мы больше не поддерживаем удаление файла DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY для отключения телеметрии.