Diferenças entre o Windows PowerShell 5.1 e o PowerShell 7.x

O Windows PowerShell 5.1 é criado na plataforma .NET Framework v4.5. Com o lançamento do PowerShell 6.0, o PowerShell se tornou um projeto de código aberto criado na plataforma .NET Core 2.0. A migração do .NET Framework para o .NET Core permitiu que o PowerShell se transformasse em uma solução multiplataforma. O PowerShell é executado no Windows, no macOS e no Linux.

Há algumas diferenças na linguagem do PowerShell entre o Windows PowerShell e o PowerShell. As diferenças mais perceptíveis são relacionadas à disponibilidade e ao comportamento dos cmdlets do PowerShell entre plataformas Windows e não Windows, juntamente com as alterações que derivam das diferenças entre o .NET Framework e o .NET Core.

Este artigo resume as diferenças significativas e as alterações interruptivas entre Windows PowerShell e a versão atual do PowerShell. Este resumo não inclui novos recursos nem cmdlets que foram adicionados. Este artigo também não aborda o que mudou entre as versões. A meta deste artigo é apresentar o estado atual do PowerShell e como isso é diferente do Windows PowerShell. Para uma discussão detalhada sobre as alterações entre as versões e a adição de novos recursos, confira os artigos Novidades de cada versão.

.NET Framework versus .NET Core

O PowerShell no Linux/macOS usa o .NET Core, que é um subconjunto do .NET Framework completo no Microsoft Windows. Isso é significativo, pois o PowerShell fornece acesso direto aos métodos e tipos de estrutura subjacentes. Como resultado, scripts executados no Windows não podem ser executados em outras plataformas devido às diferenças nas estruturas. Para obter mais informações sobre as alterações no .NET Core, confira Alterações interruptivas para a migração do .NET Framework para o .NET Core.

Cada nova versão do PowerShell é criada com base na versão mais recente do .NET. Pode haver alterações importantes no .NET que afetem o PowerShell.

  • PowerShell 7.5 – Com base no .NET 9.0
  • PowerShell 7.4 – Com base no .NET 8.0
  • PowerShell 7.3 – Com base no .NET 7.0
  • PowerShell 7.2 (atual LTS) - Com base no .NET 6.0 (atual LTS)
  • PowerShell 7.1 - Com base no .NET 5.0
  • PowerShell 7.0 (LTS) - Com base no .NET Core 3.1 (LTS)
  • PowerShell 6.2 - Com base no .NET Core 2.1
  • PowerShell 6.1 - Com base no .NET Core 2.1
  • PowerShell 6.0 - Com base no .NET Core 2.0

Com o advento do .NET Standard 2.0, o PowerShell pode carregar vários módulos tradicionais do Windows PowerShell sem modificação. Além disso, o PowerShell 7 inclui um recurso de compatibilidade do Windows PowerShell que permite que você use módulos do Windows PowerShell que ainda exigem a estrutura completa.

Para obter mais informações, consulte:

Esteja ciente das alterações do método .NET

Embora as alterações do método .NET não sejam específicas do PowerShell, elas podem afetar seus scripts, especialmente se você estiver chamando métodos .NET diretamente. Além disso, pode haver novas sobrecargas para construtores. Isso pode ter um impacto na forma como você cria objetos usando o método New-Object ou [type]::new().

Por exemplo, o .NET adicionou sobrecargas ao método [System.String]::Split() que não está disponível no .NET Framework 4.5. A seguinte lista mostra as sobrecargas para o método Split() disponível no 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)

A seguinte lista mostra as sobrecargas para o método Split() disponível no 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)

No Windows PowerShell 5.1, você pode passar uma matriz de caracteres (char[]) para o método Split() como um string. O método divide a cadeia de caracteres de destino em qualquer ocorrência de um caractere na matriz. O seguinte comando divide a cadeia de caracteres de destino no Windows PowerShell 5.1, mas não no PowerShell 7:

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

Para associar à sobrecarga correta, você precisa fazer typecast da cadeia de caracteres para uma matriz de caracteres:

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

Módulos que não são mais fornecidos com o PowerShell

Por vários motivos de compatibilidade, os módulos a seguir não estão mais incluídos no PowerShell.

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

Fluxo de trabalho do PowerShell

Fluxo de Trabalho do PowerShell é um recurso no Windows PowerShell baseado no Windows Workflow Foundation (WF) que permite a criação de runbooks robustos para tarefas em paralelo ou de longa duração.

Devido à falta de suporte a Windows Workflow Foundation no .NET Core, o Fluxo de Trabalho do PowerShell foi removido do PowerShell.

Futuramente, gostaríamos de habilitar o paralelismo/simultaneidade nativa na linguagem do PowerShell sem a necessidade do Fluxo de Trabalho do PowerShell.

Se houver a necessidade de usar pontos de verificação para retomar um script após a reinicialização do sistema operacional, recomendamos o uso de Agendador de Tarefas para executar um script na inicialização do sistema, mas o script precisaria manter o próprio estado (como mantê-lo em um arquivo).

