Partilhar via


Sobre os escopos

Breve descrição

Explica o conceito de escopo no PowerShell e mostra como definir e alterar o escopo dos elementos.

Descrição longa

O PowerShell protege o acesso a variáveis, aliases, funções e unidades do PowerShell (PSDrives) limitando onde elas podem ser lidas e alteradas. O PowerShell usa regras de escopo para garantir que você não altere inadvertidamente um item que não deve ser alterado.

As regras básicas de âmbito de aplicação são as seguintes:

  • Os escopos podem aninhar. Um escopo externo é chamado de escopo pai. Todos os escopos aninhados são escopos filhos desse pai.

  • Um item é visível no escopo em que foi criado e em qualquer escopo filho, a menos que você o torne explicitamente privado. Você pode colocar variáveis, aliases, funções ou unidades do PowerShell em um ou mais escopos.

  • Um item que você criou dentro de um escopo pode ser alterado somente no escopo no qual foi criado, a menos que você especifique explicitamente um escopo diferente.

Se você criar um item em um escopo e o item compartilhar seu nome com um item em um escopo diferente, o item original poderá estar oculto sob o novo item, mas não será substituído ou alterado.

Escopos do PowerShell

O PowerShell oferece suporte aos seguintes escopos:

  • Global: o escopo que está em vigor quando o PowerShell é iniciado. As variáveis e funções que estão presentes quando o PowerShell é iniciado foram criadas no escopo global, como variáveis automáticas e variáveis de preferência. As variáveis, aliases e funções em seus perfis do PowerShell também são criadas no escopo global.

  • Local: O escopo atual. O escopo local pode ser o escopo global ou qualquer outro escopo.

  • Script: O escopo que é criado enquanto um arquivo de script é executado. Somente os comandos no script são executados no escopo do script. Para os comandos em um script, o escopo do script é o escopo local.

Observação

Privado não é um escopo. É uma opção que altera a visibilidade de um item fora do escopo onde o item está definido.

Escopos pai e filho

Você pode criar um novo escopo executando um script ou função, criando uma sessão ou iniciando uma nova instância do PowerShell. Quando você cria um novo escopo, o resultado é um escopo pai (o escopo original) e um escopo filho (o escopo que você criou).

No PowerShell, todos os escopos são escopos filhos do escopo global, mas você pode criar muitos escopos e muitos escopos recursivos.

A menos que você torne explicitamente os itens privados, os itens no escopo pai estarão disponíveis para o escopo filho. No entanto, os itens criados e alterados no escopo filho não afetam o escopo pai, a menos que você especifique explicitamente o escopo ao criar os itens.

Herança

Um escopo filho não herda as variáveis, aliases e funções do escopo pai. A menos que um item seja privado, o escopo filho pode exibir os itens no escopo pai. Além disso, ele pode alterar os itens especificando explicitamente o escopo pai, mas os itens não fazem parte do escopo filho.

No entanto, um escopo filho é criado com um conjunto de itens. Normalmente, ele inclui todos os aliases que têm a opção AllScope . Esta opção é discutida mais adiante neste artigo. Ele inclui todas as variáveis que têm a opção AllScope , além de algumas variáveis automáticas.

Para localizar os itens em um escopo específico, use o parâmetro Scope de Get-Variable ou Get-Alias.

Por exemplo, para obter todas as variáveis no escopo local, digite:

Get-Variable -Scope local

Para obter todas as variáveis no escopo global, digite:

Get-Variable -Scope global

Modificadores de escopo

Uma variável, alias ou nome de função pode incluir qualquer um dos seguintes modificadores de escopo opcionais:

  • global: - Especifica que o nome existe no escopo Global.

  • local: - Especifica que o nome existe no escopo Local. O escopo atual é sempre o escopo Local .

  • private: - Especifica que o nome é Privado e é visível apenas para o escopo atual.

  • script: - Especifica que o nome existe no escopo de Script. O escopo do script é o escopo do arquivo de script ancestral mais próximo ou Global se não houver um arquivo de script ancestral mais próximo.

  • using: - Usado para acessar variáveis definidas em outro escopo durante a execução de scripts por meio de cmdlets como Start-Job e Invoke-Command.

  • workflow: - Especifica que o nome existe dentro de um fluxo de trabalho. Observação: não há suporte para fluxos de trabalho no PowerShell Core.

  • <variable-namespace> - Um modificador criado por um provedor PSDrive do PowerShell. Por exemplo:

    Espaço de nomes Descrição
    Alias: Aliases definidos no âmbito atual
    Env: Variáveis de ambiente definidas no âmbito atual
    Function: Funções definidas no âmbito atual
    Variable: Variáveis definidas no âmbito atual

