Variáveis de Ambiente do PowerShell: Uma Investigação Profunda

Usar o PowerShell para definir variáveis de ambiente do Windows, ler variáveis de ambiente e criar novas variáveis de ambiente é fácil uma vez que você conheça o truque. Os truques que você aprende neste artigo funcionarão para variáveis de ambiente do Windows 10, bem como para qualquer cliente/servidor do Windows após o Windows 7 SP1/Windows Server 2008.

O PowerShell fornece muitas maneiras diferentes de interagir com as variáveis de ambiente do Windows através do PSDrive $env:, do registro e da classe .NET [System.Environment]. Você aprenderá sobre cada método, incluindo o entendimento do escopo das variáveis de ambiente, neste passo a passo.

Suposições

Ao longo deste artigo, estarei usando o Windows PowerShell 5.1 no Windows 10. Mas se você tiver qualquer versão do Windows PowerShell posterior à v3 no Windows 7 SP1 ou posterior, as técnicas que estou prestes a mostrar devem funcionar muito bem.

O que são Variáveis de Ambiente?

As variáveis de ambiente, como o nome sugere, armazenam informações sobre o ambiente que é usado pelo Windows e pelas aplicações. As variáveis de ambiente podem ser acessadas por aplicativos gráficos como o Windows Explorer e editores de texto simples como o Notepad, assim como pelo cmd.exe e pelo PowerShell.

O uso de variáveis de ambiente ajuda a evitar a codificação rígida de caminhos de arquivos, nomes de usuário ou computador e muito mais em seus scripts ou módulos do PowerShell.

Variáveis de Ambiente Comuns

À medida que você começa a aprender mais sobre como trabalhar com variáveis de ambiente no PowerShell, você encontrará muitas variáveis diferentes. Algumas são mais úteis do que outras. Abaixo está uma lista de algumas das variáveis de ambiente comuns e seu uso para referência.

Variable Usage
ClientName The name of the remote computer connected via a Remote Desktop session.
SessionName This helps to identify if the current Windows session is regarded by the operating system as running at the console. For console sessions SessionName will be ‘Console’. Enhanced Session connections to Hyper-V Virtual Machines do not report SessionName as ‘Console’, whereas Standard Sessions do.
ComputerName The name of the computer.
SystemRoot and Windir The path to the current Windows installation.
ProgramFiles and ProgramFiles(x86) The default locations for x64 and x86 programs.
ProgramW6432 The default location for programs, avoiding 32/64 bit redirection. This variable only applies for 32 bit processes running on a 64 bit platform. This means that you can use it to identify when a 32 bit instance of PowerShell is running on a 64 bit system.
UserDNSDomain The Fully Qualified Domain Name of the Active Directory domain that the current user logged on to. Only present for domain logons.
UserDomain The NETBIOS-style name of the domain that the current user logged on to. Can be a computer name if there’s no domain.
UserDomainRoamingProfile The location of the central copy of the roaming profile for the user, if any. Only present for domain logons.
UserName The name of the currently logged on user.
UserProfile The location of the profile of the current user on the local computer.

Escopos de Variáveis de Ambiente

Há três escopos de variáveis de ambiente. Pense nos escopos como camadas de variáveis que se acumulam para dar uma imagem completa. Combinados, essas “camadas” fornecem muitas variáveis de ambiente diferentes para qualquer processo em execução no Windows.

Hierarquia de Escopo de Variáveis de Ambiente

Cada uma dessas “camadas” combina ou sobrescreve uma à outra. Elas são definidas em uma hierarquia como: máquina -> usuário -> processo, com cada variável de escopo sobregravando a variável pai se uma existir no escopo pai.

Por exemplo, uma variável de ambiente comum é TEMP. Essa variável armazena o caminho da pasta para a pasta temporária local do Windows. Essa variável de ambiente é definida como:

  • C:\WINDOWS\TEMP in the machine scope
  • C:\Users\<username>\AppData\Local\Temp in the user scope
  • C:\Users\<username>\AppData\Local\Temp in the process scope.

Se não houver uma variável de ambiente TEMP definida no escopo usuário, o resultado final será C:\WINDOWS\TEMP.

Tipos de Escopo de Variáveis de Ambiente

Há três escopos diferentes de variáveis de ambiente no Windows.

Máquina

As variáveis de ambiente no escopo máquina estão associadas à instância em execução do Windows. Qualquer conta de usuário pode ler essas variáveis, mas defini-las, alterá-las ou excluí-las precisa ser feito com privilégios elevados.

Usuário