Cmdlets removidos do PowerShell

Para os módulos incluídos no PowerShell, os cmdlets a seguir foram removidos do PowerShell por vários motivos de compatibilidade ou o uso de APIs incompatíveis.

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

Cmdlets do WMI v1

Os seguintes cmdlets WMI v1 foram removidos do PowerShell:

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

Os cmdlets do módulo CimCmdlets (também conhecido como WMI v2) executam a mesma função e fornecem uma nova funcionalidade e uma sintaxe reprojetada.

cmdlet New-WebServiceProxy removido

O .NET Core não dá suporte ao Windows Communication Framework, que fornece serviços para o uso do protocolo SOAP. Esse cmdlet foi removido porque requer o SOAP.

Cmdlets *-Transaction removidos

Esses cmdlets tinham uso muito limitado. A decisão foi tomada para descontinuar o suporte para eles.

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

Cmdlets de *-EventLog

Devido ao uso de APIs incompatíveis, os cmdlets *-EventLog foram removidos do PowerShell. Get-WinEvent e New-WinEvent estão disponíveis para obter e criar eventos no Windows.

Cmdlets que usam o WPF (Windows Presentation Framework)

O .NET Core 3.1 adicionou suporte ao WPF, portanto, o lançamento do PowerShell 7.0 restaurou os seguintes recursos específicos do Windows:

  • O cmdlet Show-Command
  • O cmdlet Out-GridView
  • O parâmetro ShowWindow de Get-Help

Alterações na DSC (Desired State Configuration) do PowerShell

Invoke-DscResource foi restaurado como um recurso experimental no PowerShell 7.0.

Do PowerShell 7.2 em diante, o módulo PSDesiredStateConfiguration foi removido do PowerShell e publicado no Galeria do PowerShell. Para obter mais informações, confira o comunicado no blog da Equipe do PowerShell.

Alterações executáveis do PowerShell

powershell.exe renomeado para pwsh.exe

O nome do binário para o PowerShell foi alterado de powershell(.exe) para pwsh(.exe). Essa alteração oferece uma forma determinística para que os usuários executem o PowerShell em computadores e deem suporte a instalações lado a lado do PowerShell e do Windows PowerShell.

Alterações adicionais para pwsh(.exe) de powershell.exe:

  • O primeiro parâmetro posicional foi alterado de -Command para -File. Essa alteração corrige o uso de #! (também conhecido como um shebang) em scripts do PowerShell que estão sendo executados de shells não PowerShell em plataformas não Windows. Isso também significa que você pode executar comandos como pwsh foo.ps1 ou pwsh fooScript sem especificar -File. No entanto, essa alteração exige que você especifique explicitamente -c ou -Command ao tentar executar comandos como pwsh.exe -Command Get-Command.
  • O pwsh aceita o comutador -i (ou -Interactive) para indicar um shell interativo. Isso permite que o PowerShell seja usado como um shell padrão em plataformas Unix.
  • Parâmetros -ImportSystemModules e -PSConsoleFile removidos de pwsh.exe.
  • pwsh -version alterado e ajuda interna para pwsh.exe para se alinhar com outras ferramentas nativas.
  • Mensagens de erro de argumento inválido para -File e -Command, bem como códigos de saída consistentes com os padrões do Unix
  • Parâmetro -WindowStyle adicionado no Windows. Da mesma forma, atualizações de instalações baseadas no pacote em plataformas não Windows são atualizações in-loco.

O nome abreviado também é consistente com a nomenclatura dos shells em plataformas não Windows.

Suporte à execução de um script do PowerShell com o parâmetro bool

Antes, usar o pwsh.exe para executar um script do PowerShell usando -File não fornecia uma forma de passar $true/$false como valores de parâmetro. Adicionamos suporte para $true/$false como valores analisados para parâmetros. Também há suporte para valores de opção.

Melhor compatibilidade com versões anteriores do Windows PowerShell

Para o Windows, um novo parâmetro de opção UseWindowsPowerShell é adicionado ao Import-Module. Essa opção cria um módulo proxy no PowerShell 7 que usa um processo local do Windows PowerShell para executar implicitamente todos os cmdlets contidos nesse módulo. Para obter mais informações, consulte Import-Module.

Para obter mais informações sobre quais módulos da Microsoft funcionam com o PowerShell 7.0, confira a Tabela de Compatibilidade de Módulos.

Suporte para Microsoft Update para Windows

O PowerShell 7.2 adicionou suporte para Microsoft Update. Ao habilitar esse recurso, você receberá as atualizações mais recentes do PowerShell 7 em seu fluxo de gerenciamento tradicional do WU (Windows Update), seja com o Windows Update for Business, WSUS, SCCM ou a caixa de diálogo interativa do WU em Configurações.

O pacote MSI do PowerShell 7.2 inclui as seguintes opções de linha de comando:

  • USE_MU – essa propriedade tem dois valores possíveis:
    • 1 (padrão) – opta por atualizar por meio do Microsoft Update ou WSUS
    • 0 – não opta por atualizar por meio do Microsoft Update ou do WSUS
  • ENABLE_MU
    • 1 (padrão) – opta por usar o Microsoft Update, Atualizações Automáticas ou o Windows Update
    • 0 – não opta por usar Microsoft Update, Atualizações Automáticas ou o Windows Update