O escopo padrão para scripts é o escopo do script. O escopo padrão para funções e aliases é o escopo local, mesmo que eles sejam definidos em um script.

Usando modificadores de escopo

Para especificar o escopo de uma nova variável, alias ou função, use um modificador de escopo.

A sintaxe para um modificador de escopo em uma variável é:

$[<scope-modifier>:]<name> = <value>

A sintaxe para um modificador de escopo em uma função é:

function [<scope-modifier>:]<name> {<function-body>}

O comando a seguir, que não usa um modificador de escopo, cria uma variável no escopo atual ou local :

$a = "one"

Para criar a mesma variável no escopo global , use o modificador de escopo global::

$global:a = "one"

Para criar a mesma variável no script escopo, use o modificador de escopo script::

$script:a = "one"

Você também pode usar um modificador de escopo com funções. A seguinte definição de função cria uma função no escopo global .

function global:Hello {
  Write-Host "Hello, World"
}

Você também pode usar modificadores de escopo para se referir a uma variável em um escopo diferente. O comando a seguir refere-se à variável $test, primeiro no escopo local e depois no escopo global:

$test
$global:test

O modificador de escopo Using:

Usando é um modificador de escopo especial que identifica uma variável local em um comando remoto. Sem um modificador, o PowerShell espera que variáveis em comandos remotos sejam definidas na sessão remota.

O modificador de escopo Usando é introduzido no PowerShell 3.0.

Para mais informações, veja about_Remote_Variables.

A opção AllScope

Variáveis e aliases têm uma propriedade Option que pode ter um valor de AllScope. Os itens que têm a propriedade AllScope tornam-se parte de quaisquer escopos filho que você criar, embora não sejam herdados retroativamente pelos escopos pai.

Um item que tem a propriedade AllScope é visível no escopo filho e faz parte desse escopo. As alterações no item em qualquer escopo afetam todos os escopos nos quais a variável é definida.

Gerenciando o escopo

Vários cmdlets têm um parâmetro Scope que permite obter ou definir (criar e alterar) itens num escopo específico. Use o comando a seguir para localizar todos os cmdlets em sua sessão que tenham um parâmetro Scope:

Get-Help * -Parameter scope

Para localizar as variáveis visíveis em um escopo específico, use o parâmetro Scope de Get-Variable. As variáveis visíveis incluem variáveis globais, variáveis no escopo pai e variáveis no escopo atual.

Por exemplo, o comando a seguir obtém as variáveis visíveis no escopo local:

Get-Variable -Scope local

Para criar uma variável em um escopo específico, use um modificador de escopo ou o parâmetro Scope de Set-Variable. O comando a seguir cria uma variável no escopo global:

New-Variable -Scope global -Name a -Value "One"

Você também pode usar o parâmetro Scope dos cmdlets New-Alias, Set-Aliasou Get-Alias para especificar o escopo. O comando a seguir cria um alias no escopo global:

New-Alias -Scope global -Name np -Value Notepad.exe

Para obter as funções num escopo específico, use o cmdlet Get-Item quando se encontrar nesse escopo. O Get-Item cmdlet não tem um parâmetro Scope .

Observação

Para os cmdlets que usam o parâmetro Scope, você também pode fazer referência aos escopos por número. O número descreve a posição relativa de um escopo em relação a outro. O escopo 0 representa o escopo atual ou local. O escopo 1 indica o escopo pai imediato. O escopo 2 indica o pai do escopo pai e assim por diante. Os escopos numerados são úteis se você tiver criado muitos escopos recursivos.

Usando a notação de origem de ponto com escopo

Scripts e funções seguem todas as regras de escopo. Você os cria em um escopo específico e eles afetam apenas esse escopo, a menos que você use um parâmetro de cmdlet ou um modificador de escopo para alterar esse escopo.

Mas, você pode adicionar um script ou função ao escopo atual usando a notação de origem de ponto. Em seguida, quando um script é executado no escopo atual, todas as funções, aliases e variáveis que o script cria estão disponíveis no escopo atual.

Para adicionar uma função ao escopo atual, digite um ponto (.) e um espaço antes do caminho e do nome da função na chamada de função.

Por exemplo, para executar o script Sample.ps1 a partir do diretório C:\Scripts no escopo do script (o padrão para scripts), use o seguinte comando:

c:\scripts\sample.ps1

Para executar o script Sample.ps1 no escopo local, use o seguinte comando:

. c:\scripts.sample.ps1