As variáveis de ambiente no escopo usuário estão associadas ao usuário que está executando o processo atual. As variáveis do usuário sobrescrevem as variáveis do escopo máquina que possuem o mesmo nome.

Observação: A Microsoft recomenda que os valores das variáveis de ambiente do escopo Máquina e Usuário não contenham mais de 2048 caracteres.

Processo

As variáveis de ambiente no escopo processo são uma combinação dos escopos máquina e usuário, juntamente com algumas variáveis que o Windows cria dinamicamente.

Abaixo está uma lista de variáveis de ambiente disponíveis para um processo em execução. Todas essas variáveis são criadas dinamicamente.

  • ALLUSERSPROFILE
  • APPDATA
  • COMPUTERNAME
  • HOMEDRIVE
  • HOMEPATH
  • LOCALAPPDATA
  • LOGONSERVER
  • PROMPT
  • PUBLIC
  • SESSION
  • SystemDrive
  • SystemRoot
  • USERDNSDOMAIN
  • USERDOMAIN
  • USERDOMAIN_ROAMINGPROFILE
  • USERNAME
  • USERPROFILE

Variáveis de ambiente no Registro

As variáveis de ambiente são armazenadas em dois locais do registro, um para o escopo do usuário e outro para o escopo da máquina.

Não use o Registro para gerenciar variáveis ​​de ambiente

Há uma ressalva ao fazer alterações em variáveis ​​dentro do registro. Processos em execução não verão alterações nas variáveis ​​do registro. Os processos só veem as variáveis ​​e valores do registro que estavam presentes quando o processo foi iniciado, a menos que o Windows os notifique sobre uma alteração.

Em vez de modificar o registro diretamente, você pode usar uma classe .NET. A classe .NET [System.Environment] pode modificar variáveis ​​de ambiente com escopo de máquina e usuário e lidar com a manutenção do registro para você.

Modificar as variáveis ​​de ambiente no registro diretamente, embora possível, não faz sentido. A classe .NET oferece uma abordagem mais simples, suportada pela Microsoft. Você aprenderá a usar a classe .NET [System.Environment] posteriormente neste artigo.

Locais do Registro de Variáveis ​​de Ambiente e Consulta

I hope you’ve been convinced to not modify the registry directly but if you’d like to take a peek at what’s in there, you can find all user environment variables in the HKEY_CURRENT_USER\Environment key. Machine-scoped environment variables are stored at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.

Dentro de qualquer uma dessas chaves estão valores do registro do tipo REG_SZ ou REG_EXPAND_SZ. Valores REG_EXPAND_SZ contêm variáveis ​​de ambiente incorporadas como parte de seu valor. Essas variáveis ​​de ambiente são expandidas quando o valor é recuperado.

Para demonstrar isso, use a ferramenta REG. Esta é uma pequena ferramenta de linha de comando incluída no Windows.

Consulte a variável de ambiente TEMP conforme mostrado abaixo. Execute o REG com o parâmetro QUERY para recuperar o valor da variável TEMP.

> REG QUERY HKCU\Environment /V TEMP

HKEY_CURRENT_USER\Environment     
    TEMP    REG_EXPAND_SZ    %USERPROFILE%\AppData\Local\Temp

Às vezes, você notará que as variáveis de ambiente são exibidas entre símbolos de porcentagem (%COMPUTERNAME%) como acima. Esta é a maneira antiga de mostrar variáveis de ambiente através do cmd.exe e arquivos em lote. Saiba que o PowerShell não reconhece esse formato.

A ferramenta REG nos permite ver o valor nativo do valor do registro. O tipo de valor é REG_EXPAND_SZ e o valor contém a variável de ambiente %USERPROFILE%.

Se você preferir usar o PowerShell para recuperar o valor do registro, você pode fazer isso usando o cmdlet Get-Item como mostrado abaixo.

PS51> Get-ItemProperty -Path HKCU:\Environment -Name TEMP

TEMP         : C:\Users\<your username>\AppData\Local\Temp
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Environment
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER
PSChildName  : Environment
PSDrive      : HKCU
PSProvider   : Microsoft.PowerShell.Core\Registry

Visualizar e definir variáveis de ambiente do Windows através da GUI

Para ver uma visualização da GUI das variáveis de ambiente do usuário e do sistema, execute SystemPropertiesAdvanced.exe no PowerShell, em um prompt de comando ou pressionando a tecla Windows+R para exibir a guia Propriedades do Sistema Avançadas. Clique no botão EnvironmentVariables, que está destacado na imagem abaixo.

The System Properties dialog, Advanced tab