Alterações no mecanismo

Suporte para o PowerShell como um shell Unix padrão

Em Unix, é padrão dos shells aceitar -i para um shell interativo, e muitas ferramentas esperam esse comportamento (script por exemplo e ao configurar o PowerShell como o shell padrão) e chama o shell com a opção -i. Essa alteração causa falhas, pois, antes, -i podia ser usado como uma síntese disponível para corresponder -inputformat, e agora precisa ser -in.

Snap-ins personalizados

Snap-ins do PowerShell são um predecessor dos módulos do PowerShell que não têm ampla adoção da comunidade do PowerShell.

Devido à complexidade do suporte aos snap-ins e à falta de uso da comunidade, não oferecemos mais suporte a snap-ins personalizados no PowerShell.

Sinalizadores de recursos experimentais

O PowerShell 6.2 habilitou o suporte aos Recursos experimentais. Isso possibilita aos desenvolvedores do PowerShell fornecer novos recursos e obter comentários antes da conclusão do design. Dessa maneira, evitamos fazer alterações significativas à medida que o projeto evolui.

Use Get-ExperimentalFeature para obter uma lista de recursos experimentais disponíveis. Você pode habilitar ou desabilitar esses recursos com Enable-ExperimentalFeature e Disable-ExperimentalFeature.

Carregamento do assembly do caminho base do módulo antes de tentar carregar do GAC

Anteriormente, quando um módulo binário tinha o assembly do módulo no GAC, carregávamos o assembly do GAC antes de tentar carregá-lo do caminho base do módulo.

Verificação de elemento nulo ignorada para coleções com um tipo de elemento de tipo de valor

Para o parâmetro Mandatory e os atributos ValidateNotNull e ValidateNotNullOrEmpty, ignore a verificação de elemento nulo se o tipo de elemento da coleção for um tipo de valor.

Preservação de $? para ParenExpression, SubExpression e ArrayExpression

Essa PR altera o modo como compilamos subpipelines (...), subexpressões $(...) e expressões de matriz @() para que $? não seja automaticamente true. Em vez disso, o valor de $? depende do resultado do pipeline ou das instruções executadas.

Correção de $? para não ser $false quando o comando nativo gravar em stderr

$? não está definido como $false quando o comando nativo grava em stderr. É comum que comandos nativos gravem em stderr sem a intenção de indicar uma falha. $? está definido como $false somente quando o comando nativo tem um código de saída diferente de zero.

Fazer com que $ErrorActionPreference não afete a saída stderr de comandos nativos

É comum que comandos nativos gravem em stderr sem a intenção de indicar uma falha. Com essa alteração, a saída stderr ainda será capturada em objetos ErrorRecord, mas o runtime não aplicará $ErrorActionPreference se o ErrorRecord vier de um comando nativo.

Alteração do $OutputEncoding para usar codificação UTF-8 NoBOM em vez de ASCII

A codificação anterior, ASCII (7 bits), resultaria em alteração incorreta da saída em alguns casos. Ao tornar o UTF-8 NoBOM padrão, a saída Unicode é preservada com uma codificação compatível com a maioria das ferramentas e dos sistemas operacionais.

Unificação dos cmdlets com o parâmetro -Encoding para o tipo System.Text.Encoding

O valor de -Encoding, Byte, foi removido dos cmdlets do provedor do sistema de arquivos. Agora, um novo parâmetro, -AsByteStream, é usado para especificar a exigência de um fluxo de bytes como entrada, ou que a saída seja um fluxo de bytes.

Alteração da codificação New-ModuleManifest para UTF8NoBOM em plataformas que não são o Windows

Antes, o New-ModuleManifest criava manifestos psd1 em UTF-16 com BOM, criando um problema para as ferramentas do Linux. Essa alteração da falha altera a codificação de New-ModuleManifest para UTF (sem BOM) em plataformas que não são Windows.

Remoção de AllScope da maioria dos aliases padrão

Para acelerar a criação de escopo, AllScope foi removido da maioria dos aliases padrão. AllScope foi deixado por alguns aliases usados com frequência nos quais a pesquisa foi mais rápida.

-Verbose e -Debug não substituem mais $ErrorActionPreference

Antes, se -Verbose ou -Debug fosse especificado, substituiria o comportamento de $ErrorActionPreference. Com essa alteração, -Verbose e -Debug não afetam mais o comportamento de $ErrorActionPreference.

O parâmetro -Debug agora define $DebugPreference como Continuar ao invés de Consultar.

Alteração para que $PSCulture reflita consistentemente as alterações de cultura na sessão

No Windows PowerShell, o valor de cultura atual é armazenado em cache, o que pode permitir que o valor saia de sincronização com a cultura e seja alterado após a inicialização da sessão. Esse comportamento de cache é corrigido no PowerShell Core.

