Переменные среды PowerShell: Глубокое погружение

Использование PowerShell для установки переменных среды Windows, чтения переменных среды и создания новых переменных среды легко, как только вы узнаете хитрость. Хитрости, которые вы узнаете в этой статье, будут работать для переменных среды Windows 10, а также для любого клиента/сервера Windows после Windows 7 SP1/Windows Server 2008.

PowerShell предоставляет множество различных способов взаимодействия с переменными среды Windows из PSDrive $env:, реестра и класса .NET [System.Environment]. Вы узнаете о каждом методе, включая понимание области переменных среды, в этом пошаговом руководстве.

Предположения

На протяжении этой статьи я буду использовать Windows PowerShell 5.1 на Windows 10. Но если у вас есть любая версия Windows PowerShell после v3 на Windows 7 SP1 или более поздняя, то методы, которые я собираюсь показать вам, должны работать нормально.

Что такое переменные среды?

Переменные среды, как следует из их названия, хранят информацию о среде, которая используется Windows и приложениями. Переменные среды могут быть доступны графическим приложениям, таким как Проводник Windows, и простым текстовым редакторам, таким как Блокнот, а также cmd.exe и PowerShell.

Использование переменных среды помогает вам избежать жесткого закодирования путей к файлам, имен пользователей или компьютеров и многого другого в ваших сценариях PowerShell или модулях.

Общие переменные среды

Когда вы начнете углубляться в изучение работы с переменными среды в PowerShell, вы столкнетесь с множеством различных переменных. Некоторые из них более полезны, чем другие. Вот список некоторых общих переменных среды и их использование для справки.

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.

Области переменных среды

Существует три области переменных среды. Представьте себе области как слои переменных, которые накапливаются, чтобы дать полную картину. Вместе эти “слои” предоставляют множество различных переменных среды для любого запущенного процесса в Windows.

Структура областей переменных среды

Каждый из этих “слоев” либо объединяет, либо перезаписывает друг друга. Они определены в иерархии, например: машина –> пользователь –> процесс, при этом каждая область переменной перезаписывает переменную родительской области, если она существует в родительской области.

Например, общей переменной среды является TEMP. Эта переменная хранит путь к локальной временной папке Windows. Эта переменная среды установлена как:

  • 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.

Если переменная среды TEMP не установлена в области пользователя, то результат будет C:\WINDOWS\TEMP.

Типы областей переменных среды

Существует три различные области переменных среды в Windows.

Машина

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

Пользователь

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

Примечание: Microsoft рекомендует, чтобы значения переменных среды области машины и пользователя не превышали 2048 символов.

Процесс

Переменные среды в области процесса представляют собой комбинацию переменных из области машины и пользователя, а также некоторых переменных, которые Windows создает динамически.

Ниже приведен список переменных среды, доступных для выполняемого процесса. Все эти переменные создаются динамически.

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

Переменные среды в реестре

Переменные среды хранятся в двух местах реестра, одно для области пользователя и одно для области машины.

Не используйте реестр для управления переменными среды

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

Вместо прямого изменения реестра, вы можете использовать класс .NET. Класс .NET [System.Environment] может изменять переменные среды машины и пользователя и управлять обслуживанием реестра за вас.

Изменение переменных среды в реестре напрямую, хотя и возможно, не имеет смысла. Класс .NET предлагает более простой подход, поддерживаемый Microsoft. Вы узнаете о использовании класса .NET [System.Environment] позже в этой статье.

Расположение переменных среды в реестре и запросы

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.

Внутри любого из этих ключей находятся значения реестра типа REG_SZ или REG_EXPAND_SZ. Значения типа REG_EXPAND_SZ содержат встроенные переменные среды в качестве части их значения. Эти переменные среды расширяются при получении значения.

Для демонстрации этого используйте утилиту REG. Это небольшая командная утилита, включенная в Windows.

Запросите переменную среды TEMP, как показано ниже. Запустите REG с параметром QUERY, чтобы получить значение переменной TEMP.

> REG QUERY HKCU\Environment /V TEMP

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

Иногда вы замечаете переменные среды, окруженные знаками процента (%COMPUTERNAME%), как показано выше. Это старомодный способ отображения переменных среды через cmd.exe и файлы пакетных команд. Знайте, что PowerShell не распознает этот формат.

Утилита REG позволяет нам видеть первоначальное значение значения реестра. Тип значения – REG_EXPAND_SZ, а значение содержит переменную среды %USERPROFILE%.

Если вы предпочитаете использовать PowerShell для извлечения значения реестра, вы можете это сделать, используя командлет Get-Item, как показано ниже.

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

Просмотр и установка переменных среды Windows через графический интерфейс

Чтобы увидеть графический вид пользовательских и системных переменных среды, запустите SystemPropertiesAdvanced.exe из PowerShell, командной строки или нажмите клавиши Windows+R, чтобы отобразить вкладку Расширенные параметры системы. Нажмите кнопку Переменные среды, которая выделена на изображении ниже.

The System Properties dialog, Advanced tab