A caixa de diálogo Variáveis de Ambiente, mostrada abaixo, permite visualizar, criar e modificar variáveis de ambiente com escopo de usuário e máquina. Observe que a caixa de diálogo se refere a variáveis com escopo de máquina como variáveis do sistema.

The Environment Variables dialog

Agora que você entende as variáveis de ambiente, vamos ao que você está aqui para fazer, gerenciá-las com o PowerShell!

Existem várias maneiras diferentes de interagir com variáveis de ambiente usando o PowerShell.

  • O PSDrive e Provedor Env: – baseado em sessão. Apenas define os valores das variáveis de ambiente para a sessão atual do PowerShell
  • As variáveis $env: – baseado em sessão. Apenas define os valores das variáveis de ambiente para a sessão atual do PowerShell
  • A Classe .NET [System.Environment] – permite persistir variáveis de ambiente de escopo do usuário e do sistema em sessões e reinicializações

O PSDrive e Provedor Env:

Uma das melhores maneiras de ler variáveis de ambiente é um conceito PowerShell conhecido como drives PowerShell (PS drives). Um PS drive permite tratar variáveis de ambiente como se fossem um sistema de arquivos através do drive Env:.

Mudando para o Drive Env:

Assim como todos os PS drives, você o referencia através de caminhos como Env:\TEMP, Env:\COMPUTERNAME, etc. Mas para economizar algumas teclas, mude para o drive Env: da mesma forma que você mudaria para qualquer drive de sistema de arquivos, como mostrado abaixo.

PS51> cd Env:
PS51 Env:\>

## ou

PS51> Set-Location Env:
PS Env:\>

Completando com o Tab usando o drive Env:

Você pode usar os mesmos comandos que usaria para acessar um sistema de arquivos, como Get-Item e Get-ChildItem para acessar as variáveis de ambiente. Mas, em vez do sistema de arquivos, você está lendo a unidade Env:.

Como as variáveis de ambiente são armazenadas em uma unidade PS, você pode usar o recurso de conclusão de guias do PowerShell para percorrer as variáveis disponíveis, como mostrado abaixo.

Env: tab completion – finding environment variables starting with the letter C

Agora, vamos ver alguns exemplos de como você pode usar a unidade PS Env: para trabalhar com variáveis de ambiente.

Listando Variáveis de Ambiente com Env:

PS51> Get-Item -Path Env:
PS51> Get-Item -Path Env:USERNAME

Listando Variáveis de Ambiente Usando um Coringa com Env:

PS51> Get-Item -Path Env:user*

Encontrando Valores de Variáveis de Ambiente com Env:

Os resultados desses comandos são objetos .NET [System.Collections.DictionaryEntry] chave/valor. Esses objetos contêm o nome da variável de ambiente na propriedade Name e o valor na propriedade Value.

Você pode acessar um valor específico de uma variável de ambiente envolvendo a referência do comando Get-Item entre parênteses e referenciando a propriedade Value, como mostrado abaixo:

PS51> (Get-Item -Path Env:computername).Value
MYCOMPUTERHOSTNAME

Em situações em que você precisa retornar apenas certas variáveis de ambiente, use cmdlets padrão do PowerShell, como Select-Object e Where-Object para selecionar e filtrar os objetos retornados pelo provedor Env:.

No exemplo abaixo, apenas a variável de ambiente COMPUTERNAME é retornada.

PS51> Get-ChildItem -Path Env: | Where-Object -Property Name -eq 'COMPUTERNAME'

Como método alternativo, use o cmdlet Get-Content. Este cmdlet retorna um objeto [String] contendo o valor da variável de ambiente. Este objeto é mais simples de lidar, pois retorna apenas o valor, em vez de um objeto com as propriedades Name e Value.

PS51> Get-Content -Path Env:\COMPUTERNAME

Demonstração: Inserindo Valores de Ambiente em uma String

Usando o Get-Content, você pode encontrar o valor de uma variável de ambiente e inserir, por exemplo, a variável de ambiente COMPUTERNAME em uma string de texto.

PS51> 'Computer Name is: {0}' -f (Get-Content -Path Env:COMPUTERNAME)
Computer Name is: MYCOMPUTER

Definindo uma Variável de Ambiente (e Criando) com o Env:

Crie novas variáveis de ambiente com o PowerShell usando o cmdlet New-Item. Forneça o nome da variável de ambiente na forma Env:\<NomeVarAmbiente> para o valor de Name e o valor da variável de ambiente para o parâmetro Value, conforme mostrado abaixo.

PS51> New-Item -Path Env:\MYCOMPUTER -Value MY-WIN10-PC
Name                           Value
----                           -----
MYCOMPUTER                     MY-WIN10-PC