Permitir que o parâmetro nomeado especificado explicitamente substitua o mesmo no nivelamento de tabela de hash

Com essa alteração, os parâmetros nomeados do nivelamento são movidos para o final da lista de parâmetros. Dessa maneira, eles ficam associados após todos os parâmetros nomeados especificados serem explicitamente associados. A associação de parâmetros para funções simples não gera erros quando um parâmetro nomeado especificado não pode ser encontrado. Parâmetros nomeados desconhecidos são associados ao parâmetro $args da função simples. Mover o nivelamento para o final da lista de argumentos altera a ordem em que os parâmetros aparecem em $args.

Por exemplo:

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

No comportamento anterior, MyPath não está associado a -Path porque está em terceiro na lista de argumentos. ## Por isso, é colocado em '$args' junto com Blah = "World".

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

Com essa alteração, os argumentos de @hash são movidos para o final da lista de argumentos. MyPath se torna o primeiro argumento na lista, portanto, associado a -Path.

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

Alterações de linguagem

Operador de avaliação de nulo ??

O operador de avaliação de nulo ?? retorna o valor do seu operando esquerdo caso não seja nulo. Caso contrário, ele avalia o operando do lado direito e retorna seu resultado. O operador ?? não avaliará o operando do lado direito se o operando esquerdo for avaliado como não nulo.

$x = $null
$x ?? 100
100

No exemplo a seguir, o operando à direita não será avaliado.

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

Operador de atribuição de avaliação de nulo ??=

O operador de atribuição de avaliação de nulo ??= atribuirá o valor do operando do lado direito para o operando esquerdo somente se o operando esquerdo for avaliado como nulo. O operador ??= não avaliará o operando do lado direito se o operando esquerdo for avaliado como não nulo.

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

No exemplo a seguir, o operando à direita não será avaliado.

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

Operadores condicionais null

Observação

Esse recurso foi movido de experimental para base no PowerShell 7.1.

Um operador condicional nulo aplicará uma operação de acesso de membro ?. ou de acesso de elemento ?[] ao operando somente se esse operando for avaliado como não nulo; caso contrário, ele retornará nulo.

Como o PowerShell permite que ? faça parte do nome da variável, é necessária uma especificação formal do nome da variável para usar esses operadores. Portanto, é necessário usar {} em torno dos nomes de variáveis, como ${a} ou quando ? faz parte do nome da variável ${a?}.

No exemplo a seguir, o valor de PropName é retornado.

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

O exemplo a seguir retornará nulo, sem tentar acessar o nome do membro PropName.

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

Da mesma forma, o valor do elemento será retornado.

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

Quando o operando é nulo, o elemento não é acessado e nulo é retornado.

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

Observação

A sintaxe do nome da variável de ${<name>} não deve ser confundida com o operador de subexpressão $(). Para obter mais informações, confira a seção Nome da variável de about_Variables.

Adição do operador & para controle de trabalho

Colocar & no final de um pipeline faz com que o pipeline seja executado como um trabalho do PowerShell. Quando um pipeline é colocado em segundo plano, um objeto de trabalho é retornado. Quando o pipeline estiver em execução como um trabalho, todas os cmdlets *-Job padrão podem ser usados para gerenciar o trabalho. Variáveis (ignorando variáveis específicas do processo) usadas no pipeline são copiadas automaticamente para o trabalho e Copy-Item $foo $bar & funciona. Além disso, o trabalho é executado no diretório atual em vez do diretório base do usuário.

Novos métodos/propriedades em PSCustomObject

Adicionamos novos métodos e propriedades ao PSCustomObject. PSCustomObject agora inclui uma propriedade Count/Length como outros objetos.

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

$PSCustomObject.Length
1
$PSCustomObject.Count
1

Esse trabalho também inclui os métodos ForEach e Where, que permitem que você utilize e filtre os itens PSCustomObject:

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

Conversões de PSMethod para delegado

Você pode converter um PSMethod em um delegado. Isso permite realizar ações como transmitir PSMethod[M]::DoubleStrLen como valor delegado para [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)

Comportamento de comparação de string alterado no PowerShell 7.1

O PowerShell 7.1 tem como base o .NET 5.0, que introduziu a seguinte alteração importante:

A partir do .NET 5.0, as comparações de cadeia de caracteres invariáveis de cultura ignoram caracteres de controle não imprimíveis.

Por exemplo, as duas strings a seguir são consideradas idênticas:

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

Novos cmdlets

Novo cmdlet Get-Uptime

O cmdlet Get-Uptime retorna o tempo decorrido desde a última inicialização do sistema operacional. Esse cmdlet foi introduzido no PowerShell 6.0.

Novo cmdlet Remove-Alias

O cmdlet Remove-Alias remove um alias da sessão atual do PowerShell. Esse cmdlet foi introduzido no PowerShell 6.0.

Novo cmdlet Remove-Service

O cmdlet Remove-Service remove um serviço Windows no Registro e no banco de dados de serviço. O cmdlet Remove-Service foi introduzido no PowerShell 6.0.

Novos cmdlets de Markdown