Диалоговое окно переменных среды, показанное ниже, позволяет вам просматривать, создавать и изменять переменные среды пользователя и машины. Обратите внимание, что в диалоговом окне переменных среды переменные, охватывающие машину, называются Системные переменные.

The Environment Variables dialog

Теперь, когда у вас есть понимание переменных среды, давайте перейдем к тому, зачем вы здесь, управлению ими с помощью PowerShell!

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

  • Драйв и провайдер Env: – ориентированные на сеанс. Устанавливают значения переменных окружения только для текущего сеанса PowerShell
  • $env: переменные – ориентированные на сеанс. Устанавливают значения переменных окружения только для текущего сеанса PowerShell
  • Класс .NET [System.Environment] – позволяет сохранять переменные окружения, ориентированные на пользователя и систему, между сеансами и перезагрузками

Драйв и провайдер Env:

Один из лучших способов считывать переменные окружения – это концепция PowerShell, известная как драйвы PowerShell (PS drives). Драйв PowerShell позволяет обращаться к переменным окружения, как если бы они были файловой системой через драйв Env:

Переключение на драйв Env:

Как и все драйвы PowerShell, вы обращаетесь к нему через пути, например, Env:\TEMP, Env:\COMPUTERNAME и так далее. Но чтобы сэкономить немного нажатий клавиш, переключитесь на драйв Env: так же, как вы бы сделали с любым драйвом файловой системы, как показано ниже.

PS51> cd Env:
PS51 Env:\>

## или

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

Автозавершение с драйвом Env:

Вы можете использовать те же команды, которые используются для доступа к файловой системе, такие как Get-Item и Get-ChildItem, чтобы получить доступ к переменным среды. Но вместо файловой системы вы читаете диск Env:.

Поскольку переменные среды хранятся в диске PS, вы можете использовать функцию автозаполнения табуляции в PowerShell для перебора доступных переменных, как показано ниже.

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

Теперь давайте рассмотрим несколько примеров того, как можно использовать диск Env: для работы с переменными среды.

Перечисление переменных среды с помощью Env:

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

Перечисление переменных среды с использованием шаблона с помощью Env:

PS51> Get-Item -Path Env:user*

Поиск значений переменных среды с помощью Env:

Результаты этих команд представляют собой объекты .NET типа ключ/значение [System.Collections.DictionaryEntry]. Эти объекты содержат имя переменной среды в свойстве Name и значение в свойстве Value.

Вы можете получить доступ к определенному значению переменной среды, обернув ссылку на команду Get-Item в скобки и обращаясь к свойству Value, как показано ниже:

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

В ситуациях, когда вам нужно вернуть только определенные переменные среды, используйте стандартные средства управления PowerShell, такие как Select-Object и Where-Object, чтобы выбирать и фильтровать объекты, возвращаемые провайдером Env:.

В приведенном ниже примере возвращается только переменная среды COMPUTERNAME.

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

В качестве альтернативного метода используйте командлет Get-Content. Этот командлет возвращает объект [String], содержащий значение переменной среды. Этот объект проще обрабатывать, поскольку он возвращает только значение, а не объект с свойствами Name и Value.

PS51> Get-Content -Path Env:\COMPUTERNAME

Демонстрация: Вставка значений среды в строку

С использованием Get-Content вы можете найти значение переменной среды и вставить, например, переменную среды COMPUTERNAME в текстовую строку.

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

Установка переменной среды (и создание) с помощью Env:

Создавайте новые переменные среды с помощью PowerShell, используя командлет New-Item. Укажите имя переменной среды в форме Env:\<EnvVarName> для значения Name и значение переменной среды для параметра Value, как показано ниже.

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

Используйте cmdlet Set-item для установки переменной среды или создайте новую, если её еще не существует. Ниже вы можете увидеть, что с помощью cmdlet Set-Item можно как создать, так и изменить переменную среды.

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

Копирование переменной среды с помощью Env:

Иногда возникает ситуация, когда необходимо продублировать значение переменной среды. Вы можете сделать это, используя cmdlet Copy-Item.

Ниже вы можете видеть, что значение переменной COMPUTERNAME копируется в MYCOMPUTER, перезаписывая его существующее значение.

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

Удаление переменной среды с помощью Env:

Возникают ситуации, когда переменная среды больше не нужна. Вы можете удалить переменные среды, используя один из трех методов:

  • Используйте cmdlet Set-Item для установки переменной среды пустым значением
PS51> Set-Item -Path Env:\MYCOMPUTER -Value ''
PS51> Remove-Item -Path Env:\MYCOMPUTER
  • Используйте cmdlet Clear-Item.
PS51> Clear-Item -Path Env:\MYCOMPUTER

Переименование переменной среды с помощью Env:

В ситуациях, когда требуется изменить имя переменной среды, у вас есть возможность переименовать её, а не удалять и создавать заново с помощью провайдера Env:.

Используйте командлет Rename-Item, чтобы изменить имя переменной среды, сохраняя ее значение. Ниже вы можете видеть, что переменная MYCOMPUTER переименована в OLDCOMPUTER, сохраняя ее значение.

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

$Env: Переменные