Use o cmdlet Set-item para definir uma variável de ambiente ou criar uma nova caso ela ainda não exista. Você pode ver abaixo que, usando o cmdlet Set-Item, você pode tanto criar quanto modificar uma variável de ambiente.

PS51> Set-Item -Path Env:testvariable -Value "Alpha"

Copiando uma variável de ambiente com Env:

Às vezes surge a situação em que você precisa replicar o valor de uma variável de ambiente. Você pode fazer isso usando o cmdlet Copy-Item.

Abaixo você pode ver que o valor da variável COMPUTERNAME é copiado para MYCOMPUTER, substituindo o valor existente.

PS51> Get-Item -Path Env:\MYCOMPUTER

Name                           Value
----                           -----
MYCOMPUTER                     MY-WIN10-PC

PS51> Copy-Item -Path Env:\COMPUTERNAME -Destination Env:\MYCOMPUTER
PS51> Get-Item -Path Env:\MYCOMPUTER

Name                           Value
----                           -----
MYCOMPUTER                     WIN10-1903

Removendo uma variável de ambiente com Env:

Situações podem surgir em que uma variável de ambiente não é mais necessária. Você pode remover variáveis de ambiente usando um dos três métodos:

  • Use o cmdlet Set-Item para definir uma variável de ambiente com um valor vazio.
PS51> Set-Item -Path Env:\MYCOMPUTER -Value ''
PS51> Remove-Item -Path Env:\MYCOMPUTER
  • Use o cmdlet Clear-Item.
PS51> Clear-Item -Path Env:\MYCOMPUTER

Renomeando uma variável de ambiente com Env:

Em situações em que o nome de uma variável de ambiente precisa ser alterado, você tem a opção de renomear, em vez de excluir e recriar com o provedor Env:.

Use o cmdlet Rename-Item para alterar o nome de uma variável de ambiente mantendo o seu valor. Abaixo você pode ver que a variável MYCOMPUTER é renomeada para OLDCOMPUTER mantendo o seu valor.

PS51> Rename-Item -Path Env:\MYCOMPUTER -NewName OLDCOMPUTER
PS51> Get-Item -Path OLDCOMPUTER
Name                           Value
----                           -----
OLDCOMPUTER                    WIN10-1903

$Env: Variáveis

Depois de dominar a unidade Env: para tratar as variáveis de ambiente como arquivos, esta seção mostra como tratá-las como variáveis. Outra maneira de gerenciar as variáveis de ambiente em uma sessão é usando o Analizador de Expressões PowerShell. Essa funcionalidade permite que você use o escopo $Env: para acessar as variáveis de ambiente.

Obtendo uma Variável de Ambiente com $Env:

Usando o escopo $Env, você pode fazer referência às variáveis de ambiente diretamente sem usar um comando como Get-Item como mostrado abaixo.

PS51> $env:computername

Este método facilita a inserção de variáveis de ambiente em strings como mostrado abaixo:

PS51> "The Computer Name is {0}" -f $env:computername
The Computer Name is WIN10-1809
PS51> "The Computer Name is $env:computername"
The Computer Name is WIN10-1809

Definindo ou Criando uma Variável de Ambiente com $Env:

Definir uma variável de ambiente usando este método é simples. Isso também irá criar uma nova variável de ambiente caso ela ainda não exista, como mostrado abaixo.

PS51> $env:testvariable = "Alpha"

Use a sintaxe += para adicionar a um valor existente, em vez de substituí-lo.

PS51> $env:testvariable = "Alpha"
PS51> $env:testvariable += ",Beta"

PS51> $env:testvariable
Alpha,Beta

Removendo uma Variável de Ambiente com $Env:

Para remover uma variável de ambiente usando este método, simplesmente defina o seu valor como uma string vazia.

PS51> $env:testvariable = ''

Usando a classe .NET [System.Environment]

A classe .NET [System.Environment] oferece métodos para obter e definir variáveis de ambiente também. Este é o único método para acessar diretamente vários escopos de ambiente e definir variáveis de ambiente que persistem entre sessões do PowerShell.

Em todos os exemplos a seguir, se nenhum escopo for fornecido, o escopo do processo será assumido.

Ao usar a classe [System.Environment], você usará alguns métodos diferentes de uma classe estática do .NET.. Você não precisa entender o que é um método estático. Você só precisa entender que, para usar qualquer uma das técnicas que você está prestes a aprender, você primeiro precisa fazer referência à classe ([System.Environment]) seguida de dois pontos (::) e, em seguida, pelo método.