O markdown é um padrão para a criação de documentos de texto não criptografado legíveis com formatação básica que possam ser renderizados em HTML.

Os seguintes cmdlets foram adicionados no PowerShell 6.1:

  • ConvertFrom-Markdown – converte o conteúdo de uma cadeia de caracteres ou de um arquivo em um objeto MarkdownInfo.
  • Get-MarkdownOption – retorna as cores e estilos atuais usados para renderizar o conteúdo de Markdown no console.
  • Set-MarkdownOption – define as cores e estilos usados para renderizar o conteúdo de Markdown no console.
  • Show-Markdown – exibe o conteúdo de Markdown no console ou como HTML

Novo cmdlet Test-Json

O cmdlet Test-Json testa se uma cadeia de caracteres é um documento JSON (JavaScript Object Notation) válido e pode, opcionalmente, verificar esse documento JSON em relação a um esquema fornecido.

Esse cmdlet foi introduzido no PowerShell 6.1

Novos cmdlets para dar suporte a recursos experimentais

Os cmdlets a seguir foram adicionados no PowerShell 6.2 para dar suporte a recursos experimentais.

Novo cmdlet Join-String

O cmdlet Join-String combina objetos do pipeline em uma cadeia de caracteres. Esse cmdlet foi adicionado ao PowerShell 6.2.

Novo modo de exibição ConciseView e cmdlet Get-Error

O PowerShell 7.0 aprimora a exibição de mensagens de erro para aprimorar a legibilidade dos erros interativos e de script com um novo modo de exibição padrão ConciseView. Os modos de exibição são selecionáveis pelo usuário por meio da variável de preferência $ErrorView.

Com ConciseView, se um erro não for de script ou do analisador, será exibida uma mensagem de erro de linha única:

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

Se o erro ocorrer durante a execução do script ou for um erro de análise, o PowerShell retornará uma mensagem de erro de várias linhas que contém o erro, um ponteiro e uma mensagem mostrando onde está o erro nessa linha. Se o terminal não oferecer suporte a sequências de escape de cor ANSI (VT100), as cores não serão exibidas.

O modo de exibição padrão no PowerShell 7 é ConciseView. O modo de exibição padrão anterior era NormalView, que você pode selecionar definindo a variável de preferência $ErrorView.

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

Observação

Uma nova propriedade ErrorAccentColor é adicionada a $Host.PrivateData para dar suporte à alteração da cor de destaque da mensagem de erro.

Quando desejado, um novo cmdlet Get-Error fornece um modo de exibição detalhado e completo do erro totalmente qualificado. Por padrão, o cmdlet exibe os detalhes completos, incluindo as exceções internas, do último erro que ocorreu.

O cmdlet Get-Error dá suporte à entrada do pipeline usando a variável interna $Error. Get-Error exibe todos os erros direcionados.

$Error | Get-Error

O cmdlet Get-Error dá suporte ao parâmetro Newest, permitindo especificar quantos erros da sessão atual você deseja exibir.

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

Para obter mais informações, confira Get-Error.

Alterações de cmdlet

Execução paralela adicionada ao ForEach-Object

A partir do PowerShell 7.0, o cmdlet ForEach-Object, que itera itens em uma coleção, agora tem paralelismo interno com o novo parâmetro Parallel.

Por padrão, os blocos de script paralelos usam o diretório de trabalho atual do chamador que iniciou as tarefas paralelas.

Este exemplo recupera 50.000 entradas de log de 5 logs do sistema em um computador Windows local:

$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

O parâmetro Parallel especifica o bloco de script que é executado em paralelo para cada nome de log de entrada.

O novo parâmetro ThrottleLimit limita o número de blocos de script em execução paralelamente em determinado momento. O padrão é 5.

Use a variável $_ para representar o objeto de entrada atual no bloco de script. Use o escopo $using: para passar referências de variáveis ao bloco de script em execução.

Para obter mais informações, confira ForEach-Object.

Verificar em system32 se há módulos internos compatíveis no Windows

Na atualização 1809 do Windows 10 e no Windows Server 2019, atualizamos alguns módulos internos do PowerShell para marcá-los como compatíveis com o PowerShell.

Quando o PowerShell for iniciado, ele incluirá $windir\System32 automaticamente como parte da variável de ambiente PSModulePath. No entanto, expõe módulos somente para Get-Module e Import-Module se seu CompatiblePSEdition está marcado como compatível Core.

Pode substituir esse comportamento para mostrar todos os módulos usando o parâmetro de opção -SkipEditionCheck. Também adicionamos uma propriedade PSEdition à saída de tabela.

Alias -lp para todos os parâmetros -LiteralPath

Criamos um alias de parâmetro padrão -lp para todos os cmdlets internos do PowerShell que têm um parâmetro -LiteralPath.

Correção de Get-Item -LiteralPath a*b se a*b não existir, a fim de retornar um erro

Antes, se -LiteralPath recebesse um caractere curinga, o trataria da mesma forma que -Path, e se o caractere curinga não encontrasse arquivos, sairia silenciosamente. O comportamento correto deveria ser um -LiteralPath literal, para que se o arquivo não existir, ele cause um erro. A mudança é tratar os curingas usados com -Literal como literal.

