Quando você escreve um script do PowerShell sem funções e sem dependências externas de outros scripts, o conceito de escopos do PowerShell não é uma preocupação muito grande. O conceito de variáveis globais do PowerShell não está no centro das atenções. Mas, à medida que você começa a construir funções, módulos e aprende a chamar scripts de outros scripts, o tópico se torna mais importante.
Neste artigo, você vai receber uma lição profunda sobre o que são escopos no PowerShell, como eles funcionam e como você pode escrever código com os escopos em mente. Quando terminar, você vai entender as variáveis globais do PowerShell e muito mais!
Escopos: Mais ou Menos como Baldes
Já escreveu um script onde você define uma variável e, quando verifica o valor dessa variável, é algo diferente? Você pode coçar a cabeça se perguntando como aquela variável mudou quando você a definiu claramente. Uma razão pode ser que o valor da variável está sendo sobrescrito em outro escopo.
Talvez você tenha se perguntado como certas variáveis do PowerShell têm valores quando você as referencia no seu console, mas não existem nos seus scripts. É provável que essas variáveis estejam em outro ‘balde’ que não está disponível naquele momento.
Os escopos são como baldes. Os escopos afetam a maneira como o PowerShell isola variáveis, aliases, funções e PSDrives entre diferentes áreas. Um escopo é como um balde. É um lugar para coletar todos esses itens juntos.
Quando o PowerShell é iniciado, ele cria automaticamente esses “baldes” para você. Nesse ponto, você já está usando escopos sem perceber. Todos os escopos são definidos pelo PowerShell e são criados sem qualquer ajuda da sua parte.
Tipos de Escopo
Ao iniciar o PowerShell, ele cria automaticamente quatro “buckets” ou escopos para vários itens serem colocados. Você não pode criar escopos por conta própria. Você só pode adicionar e remover itens desses escopos definidos abaixo.
Escopo Global
Itens definidos quando o PowerShell é aberto são definidos no escopo global. Esses itens incluem objetos criados pelo sistema, como unidades do PowerShell, e também qualquer coisa que você tenha definido em um perfil do PowerShell desde que seu perfil seja executado na inicialização.
Itens no escopo global estão disponíveis em todos os lugares. Você pode referenciar itens no escopo global de forma interativa no console, em qualquer script que você execute e em qualquer função. As variáveis globais do PowerShell estão em todos os lugares. Por esse motivo, o uso comum de variáveis globais do PowerShell é usar variáveis globais do PowerShell entre scripts.
Há apenas um escopo global que rege tudo.
Escopo de Script
A script scope is automatically created every time a PowerShell script runs. You can have many different script scope instances. Script scopes are created when you execute a PS1 script or a module, for example.
Apenas itens criados nessa instância de escopo de script particular podem se referenciar uns aos outros.
Escopo Privado
Normalmente, um item definido pode ser acessado de outros escopos – não é verdade com itens em um escopo privado. Itens em um escopo privado contêm objetos que são ocultos para outros escopos. Um escopo privado é usado para criar itens com o mesmo nome que itens em outros escopos para evitar sobreposições.
Escopo Local
Ao contrário de outros escopos, o escopo local é um pouco diferente. O escopo local é um ponteiro para o escopo global, de script ou privado. O escopo local é relativo ao contexto em que o código é executado no momento.
Se você criar uma variável, alias, função ou PSDrive sem atribuir explicitamente um escopo (o que abordaremos posteriormente), ela será colocada no escopo local.
Referenciando Escopos
Agora que você tem uma ideia dos quatro tipos de escopos que existem, você também deve saber que existem duas maneiras de referenciar esses escopos.
No PowerShell, existem duas maneiras de referenciar escopos – nomeadas ou numeradas. Ambos os métodos estão referenciando os mesmos escopos, mas de maneira diferente. Estas são duas formas diferentes de interagir com escopos.
Escopos Nomeados
Acima na seção Tipo de Escopo, você aprendeu sobre os escopos referenciados por nome. Referenciar um escopo pelo nome é, intuitivamente, chamado de escopo nomeado. O objetivo principal de referenciar um escopo pelo nome é atribuir um item a um escopo. Você aprenderá como fazer isso abaixo.
Escopos Numerados
Junto com um nome, cada escopo tem um número começando em zero, que será sempre o escopo local. Os escopos são numerados dinamicamente em relação ao escopo local atual.
Por exemplo, assim que você abrir uma sessão do PowerShell, estará operando no escopo global. Neste ponto, o escopo global é o escopo local (lembre-se de que o escopo local é apenas um ponteiro).
Uma vez que o escopo local é sempre o escopo zero, neste ponto, o escopo global também é atualmente o escopo zero. No entanto, ao executar um script a partir da mesma sessão, é criado um escopo de script. Durante a execução, o ponteiro do escopo local é alterado para o escopo do script. Agora, o escopo do script é o escopo zero e o escopo global é o escopo um.
Os escopos são numerados. Esse processo se repete para quantos escopos você tiver, onde o escopo local é 0. Os escopos são numerados dinamicamente pela hierarquia de escopos.
Hierarquia de Escopos e Herança
Como mencionado anteriormente, ao iniciar uma sessão do PowerShell, o PowerShell cria alguns itens para você no escopo global. Esses itens podem ser funções, variáveis, aliases ou PSDrives. Tudo o que você define em sua sessão do PowerShell também será definido no escopo global.
Como você está no escopo global por padrão, se você fizer algo que cria outro escopo, como executar um script ou executar uma função, um escopo filho será criado com o pai sendo o escopo global. Os escopos são como processos com pais e filhos.
Tudo o que é definido em um escopo pai, o escopo global, neste caso, será acessível no escopo filho. Mas esses itens só podem ser editados no escopo em que foram definidos.
Vamos supor que você tenha um script chamado Test.ps1. Dentro deste script, há uma única linha, como mostrado abaixo.
Quando você executa este script, $a
é atribuído um valor no escopo local (enquanto o script está em execução). Quando Test.ps1 é executado, você pode ver abaixo que não é possível fazer referência a ele depois que o script é executado. Como $a
foi atribuído enquanto estava no escopo do script, o escopo global (no console interativo) não pode vê-lo.