Овладев Env: диском для обращения к переменным среды как к файлам, эта секция показывает вам, как обращаться к ним как к переменным. Еще один способ управления переменными среды в сессии – использовать анализатор выражений PowerShell. Эта функция позволяет использовать область $Env: для доступа к переменным среды.

Получение переменной среды с помощью $Env:

Используя область $Env, вы можете ссылаться на переменные среды напрямую, не используя команду Get-Item, как показано ниже.

PS51> $env:computername

Этот метод упрощает вставку переменных среды в строки, как показано ниже:

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

Установка или создание переменной среды с помощью $Env:

Установка переменной среды с использованием этого метода проста. Это также создаст новую переменную среды, если она еще не существует, как показано ниже.

PS51> $env:testvariable = "Alpha"

Используйте синтаксис +=, чтобы добавить к существующему значению, а не перезаписать его.

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

PS51> $env:testvariable
Alpha,Beta

Удаление переменной среды с помощью $Env:

Чтобы удалить переменную среды с помощью этого метода, просто установите ее значение как пустую строку.

PS51> $env:testvariable = ''

Используя класс .NET [System.Environment]

, класс .NET [System.Environment] предоставляет методы для получения и установки переменных среды. Это единственный метод для прямого доступа к различным областям среды и установки переменных среды, которые сохраняются между сеансами PowerShell.

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

При использовании класса [System.Environment] вы будете использовать несколько различных методов .NET static class. Вам не нужно понимать, что такое статический метод. Вам просто нужно знать, что для использования любой из техник, которые вы собираетесь узнать, сначала вам нужно ссылаться на класс ([System.Environment]), за которым следуют два двоеточия (::), а затем сам метод.

Вывод переменных среды с использованием [System.Environment]

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

Listing environment variables with GetEnvironmentVariable in each scope
PS51> [System.Environment]::GetEnvironmentVariables('User') PS51> [System.Environment]::GetEnvironmentVariables('Machine') PS51> [System.Environment]::GetEnvironmentVariables('Process') # То же, что и процесс PS51> [System.Environment]::GetEnvironmentVariables()

Получение отдельных переменных среды с использованием [System.Environment]

Если вам нужно найти конкретную переменную среды, вы можете сделать это двумя способами.

  • GetEnvironmentVariables().<имя переменной> – не рекомендуется
  • GetEnvironmentVariable('<var name>','<scope>')

GetEnvironmentVariables()

Используя метод GetEnvironmentVariables(), вы используете точечную нотацию для ссылки на значение. Оберните ссылку на класс и статический метод [System.Environment] в круглые скобки, за которыми следует точка, а затем имя переменной среды, как показано ниже:

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

Обратите внимание, что при ссылке на переменные среды таким образом вы должны обеспечить совпадение регистра! В приведенном выше примере попробуйте ссылаться на переменную APPDATA, используя appdata. Вместо этого используйте метод GetEnvironmentVariable().

GetEnvironmentVariable()

Вместо использования метода GetEnvironmentVariables() используйте метод GetEnvironmentVariable() для поиска одиночных переменных среды. Это обходит проблему с регистром и также позволяет указать область видимости.

Чтобы использовать этот метод, укажите имя переменной среды и область, в которой вы хотели бы найти эту переменную, разделенные запятой.

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','User')
# Пусто

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','Machine')
# Пусто

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

# То же, что и Процесс
PS51> [System.Environment]::GetEnvironmentVariable('ComputerName')
WIN10-1903

Установка переменной среды с помощью [System.Environment]

Используйте метод SetEnvironmentVariable(), чтобы установить значение переменной среды для заданной области или создать новую, если она еще не существует.

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

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

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

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

 # То же, что и в процессе
PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha')

Примечание: Вызов метода SetEnvironmentVariable с именем переменной или значением от 32767 символов и более вызовет исключение.

Удаление переменной среды с помощью [System.Environment]

Используйте метод SetEnvironmentVariable() для удаления переменной среды для заданной области, установив ее значение в пустую строку.

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

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

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

# То же, что и в процессе
PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '')

Полезные переменные среды PowerShell

Как и многие другие приложения Windows, в PowerShell есть свои собственные переменные среды. Две полезные переменные среды, о которых стоит знать, это PSExecutionPolicyPreference и PSModulePath.

PSExecutionPolicyPreference

Переменная среды PSExecutionPolicyPreference хранит текущую политику выполнения PowerShell. Она создается, если установлена сеансо-специфическая политика выполнения PowerShell:

  • Запуск cmdlet Set-ExecutionPolicy с параметром Scope равным Process
  • Запуск исполняемого файла powershell.exe для запуска нового сеанса, используя параметр командной строки ExecutionPolicy для установки политики для сеанса.

PSModulePath

Переменная среды PSModulePath содержит путь, по которому PowerShell ищет модули, если вы не указываете полный путь. Она формируется примерно так же, как стандартная переменная среды PATH, с отдельными путями каталогов, разделенными точкой с запятой.

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

Быстрый совет: Разделите каждую папку, чтобы получить строковый массив и обработать каждый путь отдельно, используя $env:PSModulePath.split(‘;’)

Сводка

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

Дополнительная информация

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