Definir o diretório de trabalho para o diretório atual em Start-Job

O cmdlet Start-Job agora usa o diretório atual como o diretório de trabalho para o novo trabalho.

Remoção de -Protocol dos cmdlets *-Computer

Devido a problemas com a comunicação remota do RPC no CoreFX (principalmente em plataformas diferentes do Windows), e para garantir uma experiência de comunicação remota consistente no PowerShell, o parâmetro -Protocol foi removido dos cmdlets \*-Computer. O DCOM não é compatível na comunicação remota. Os seguintes cmdlets só dão suporte à comunicação remota do WSMAN:

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

Remoção de -ComputerName dos cmdlets *-Service

Para incentivar a consistência no uso de PSRP, o parâmetro -ComputerName foi removido dos cmdlets *-Service.

Correção de Get-Content -Delimiter para não incluir o delimitador nas linhas retornadas

Antes, a saída durante o uso de Get-Content -Delimiter era inconsistente e inconveniente, pois exigia mais processamento dos dados para remover o delimitador. Essa alteração remove o delimitador das linhas retornadas.

Alterações para Format-Hex

O parâmetro -Raw agora é "não operacional" (ou seja, não faz nada). Ao prosseguir, toda a saída é exibida com uma representação real de números, o que inclui todos os bytes para o tipo dessa saída. É isso que o parâmetro -Raw fazia antes dessa alteração.

Correção de erro de digitação no nome da propriedade Get-ComputerInfo

BiosSerialNumber foi digitado incorretamente como BiosSeralNumber e foi alterado para a ortografia correta.

Adição dos cmdlets Get-StringHash e Get-FileHash

A mudança é que alguns algoritmos de hash não têm suporte do CoreFX, portanto, não estão mais disponíveis:

  • MACTripleDES
  • RIPEMD160

Adição de validação em cmdlets Get-*, em que passar $null retorna todos os objetos em vez do erro

Agora, passar $null para qualquer uma das seguintes opções gera um erro:

  • 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

Adição de suporte ao Formato de Arquivo de Log Estendido do W3C em Import-Csv

Antes, o cmdlet Import-Csv não podia ser usado para importar diretamente os arquivos de log no formato de log estendido do W3C e uma ação adicional seria necessária. Com essa alteração, há suporte para o formato de log estendido W3C.

Import-Csv aplica PSTypeNames na importação quando há informações de tipo no CSV

Antes, os objetos exportados usando Export-CSV com TypeInformation importado com ConvertFrom-Csv não estavam retendo as informações de tipo. Esta mudança adiciona as informações de tipo ao membro PSTypeNames, se estiverem disponíveis no arquivo CSV.

-NoTypeInformation é o padrão em Export-Csv

Antes, o cmdlet Export-CSV gerava um comentário na primeira linha contendo o nome do tipo do objeto. A alteração exclui as informações de tipo por padrão porque elas não são compreendidas pela maioria das ferramentas de CSV. Essa alteração foi feita para tratar de comentários dos clientes.

Use -IncludeTypeInformation para reter o comportamento anterior.

Permissão para que * seja usado no caminho do registro para Remove-Item

Antes, se -LiteralPath recebesse um caractere curinga, o trataria da mesma forma que -Path, e se o caractere curinga não encontrasse arquivos, sairia silenciosamente. O comportamento correto deveria ser um -LiteralPath literal, para que se o arquivo não existir, ele cause um erro. A mudança é tratar os curingas usados com -Literal como literal.

Agora o Group-Object classifica os grupos

Como parte da melhoria de desempenho, agora Group-Object retorna uma lista classificada dos grupos. Embora você não deva confiar na classificação, essa alteração pode desviá-lo se você quiser o primeiro grupo. Decidimos que essa melhoria de desempenho faz a alteração valer a pena, pois o impacto de depender do comportamento anterior é baixo.

Desvio padrão em Measure-Object

A saída de Measure-Object agora inclui uma propriedade 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 agora tem o parâmetro Password, que usa um SecureString. Assim, você pode usá-lo de forma não interativa:

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

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

Remoção da função more

No passado, o PowerShell enviou uma função no Windows chamada more, que encapsulou more.com. Essa função foi removida.

Além disso, a função help foi alterada para usar more.com no Windows ou o pager padrão do sistema especificado por $env:PAGER em plataformas não Windows.

Agora, cd DriveName: retorna os usuários para o diretório de trabalho atual na unidade

Anteriormente, o uso de Set-Location ou cd para retornar para um PSDrive enviava aos usuários ao local padrão para essa unidade. Os usuários são enviados ao último diretório de trabalho atual conhecido para a sessão.

cd - retorna ao diretório anterior

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

Ou no Linux:

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

Além, cd e cd -- mudam para $HOME.

Update-Help como não administrador

Por demanda popular, Update-Help não precisa mais ser executado como um administrador. Agora, o padrão de Update-Help é salvar a ajuda em uma pasta no escopo do usuário.