Vamos levar este exemplo um passo adiante e fazer com que o script Test.ps1 fique assim. O script agora está tentando exibir o valor de $a
antes de defini-lo no mesmo escopo.
Para demonstrar, atribua um valor a $a
no console interativo. Isso atribui o valor no escopo global. Agora, quando o script é executado, ele herda o escopo pai (global) e deve ser capaz de ver o valor.
Você pode ver abaixo que quando Test.ps1 é executado (criando um escopo filho do escopo global), ele pode ver o valor de $a
. Você também pode ver que o valor da variável está disponível no escopo global também, já que esse escopo é onde foi definido. Isso significa que $a
está disponível tanto nos escopos do script (filho) quanto do pai (global).

Lembre-se deste comportamento de herança de escopo. Fazê-lo ajudará você quando ocorrerem conflitos de variáveis durante a solução de problemas, como variáveis em diferentes escopos com o mesmo nome.
Definindo e Acessando Itens em Escopos
Agora que você sabe o que é um escopo e como eles funcionam, como você os acessa? Vamos ver como usar o PowerShell para definir um escopo de variável (e acessá-los).
Get/Set-Variable
No PowerShell, existem dois cmdlets que permitem definir variáveis chamadas Get-Variable
e Set-Variable
. Esses cmdlets permitem que você recupere o valor de uma variável ou defina um valor.
Ambos os cmdlets são semelhantes, com os parâmetros Name
e Scope
. Usando esses parâmetros, o PowerShell permite definir e recuperar valores de variáveis em todos os escopos.
Escopos Locais
Para definir uma variável em um escopo local, use Set-Variable
e forneça um nome de variável local e um valor como mostrado abaixo.
O escopo local é sempre o padrão, então não usar o parâmetro Scope
sempre definirá a variável no escopo local.
Para recuperar o valor de uma variável de escopo local, use Get-Variable
fornecendo o nome.
Escopos Privados/Script/Global
Você usará os mesmos parâmetros (Name
e Value
) ao trabalhar com variáveis privadas, de script e globais também. A única diferença é que desta vez você usará o parâmetro Scope para definir explicitamente o escopo.
Os métodos para definir uma variável de escopo privado, de script ou global são os mesmos. Basta substituir o valor passado para o parâmetro Scope
como Private
, Script
, Global
.
Para recuperar o valor de um script ou variável de escopo global, use Get-Variable
fornecendo o nome e o escopo.
Nota: Você também pode referenciar escopos usando números de escopo em vez de nomes com os cmdlets
Get
/Set-Variable
.
“Prefixação” de Escopo
Também é possível recuperar e definir variáveis em escopos usando um atalho. Em vez de usar os cmdlets do PowerShell, você irá prefixar o escopo à variável ao referenciá-la.
Escopos Locais
Já que o escopo local é sempre o padrão, simplesmente definir uma variável e referenciá-la irá definir e recuperar uma variável de escopo local.
Escopos Privado/Script/Global
Se desejar definir e referenciar escopos de script ou globais, você pode prefixar as variáveis com o nome do escopo e um ponto e vírgula.
Por exemplo, para definir a variável $a
no escopo global, você pode prefixar com $global:
.
O mesmo pode ser feito para uma variável de escopo de script.
Uma vez que as variáveis estão definidas no escopo preferido, você então as referencia da mesma forma. Também observe que você pode excluir a prefixação do escopo se o escopo definido for o escopo local.
Escopos em Blocos de Script
O PowerShell possui uma construção útil chamada blocos de script. Blocos de script permitem que você mova trechos de código e os execute em praticamente qualquer lugar.
Assim como um script PS1, os blocos de script são executados em seu próprio escopo de script. Quando você executa um bloco de script, essencialmente está executando um script PS1.
Observe no exemplo abaixo onde uma variável é definida no escopo global e depois tentada de ser sobrescrita em um escopo de script. Como você aprendeu acima, isso não funcionará porque um escopo filho não pode fazer referência a um escopo pai.