Listando Variáveis de Ambiente com [System.Environment]

Se você deseja ver todas as variáveis de ambiente em um escopo específico, você usaria o método GetEnvironmentVariables. Este método retorna todas as variáveis de ambiente pelo escopo especificado como argumento do método (entre parênteses).

Listing environment variables with GetEnvironmentVariable in each scope
PS51> [System.Environment]::GetEnvironmentVariables('User') PS51> [System.Environment]::GetEnvironmentVariables('Machine') PS51> [System.Environment]::GetEnvironmentVariables('Process') # O mesmo que Process PS51> [System.Environment]::GetEnvironmentVariables()

Obtendo Variáveis de Ambiente Únicas com [System.Environment]

Se você precisa encontrar uma variável de ambiente específica, você pode fazer isso de duas maneiras diferentes.

  • GetEnvironmentVariables().<nome da variável> – não recomendado
  • GetEnvironmentVariable('<nome da variável>','<escopo>')

GetEnvironmentVariables()

Usando o método GetEnvironmentVariables(), você usa a notação de ponto para referenciar o valor. Envolva a classe [System.Environment] e a referência ao método estático em parênteses seguidos de um ponto e, em seguida, o nome da variável de ambiente, como abaixo:

PS51> ([System.Environment]::GetEnvironmentVariables()).APPDATA

Observe que, ao referenciar variáveis de ambiente dessa maneira, você deve garantir que a capitalização corresponda! No exemplo acima, tente referenciar a variável APPDATA usando appdata. Use o método GetEnvironmentVariable() em vez disso.

GetEnvironmentVariable()

Em vez de usar o método GetEnvironmentVariables(), use GetEnvironmentVariable() para encontrar uma única variável de ambiente. Isso contorna o problema da capitalização e também permite que você especifique o escopo.

Para usar esse método, especifique o nome da variável de ambiente e o escopo em que deseja procurar essa variável separados por vírgula.

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','User')
# Em branco

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','Machine')
# Em branco

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','Process')  WIN10-1903

# O mesmo que Process
PS51> [System.Environment]::GetEnvironmentVariable('ComputerName')
WIN10-1903

Definindo uma Variável de Ambiente com [System.Environment]

Use o método SetEnvironmentVariable() para definir o valor de uma variável de ambiente para o escopo fornecido, ou crie uma nova se ainda não existir.

Ao definir variáveis no escopo do processo, você descobrirá que o escopo do processo é volátil, enquanto as alterações nos escopos do usuário e da máquina são permanentes.

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha','User')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha','Process')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha','Machine')

 # O mesmo que Processo
PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha')

Observação: Chamar o método SetEnvironmentVariable com um nome de variável ou valor de 32767 caracteres ou mais causará uma exceção.

Removendo uma Variável de Ambiente com [System.Environment]

Use o método SetEnvironmentVariable() para remover uma variável de ambiente para o escopo específico, definindo seu valor como uma string vazia.

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '', 'User')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '', 'Process')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '', 'Machine')

# O mesmo que processo
PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '')

Variáveis de Ambiente Úteis do PowerShell

Assim como muitos outros aplicativos do Windows, o PowerShell possui algumas variáveis de ambiente próprias. Duas variáveis de ambiente úteis para se conhecer são PSExecutionPolicyPreference e PSModulePath.

PSExecutionPolicyPreference

A variável de ambiente PSExecutionPolicyPreference armazena a política de execução atual do PowerShell. Ela é criada se uma política de execução específica da sessão do PowerShell for definida por:

  • Executando o cmdlet Set-ExecutionPolicy com um parâmetro Scope de Process
  • Executando o executável powershell.exe para iniciar uma nova sessão, usando o parâmetro da linha de comando ExecutionPolicy para definir uma política para a sessão.

PSModulePath

A variável de ambiente PSModulePath contém o caminho que o PowerShell procura por módulos se você não especificar um caminho completo. É formado de forma semelhante à variável de ambiente padrão PATH, com caminhos de diretório individuais separados por ponto e vírgula.

PS51> $env:PSModulePath
C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

Dica rápida: Divida cada pasta para obter uma matriz de strings para processar cada caminho individualmente usando $env:PSModulePath.split(‘;’)

Resumo

As variáveis de ambiente são um método útil para obter informações sobre um sistema em execução ou armazenar informações em sessões e reinicializações. Seja apenas lendo as variáveis de ambiente padrão do sistema operacional Windows e criando as suas próprias, agora você pode gerenciá-las de várias maneiras com o PowerShell!

Leitura adicional

Source:
https://adamtheautomator.com/powershell-environment-variables/