Where-Object -Not

Com a adição do parâmetro -Not a Where-Object, é possível filtrar um objeto no pipeline para a não existência de uma propriedade ou um valor da propriedade nulo/vazio.

Por exemplo, esse comando retorna todos os serviços que não têm serviços dependentes definidos:

Get-Service | Where-Object -Not DependentServices

Alterações nos cmdlets da Web

A API do .NET subjacente dos cmdlets Web foi alterada para System.Net.Http.HttpClient. Essa alteração fornece muitos benefícios. No entanto, essa alteração, junto com a falta de interoperabilidade com o Internet Explorer, resultou em várias alterações com falha em Invoke-WebRequest e Invoke-RestMethod.

  • Agora, Invoke-WebRequest dá suporte apenas à Análise de HTML básica. Invoke-WebRequest sempre retorna um objeto BasicHtmlWebResponseObject. As propriedades ParsedHtml e Forms foram removidas.
  • Agora, os valores de BasicHtmlWebResponseObject.Headers são String[], em vez de String.
  • Agora, BasicHtmlWebResponseObject.BaseResponse é um objeto de System.Net.Http.HttpResponseMessage.
  • A propriedade Response nas exceções do cmdlet da Web agora é um objeto System.Net.Http.HttpResponseMessage.
  • Agora, a análise de cabeçalho RFC estrita é padrão para o parâmetro -Headers e -UserAgent. Isso pode ser ignorado com -SkipHeaderValidation.
  • Os esquemas de URI file:// e ftp:// não têm mais suporte.
  • As configurações de System.Net.ServicePointManager não são mais cumpridas.
  • No momento, não há uma autenticação baseada em certificado disponível no macOS.
  • O uso de -Credential sobre uma URI http:// resultará em erro. Use um URI https:// ou forneça o parâmetro -AllowUnencryptedAuthentication para suprimir o erro.
  • Agora, -MaximumRedirection produz um erro de encerramento quando as tentativas de redirecionamento excedem o limite fornecido em vez de retornar os resultados do último redirecionamento.
  • No PowerShell 6.2, foi feita uma alteração no padrão da codificação UTF-8 para respostas JSON. Quando um conjunto de caracteres não é fornecido para uma resposta JSON, a codificação padrão deve ser UTF-8 conforme RFC 8259.
  • Conjunto de codificação padrão para UTF-8 para respostas application-json
  • Adicionado o parâmetro -SkipHeaderValidation para permitir cabeçalhos Content-Type não compatíveis com os padrões
  • Adicionado o parâmetro -Form para dar suporte ao suporte multipart/form-data simplificado
  • Manipulação de chaves de relação em conformidade e sem distinção entre maiúsculas e minúsculas
  • Adicionado o parâmetro -Resume para cmdlets da Web

Invoke-RestMethod não retorna informações úteis quando nenhum dado é retornado

Quando uma API retorna apenas null, Invoke-RestMethod serializava isso como a cadeia de caracteres "null" em vez de $null. Essa alteração corrige a lógica em Invoke-RestMethod para serializar apropriadamente um JSON null literal de valor único como $null.

Os cmdlets da Web avisam quando -Credential é enviado por conexões não criptografadas

Ao usar HTTP, todo conteúdo, incluindo senhas, é enviado como texto não criptografado. Essa alteração serve para não permitir isso por padrão e retornar um erro se as credenciais estiverem sendo passadas de maneira insegura. Os usuários podem ignorar isso usando a opção -AllowUnencryptedAuthentication.

Ela faz o parâmetro -OutFile nos cmdlets da Web funcionar como -LiteralPath

A partir do PowerShell 7.1, o parâmetro OutFile dos cmdlets da Web funciona como LiteralPath e não processa curingas.

Alterações de API

Remoção da classe AddTypeCommandBase

A classe AddTypeCommandBase foi removida de Add-Type para melhorar o desempenho. Essa classe é usada apenas pelo cmdlet Add-Type e não deve afetar os usuários.

VisualBasic removido como linguagem com suporte em Add-Type

No passado, era possível compilar o código do Visual Basic usando o cmdlet Add-Type. O Visual Basic raramente era usado com Add-Type. Removemos esse recurso para reduzir o tamanho do PowerShell.

Remoção do suporte a RunspaceConfiguration

Antes, ao criar um runspace do PowerShell de maneira programática usando a API, era possível usar o RunspaceConfiguration herdado ou as classes InitialSessionState mais recentes. Essa alteração removeu o suporte a RunspaceConfiguration, e só dá suporte a InitialSessionState.

CommandInvocationIntrinsics.InvokeScript associa argumentos a $input em vez de $args

Uma posição incorreta de um parâmetro resultou na passagem de argumentos como entrada, e não como argumentos.

Remoção das propriedades ClrVersion e BuildVersion de $PSVersionTable

A propriedade ClrVersion de $PSVersionTable não é útil com o CoreCLR. Os usuários finais não devem usar esse valor para determinar a compatibilidade.