Quando você usa o operador de chamada (&) para executar uma função ou script, ele não é adicionado ao escopo atual. O exemplo a seguir usa o operador de chamada:

& c:\scripts.sample.ps1

Pode ler mais sobre o operador de chamadas em about_operators.

Quaisquer aliases, funções ou variáveis que o script Sample.ps1 cria não estão disponíveis no escopo atual.

Restrição sem âmbito de aplicação

Alguns conceitos do PowerShell são semelhantes ao escopo ou interagem com o escopo. Esses conceitos podem ser confundidos com o escopo ou o comportamento do escopo.

Sessões, módulos e prompts aninhados são ambientes autônomos, mas não são escopos filhos do escopo global na sessão.

Sessões

Uma sessão é um ambiente no qual o PowerShell é executado. Quando você cria uma sessão em um computador remoto, o PowerShell estabelece uma conexão persistente com o computador remoto. A conexão persistente permite que você use a sessão para vários comandos relacionados.

Como uma sessão é um ambiente contido, ela tem seu próprio escopo, mas uma sessão não é um escopo filho da sessão na qual foi criada. A sessão começa com o seu próprio âmbito global. Este âmbito é independente do âmbito global da sessão. Você pode criar escopos-filho na sessão. Por exemplo, você pode executar um script para criar um escopo filho em uma sessão.

Módulos

Você pode usar um módulo do PowerShell para compartilhar e entregar ferramentas do PowerShell. Um módulo é uma unidade que pode conter cmdlets, scripts, funções, variáveis, aliases e outros itens úteis. A menos que explicitamente definido, os itens em um módulo não são acessíveis fora do módulo. Portanto, você pode adicionar o módulo à sua sessão e usar os itens públicos sem se preocupar que os outros itens possam substituir os cmdlets, scripts, funções e outros itens em sua sessão.

A privacidade de um módulo se comporta como um escopo, mas adicionar um módulo a uma sessão não altera o escopo. Além disso, o módulo não tem seu próprio escopo, embora os scripts no módulo, como todos os scripts do PowerShell, tenham seu próprio escopo.

Por padrão, os módulos são carregados no nível superior do estado da sessão atual e não no escopo atual. Pode ser um estado de sessão de módulo ou o estado de sessão global. Se você estiver no escopo global, os módulos serão carregados no estado da sessão global. Todas as exportações são colocadas nas tabelas globais. Se você carregar module2 de dentro do module1, module2 será carregado no estado de sessão do module1, não no estado global da sessão. Todas as exportações do module2 são colocadas na parte superior do estado da sessão do module1. Se você usar Import-Module -Scope local, as exportações serão colocadas no objeto de escopo atual em vez de no nível superior. Se você estiver em um módulo e usar Import-Module -Scope global (ou Import-Module -Global) para carregar outro módulo, esse módulo e suas exportações serão carregados no estado da sessão global em vez do estado da sessão local do módulo. Este recurso foi projetado para escrever módulos que manipulam módulos. O módulo WindowsCompatibility faz isso para importar módulos proxy para o escopo global.

Prompts aninhados

Da mesma forma, os prompts aninhados não têm seu próprio escopo. Quando você insere um prompt aninhado, o prompt aninhado é um subconjunto do ambiente. Mas, você permanece dentro do escopo local.

Os scripts têm seu próprio escopo. Se estiveres a depurar um script e chegares a um ponto de interrupção no script, entras no escopo do script.

Opção privada

Aliases e variáveis têm uma propriedade Option que pode ter um valor de Private. Os itens que têm a opção Privada podem ser visualizados e alterados no âmbito em que são criados, mas não podem ser visualizados ou alterados fora desse âmbito.

Por exemplo, se você criar uma variável que tenha uma opção privada no escopo global e, em seguida, executar um script, Get-Variable os comandos no script não exibirão a variável private. O uso do modificador de escopo global nesta instância não exibe a variável private.

Você pode usar o parâmetro Option dos New-Variablecmdlets , Set-Variable, New-Aliase para Set-Alias definir o valor da propriedade Option como Private.

Visibilidade

A propriedade Visibility de uma variável ou alias determina se você pode ver o item fora do contêiner, no qual ele foi criado. Um contêiner pode ser um módulo, script ou snap-in. A visibilidade é projetada para contêineres da mesma forma que o valor Private da propriedade Option é projetado para escopos.

A propriedade Visibility assume os valores Público e Privado . Os itens que têm visibilidade privada podem ser visualizados e alterados apenas no contêiner no qual foram criados. Se o contêiner for adicionado ou importado, os itens que têm visibilidade privada não poderão ser exibidos ou alterados.

