Прочитать на английском

Поделиться через


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

Windows PowerShell 5.1 построен на основе .NET Framework версии 4.5. В выпуске PowerShell 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.

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

.NET Framework и .NET Core

PowerShell в Linux и macOS использует .NET Core, который является подмножеством полной платформы .NET Framework в Microsoft Windows. Это важно, так как PowerShell предоставляет прямой доступ к базовым типам и методам платформы. В результате скрипты, выполняемые в Windows, могут не выполняться на платформах, отличных от 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-current) — основан на .NET 6.0 (LTS-current)
  • 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 Workflow.

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

Командлеты удалены из 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 Командлет
  • Параметр ShowWindowGet-Help

Изменения в конфигурации требуемого состояния PowerShell (DSC)

Invoke-DscResource был восстановлен как экспериментальный компонент в PowerShell 7.0.

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

Изменения исполняемого файла 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 добавлен новый параметр switch UseWindowsPowerShell в Import-Module. Этот коммутатор создает прокси-модуль в PowerShell 7, использующий локальный процесс Windows PowerShell для неявного выполнения любых командлетов, содержащихся в этом модуле. Дополнительные сведения см. в разделе Import-Module.

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

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

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

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

  • USE_MU. Это свойство имеет два возможных значения:
    • 1 (по умолчанию) — выбирает обновление с помощью Центра обновления Майкрософт или WSUS.
    • 0 — Не выбирайте обновление с помощью Центра обновления Майкрософт или WSUS
  • ENABLE_MU
    • 1 (по умолчанию) — выбирает использование Microsoft Update, автоматического обновления или Центра обновления Windows Майкрософт
    • 0 — Не подключайтесь к использованию обновлений Microsoft Update, автоматических обновлений или Центра обновления 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

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

Пропустить проверку на null-элемент для коллекций с элементами значимого типа.

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

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

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

Исправьте $?, чтобы он не становился $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 было удалено из командлетов поставщика FileSystem. Теперь используется новый параметр -AsByteStream, чтобы указать, что поток байтов требуется в качестве входных данных или что выходные данные являются потоком байтов.

Изменение New-ModuleManifest кодирования на UTF8NoBOM на платформах, отличающихся от Windows

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

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

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

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

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

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

Сделайте так, чтобы $PSCulture последовательно отражало изменения культурных параметров во время сеанса.

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

Разрешить явно указанному именованному параметру переопределять тот же параметр, полученный из расщепления хэштаблицы.

При этом изменении именованные параметры из "splatting" перемещаются в конец списка параметров, чтобы их привязка происходила после связывания всех явно указанных именованных параметров. Привязка параметров для простых функций не приводит к ошибке, если указанный именованный параметр не найден. Неизвестные именованные параметры привязаны к $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. В противном случае он вычисляет правый операнд и возвращает результат. Оператор ?? не вычисляет правый операнд, если левый операнд равен ненулевому значению.

$x = $null
$x ?? 100
100

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

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

Оператор присваивания 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

Примечание

Добавлено новое свойство ErrorAccentColor для $Host.PrivateData поддержки изменения цвета акцента сообщения об ошибке.

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

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

$Error | Get-Error

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

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 записей журналов из 5 системных журналов на локальном компьютере 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.

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

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

Это поведение можно переопределить, чтобы отобразить все модули с помощью -SkipEditionCheck параметра switch. Мы также добавили свойство PSEdition к выходным данным таблицы.

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

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

Исправьте Get-Item -LiteralPath a*b, если a*b на самом деле не существует, чтобы вернуть ошибку

Ранее, если встречался подстановочный знак, он обрабатывался так же, как и -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 параметр теперь "no-op" (поскольку он ничего не делает). В дальнейшем все выходные данные будут отображаться с точным представлением чисел, включая все байты для своего типа. Это то, что -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 на платформах, отличных от Windows.

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 можно отфильтровать объект в конвейере по отсутствию свойства или по значению свойства NULL или пустому значению.

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

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 вместо http:// URI приведет к ошибке. Используйте 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 в веб-командлетах PowerShell работает как 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

Неправильное положение параметра привело к тому, что args передается как входные данные, а не как args.

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

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

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

Реализация escape-синтаксического анализа Юникода

`u#### или `u{####} преобразуется в соответствующий символ Юникода. Чтобы вывести литерал `u, избежать обратной символики: ``u.

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

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

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

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

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

  • Измените общедоступные конструкторы WorkflowInfo на внутренние. Мы больше не поддерживаем рабочий процесс, поэтому имеет смысл не разрешать пользователям создавать Workflow экземпляры.
  • Удалите тип System.Management.Automation.DebugSource , так как он используется только для отладки рабочего процесса.
  • Удалите перегрузку SetParent из абстрактного класса Debugger, который используется только для отладки рабочих процессов.
  • Удалите ту же перегрузку класса 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 также поддерживает удаленное взаимодействие PowerShell (PSRP) по протоколу SSH на всех платформах (Windows, macOS и Linux). Дополнительные сведения см. в статье о удаленном взаимодействии SSH в PowerShell.

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

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

В прошлом 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 отправляет базовые данные телеметрии в Корпорацию Майкрософт при запуске. Данные включают имя ОС, версию ОС и версию PowerShell. Эти данные позволяют лучше понять среды, в которых используется PowerShell, и позволяет нам определять приоритеты новых функций и исправлений.

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