A propriedade BuildVersion foi vinculada à versão de build do Windows, que não está disponível em plataformas não Windows. Use a propriedade GitCommitId para recuperar a versão de build exata do PowerShell.

Implementação da análise de escape de Unicode

`u#### ou `u{####} é convertido no caractere Unicode correspondente. Para gerar um `u literal, escape o acento grave: ``u.

Problema de associação de parâmetro com ValueFromRemainingArguments nas funções de PS

Agora, ValueFromRemainingArguments retorna os valores como uma matriz em vez de um único valor que é uma matriz.

Usos limpos de CommandTypes.Workflow e WorkflowInfoCleaned

Limpeza do código relacionado aos usos de CommandTypes.Workflow e WorkflowInfo em System.Management.Automation.

Essas pequenas alterações interruptivas afetam principalmente o código do provedor de ajuda.

  • Altere os construtores públicos de WorkflowInfo para internos. Não há mais suporte para fluxo de trabalho, portanto, faz sentido não permitir que as pessoas criem instâncias de Workflow.
  • Remova o tipo System.Management.Automation.DebugSource, pois ele só é usado para depuração de fluxo de trabalho.
  • Remova a sobrecarga de SetParent do depurador de classe abstrata que é usado somente para depuração de fluxo de trabalho.
  • Remova a mesma sobrecarga de SetParent da classe derivada RemotingJobDebugger.

Não-encapsulamento do resultado de retorno em PSObject ao converter ScriptBlock para um delegado

Quando um ScriptBlock é convertido em um tipo delegado a ser usado no contexto de C#, encapsulando o resultado em um PSObject, gera problemas desnecessários:

  • Quando o valor é convertido no tipo de retorno delegado, o PSObject é essencialmente desencapsulado. Portanto, o PSObject é desnecessário.
  • Quando o tipo de retorno delegado é object, é encapsulado em um PSObject, tornando difícil trabalhar com ele em código C#.

Após essa alteração, o objeto retornado será o objeto subjacente.

Suporte à comunicação remota

A PSRP (Comunicação Remota do PowerShell) usando o WinRM em plataformas UNIX requer NTLM/Negotiate ou autenticação básica por HTTPS. A PSRP no macOS só dá suporte à autenticação básica por HTTPS. Não há suporte para a autenticação baseada em Kerberos em plataformas não Windows.

O PowerShell também dá suporte à PSRP (Comunicação Remota do PowerShell) por SSH em todas as plataformas (Windows, macOS e Linux). Para obter mais informações, confira Comunicação remota SSH no PowerShell.

O PowerShell Direct para Contêineres tenta usar primeiro o pwsh

O PowerShell Direct é um recurso do PowerShell e do Hyper-V que permite que você se conecte a uma VM ou Contêiner do Hyper-V sem conectividade de rede ou outros serviços de gerenciamento remoto.

No passado, o PowerShell Direct era conectado usando a instância do Windows PowerShell interna no Contêiner. Agora, o PowerShell Direct primeiro tenta se conectar usando algum pwsh.exe disponível na variável de ambiente PATH. Se pwsh.exe não estiver disponível, o PowerShell Direct voltará a usar powershell.exe.

Enable-PSRemoting já cria pontos de extremidade de comunicação remota separados para versões prévias

Enable-PSRemoting já cria duas configurações de sessão de comunicação remota:

  • Uma para a versão principal do PowerShell. Por exemplo, PowerShell.6. Esse ponto de extremidade que pode ser utilizado em versões secundárias é atualizado como a configuração de sessão do PowerShell 6 "para todo o sistema"
  • Uma configuração de sessão específica da versão, por exemplo: PowerShell.6.1.0

Esse comportamento será útil se você quiser ter várias versões do PowerShell 6 instaladas e acessíveis no mesmo computador.

Além disso, as versões prévias do PowerShell já têm suas próprias configurações de sessão de comunicação remota depois de executar o cmdlet Enable-PSRemoting:

C:\WINDOWS\system32> Enable-PSRemoting

A saída poderá ser diferente se você ainda não tiver configurado o WinRM.

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

Em seguida, pode ver as configurações de sessão separadas do PowerShell para a versão prévia e builds estáveis do PowerShell 6, assim como para cada versão específica.

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

Sintaxe user@host:port com suporte para o SSH

Os clientes do SSH geralmente dão suporte a uma cadeia de conexão no formato user@host:port. Com a adição de SSH como um protocolo de comunicação remota do PowerShell, adicionamos suporte para esse formato de cadeia de conexão:

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

A telemetria só pode ser desabilitada com uma variável de ambiente

O PowerShell envia dados telemétricos básicos à Microsoft quando é iniciado. Os dados incluem o nome do sistema operacional, a versão do sistema operacional e a versão do PowerShell. Com esses dados, podemos entender melhor os ambientes nos quais o PowerShell é usado, além de priorizar novos recursos e correções.

Para recusar essa telemetria, defina a variável de ambiente POWERSHELL_TELEMETRY_OPTOUT para true, yes ou 1. Não damos mais suporte à exclusão do arquivo DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY para desabilitar a telemetria.