Este exemplo mostra que quando $a
é alterado no bloco de script, a definição de variável global para $a
não é alterada porque o bloco de script é um escopo de script filho.
Dot Sourcing Scripts (Troca de Escopos Locais)
O PowerShell tem um conceito chamado de dot-sourcing. Este é um método que permite executar um script PS1 e trazer tudo o que seria de escopo de script para o escopo local.
Ao colocar um ponto (.) antes de referenciar um script PS1 e executá-lo, isso “fontes com ponto” o conteúdo do script e traz tudo para o escopo local.
Para demonstrar, eu tenho um script Test.ps1 novamente que define uma variável como mostrado abaixo.
Em um console do PowerShell, defina um valor para uma variável $a
e então faça o dot source deste script como mostrado abaixo. Observe que a variável original foi sobrescrita. O PowerShell “mesclou” os dois escopos locais juntos.

Usando a Propriedade AllScope (Opção)
Você viu como interagir com itens em escopos específicos, mas até agora cada item ainda está definido em um único escopo. Mas e se você não souber em qual escopo uma variável está definida?
Ao definir uma variável com o cmdlet Set-Variable
, você pode colocar a variável em todos os escopos de uma vez. Para fazer isso, use o valor AllScope
para o parâmetro Option
.
Para demonstrar, o script Test.ps1 foi modificado para definir uma variável em todos os escopos. Essa variável é então mostrada como saída conforme abaixo.
Em seguida, você pode ver abaixo que um valor está sendo definido para $a
no escopo global e o script Test.ps1 é executado. No entanto, em vez de não ter efeito, o valor de $a
foi sobrescrito. Não apenas foi definido no escopo do script (Write-Output $a
), mas também sobrescreveu o escopo global.

A opção AllScope
é útil, mas seja cuidadoso. Essa opção essencialmente elimina o conceito de escopos e mescla tudo.
Escopos de Função
Ao executar uma função, todo o código dentro dessa função está em seu próprio escopo filho. Os escopos de função seguem o mesmo comportamento filho/pai que outros escopos.
Ter escopos separados para cada função é uma boa ideia. Isso permite um melhor controle sobre os itens sem precisar se preocupar com conflitos de itens. Também oferece o benefício adicional de limpeza automatizada de variáveis em uma função. Assim que a função for concluída, todos os itens definidos na função serão limpos.
Para demonstrar, copie/cole a função abaixo diretamente no console do PowerShell.
Depois de colado, execute a função. Note que não pode acessar a variável $var
fora da função.
Mantendo Itens Privados (Desativando Herança)
Geralmente, se uma variável é definida em um escopo pai, essa variável será definida no escopo filho. Mas talvez você queira usar um nome de variável, mas esse nome de variável já foi definido em um dos escopos para ser executado em uma sessão. Nesse caso, você pode escolher um nome de variável diferente ou definir a variável em um escopo privado, tornando-a uma variável privada.
A way to use scopes to reduce conflicts is to use the private scope. Using the private scope disables inheritance on that specific variable. When multiple child scopes are created, those child scopes will not see any variables defined in a private scope.
A Test.ps1 script outputs the value of $a as shown below.
Como pode ver abaixo, estou definindo uma variável com escopo privado no escopo global e então executando o script Test.ps1. Geralmente, quando define uma variável em um escopo pai, essa variável estará disponível no escopo filho – não é o caso com uma variável de escopo privado.
No exemplo abaixo, pode ver que o escopo filho do script criado ao executar o script Test.ps1 não pôde ver a variável $a
com escopo privado definida no escopo pai.

Ao contrário dos escopos globais ou da opção AllScope
no cmdlet Set-Variable
, as variáveis com escopo privado são uma excelente maneira de compartimentar itens.
Práticas Recomendadas de Escopo
É comum pensar que definir variáveis no escopo global ou usar a opção AllScope
é a melhor opção. Afinal, todas as variáveis estão disponíveis em qualquer lugar. Não há necessidade de se preocupar com as complicações dos escopos. Embora isso forneça liberdade adicional para acessar o que está definido, pode rapidamente sair do controle e se tornar difícil de solucionar problemas.
Em vez de tentar evitar o uso de escopos, siga estas dicas:
- Em vez de especificar escopos em funções, use parâmetros para passar as informações necessárias para a função.
- Fique dentro do escopo local o máximo possível.
- Em vez de definir variáveis globais a partir de um script, use o cmdlet
Write-Output
para imprimir tudo e salvá-lo em uma variável quando necessário no console.
O ponto principal aqui é abraçar os escopos e aprender a usá-los a seu favor, em vez de tentar contorná-los.