Como a visibilidade é projetada para contentores, funciona de maneira diferente num âmbito.

  • Se você criar um item que tenha visibilidade privada no escopo global, não poderá exibir ou alterar o item em nenhum escopo.
  • Se você tentar exibir ou alterar o valor de uma variável que tenha visibilidade privada, o PowerShell retornará uma mensagem de erro.

Você pode usar os cmdlets New-Variable e Set-Variable para criar uma variável que tenha visibilidade privada.

Exemplos

Exemplo 1: Alterar um valor de variável somente em um script

O comando a seguir altera o valor da variável $ConfirmPreference em um script. A alteração não afeta o âmbito global.

Primeiro, para exibir o valor da variável $ConfirmPreference no escopo local, use o seguinte comando:

PS>  $ConfirmPreference
High

Crie um script Scope.ps1 que contenha os seguintes comandos:

$ConfirmPreference = "Low"
"The value of `$ConfirmPreference is $ConfirmPreference."

Executa o script. O script altera o valor da variável $ConfirmPreference e, em seguida, relata seu valor no escopo do script. A saída deve ser semelhante à seguinte saída:

The value of $ConfirmPreference is Low.

Em seguida, teste o valor atual da variável $ConfirmPreference no escopo atual.

PS>  $ConfirmPreference
High

Este exemplo mostra que as alterações no valor de uma variável no escopo do script não afetam o valor da variável no escopo pai.

Exemplo 2: Exibir um valor de variável em escopos diferentes

Você pode usar modificadores de escopo para exibir o valor de uma variável no escopo local e em um escopo pai.

Primeiro, defina uma variável $test no âmbito global.

$test = "Global"

Em seguida, crie um script Sample.ps1 que defina a variável $test. No script, use um modificador de escopo para se referir às versões global ou local da variável $test.

Em Sample.ps1:

$test = "Local"
"The local value of `$test is $test."
"The global value of `$test is $global:test."

Quando você executa Sample.ps1, a saída deve ser semelhante à seguinte saída:

The local value of $test is Local.
The global value of $test is Global.

Quando o script estiver concluído, somente o valor global de $test será definido na sessão.

PS>  $test
Global

Exemplo 3: Alterar o valor de uma variável em um escopo pai

A menos que você proteja um item usando a opção Private ou outro método, você pode exibir e alterar o valor de uma variável em um escopo pai.

Primeiro, defina uma variável $test no âmbito global.

$test = "Global"

Em seguida, crie um script Sample.ps1 que defina a variável $test. No script, use um modificador de escopo para se referir às versões global ou local da variável $test.

Em Sample.ps1:

$global:test = "Local"
"The global value of `$test is $global:test."

Quando o script estiver concluído, o valor global de $test será alterado.

PS>  $test
Local

Exemplo 4: Criando uma variável privada

Uma variável private é uma variável que tem uma propriedade Option que tem um valor de Private. As variáveis privadas são herdadas pelo escopo filho, mas só podem ser visualizadas ou alteradas no escopo em que foram criadas.

O comando a seguir cria uma variável privada chamada $ptest no escopo local.

New-Variable -Name ptest -Value 1 -Option private

Você pode exibir e alterar o valor de $ptest no escopo local.

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

Em seguida, crie um script Sample.ps1 que contenha os seguintes comandos. O comando tenta exibir e alterar o valor de $ptest.

Em Sample.ps1:

"The value of `$Ptest is $Ptest."
"The value of `$Ptest is $global:Ptest."

A $ptest variável não é visível no escopo do script, a saída está vazia.

"The value of $Ptest is ."
"The value of $Ptest is ."

Exemplo 5: Usando uma variável local em um comando remoto

Para variáveis em um comando remoto criado na sessão local, use o modificador de escopo Using. O PowerShell pressupõe que as variáveis nos comandos remotos foram criadas na sessão remota.

A sintaxe é:

$Using:<VariableName>

Por exemplo, os comandos a seguir criam uma variável $Cred na sessão local e, em seguida, usam a variável $Cred em um comando remoto:

$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}

O escopo Usando foi introduzido no PowerShell 3.0. No PowerShell 2.0, para indicar que uma variável foi criada na sessão local, use o seguinte formato de comando.

$Cred = Get-Credential
Invoke-Command $s {
  param($c)
  Remove-Item .\Test*.ps1 -Credential $c
} -ArgumentList $Cred

Ver também

sobre_Variáveis

sobre_Variáveis_de_Ambiente

about_Functions

sobre_Blocos_de_Script