Powershell системные переменные windows

Работа с переменными окружения в Powershell Env

09 августа 2019

При работе с переменными окружения в Powershell есть ряд проблем, с которыми мы можем столкнуться. Если мы выполним следующую команду, то увидим, что у нас есть диск и именем Env, который и хранит переменные:

Мы можем в него перейти и увидеть все переменные окружения:

Если мы попробуем изменить переменные следующим способом, то они будут работать только в рамках PS и до окончания сеанса (перезагрузки например):

Способ выше аналогичен этому:

Если нам нужно сделать переменную среды постоянной есть решение для компьютера и конкретного пользователя.

Изменение переменных окружения пользователя в Powershell

У нас есть ветка реестра, которая отвечает за область пользователя:

В деталях мы уже рассматривали как работать в powershell с реестром и не будем разбирать в деталях. Способом ниже мы обратимся к Path и добавим значение «C:\Git\»:

Обращайте внимание, что у вас стоит ; перед новым значением (если вы изменяете Path), и что вы сохраняете предыдущее значение путем сложения.

Получение списка USB устройств в Powershell

Изменение переменных Env компьютера в Powershell

У нас есть другая ветка реестра, которая хранит значения переменных компьютера:

Изменяются они так же, как и в случае с пользователем:

Создание новых переменных Environment в Powershell

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

Переменные в Powershell и работа с типами данных — объявление и вывод

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

Навигация по посту

Создание

Переменная — это ссылка на значение, которое хранится в памяти. Каждая переменная в Powershell начинается со знака доллара «$» и может хранить числа, буквы и нижние подчеркивания. Присваивание значений осуществляется через знак равно «=». На примере ниже мы создали переменную variable со значением 8:

Что бы вывести переменную в консоли ее нужно повторно написать:

Мы можем проводить арифметические операции с разными переменными:

Такие операции можно проводить и со строками. На примере ниже мы выполняем сложение:

Если выполнять сложение числа и строки, то число автоматически преобразуется в строку:

Такое поведение одинаково не во всех языках и таких ситуаций лучше избегать.

Перезаписать значение переменной можно так:

Переменные живут в рамках текущего сеанса. Если вы работаете через консоль — после ее закрытия они удаляться, если это работающий скрипт — до закрытия программы. Исключения только с системными переменными и импортируемыми модулями. Одна из таких переменных, которая создается каждый сеанс $PSVersionTable, хранящая версию Powershell и ее не получится изменить или создать заново.

Типы данных

Кроме строк и чисел в Powershell существуют и другие типы. Самые популярные из них:

  • [string] — строка:
  • [char] — код символа ASCII
  • [bool] — булево значение «True»,»False»;
  • [int] — число длинною в 32 бита;
  • [long] — число длинною в 64 бита;
  • [decimal] — число с плавающей точкой диною в 128 бит и d на конце;
  • [double] — 8 битовое число с плавающей точкой;
  • [single] — 32 битовое число с плавающей точкой;
  • [DateTime] — тип данных Powershell хранящий дату и время;
  • [array] — массив;
  • [hashtable] — хэш таблица;
  • [pscustomonject] — массив типа ключ и значение.
Читайте также:  Windows serviceprofiles localservice appdata local temp что это

В большинстве случаев нет необходимости объявлять тип переменной, так как Powershell определяет это сам. В некоторых языках объявление типов переменных ускоряет работу программ.

Если вы сомневаетесь в типе переменной можно использовать GetType():

Назначать типы можно как значению, так и самой переменной:

Если мы попробуем преобразовать строку в число указывая ее тип, то получим ошибку так как невозможно сделать из букв числа:

Есть некоторые типы, которые объявлять обязательно, так как Powershell может конвертировать в другой формат. Один из таких примеров PSCustomObject. Если мы не объявим этот тип, то получим hashtable:

Про работу с такими типами вы можете почитать в предыдущих статьях, например работа с хеш таблицами в Powershell Hashtable.

Дату так же можно объявлять несколькими путями. Это можно делать через команду и объявляя тип (используя свой стандарт времени):

Кавычки и форматирование строк

Вы можете использовать одинарные и двойные кавычки. Основное различие в том, что двойные кавычки позволяют передавать переменные внутри строки:

Конечно можно передавать данные используя параметр форматирования:

Еще один способ с методом .NET, который работает так же как предыдущий:

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

Системные $_ и $PSItem и конвейер

Когда мы работаем с существующими командами Powershell бывает необходимо передать определенное значение в параметр. На примере ниже у нас есть список сервисов статус которых мы хотим получить:

На самом деле команда сама подставляет нужные переменные под нужные параметры, которые в целом выглядят так:

Если вы читали статью про функции Powershell, то знаете, что существуют параметры принимающие значения из конвейера и которые этого делать не могут. Что бы увидеть какие параметры принимают данные из конвейера используйте Get-Help:

При создании командлетов указывается какие параметры будут принимать значения из конвейера, какие только по имени (свойству) и каким достаточно только значения. Если нам нужно подставить наши значения в определенный параметр в конвейере используется специальная переменная «$PSItem» или «$_» . Они так же используются в выражениях (ScriptBlock). Например выполнив следующую команду мы получим ошибку:

  • Get-Service : Не удается найти службу с именем службы.
  • Get-Service : Cannot find any service with service name.

Этот тип массивов относится к именованным, а это значит что-либо должно совпадать имя/свойство (оно Service вместо Name) либо мы должны передаваться только значение. Первый вариант это корректно переименовать хэш-таблицу:

Пример выше сработает если только именованный массив относится к PSCustomObject. Если бы это был hashtable, то была бы ошибка.

Второй вариант это напрямую передавать значение:

Чаще и удобнее всего значения подставлять так:

Еще один пример использования $PSItem и $_ в выражениях (ScriptBlock). Вам наверняка часто требуется изменить вывод команд. На примере ниже я получаю сервис, который запущен и содержит в имени «WinR»:

Where-Object — самый частый пример использования таких переменных, так как по умолчанию он не позволяет использовать несколько условий.

Команды

Для создания, удаления и изменения есть 5 команд, которые можно увидеть так:

Получение списка с Get-Variable

Переменные бывают приватными и публичными. По умолчанию всегда создаются публичные. Для получения списка таких переменных и значений используйте этот командлет:

Читайте также:  Windows 10 удалить старую версию виндовс

Есть несколько ключей, которые мы можем использовать для фильтрации:

  • Include — включает поиск по точному соответствию или маске. Например «*PS*1» может соответствовать упоминанию «AoPSlessoon1«;
  • Exlude — исключает упоминания по тому же принципу, что и Include;
  • Name — ищет по имени. Работает так же как Include;
  • ValueOnly — показывает только значения;
  • Scope — тип переменной. Мы можем получить только глобальные «Global», локальные «Local» и Script.

Так мы получим переменную, которая хранит логику поведения при некритичных ошибках:

Если вы попробуете выполнить следующую команду, то увидите одну не критическую ошибку и один процесс:

Учитывая предпочтения мы можем изменить переменную ErrorActionPreference так, что бы ошибка не отображалась либо что бы командлет останавливался:

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

Создание с New-Variable

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

Мы не можем создать переменную используя пробел обычным способом:

Такое написание приведет к ошибке «Непредвиденная лексема», но с командлетом такое пройдет:

Конечно так лучше не делать и обходить такие ситуации нижним подчеркиванием.

Если вы попробуете объявить переменные с одним именем следующим способом, то получите ошибку:

  • New-Variable : Переменная с именем «ar» уже существует.
  • New-Variable : A variable with name ‘ar’ already exists.

Для того что бы перезаписать значения используя командлет нужно дополнительно указать ключ -Force:

Работа командлета с ключом Force будет эквивалентна этим действиям:

Так же можно добавить описание переменной используя параметр Description, но увидеть это описание можно только через Get-Variable.

Приватные и публичные

Мы можем создать приватные и публичные переменные используя параметр Visibility с ключами:

По умолчанию у нас всегда создаются публичные переменные (все примеры выше). Я никогда не использую приватные переменные, так как не вижу в этом смысла. Как я прочитал их используют разработчики модулей для того, что бы их нельзя было изменить. Если создать такую переменную в консоли и попытаться вызвать ее можно получить ошибку:

  • Не удается получить доступ к переменной «‘$te», так как она является частной.
  • Cannot access the variable ‘$te’ because it is a private variable.

Приватные переменные работают в рамках сеанса, в которой они созданы. Если вы запустите эту же команду в ISE или поместите в функцию — все сработает нормально:

Ошибок не будет, если такая же приватная переменная будет работать в отдельном модуле или скрипте.

Options

В отличие от параметра Visibility, который работает в рамках сеансов, Options определяет ее тип. У нас доступно 5 значений:

  • None — стоит по умолчанию;
  • ReadOnly — может быть удалена. Изменение возможно только с параметром Force;
  • Private — переменная доступна только в текущей области (не в сеансе, как в случае с Visibility);
  • AllScope — переменная будет работать в любой новой области;
  • Constant — не может быть удалена или изменена.

Создав переменную для чтения мы сможем ее вызывать:

А попытка изменения без ключа Force приведет к ошибке:

  • Не удается перезаписать переменную ww, так как она является постоянной либо доступна только для чтения.
  • Cannot overwrite variable ww because it is read-only or constant.

Константы работают так же, но даже с ключом Force их изменить нельзя:

Вы можете увидеть переменные, которые уже созданы как константы:

Читайте также:  Windows set path php

Одна из таких переменных $PSVersionTable.

Если вы создадите обычную переменную, то она будет видна в функции:

Обозначив ее приватной — этого сделать не получится:

Локальные и глобальные

Если продолжить прошлый пример и попытаться создать переменную внутри функции, а затем вызвать ее снаружи — у нас это не получится сделать:

Используя Scope со значением Global это можно исправить:

В основном я программирую на Python, и там такой подход считается плохим. Связано это с тем, что функции не созданы для объявления переменных и если это все же происходит — скорее всего она написана не верно. Ошибка может заключаться в том, что модуль с такой переменно может быть импортирован, что приведет к ошибке.

Кроме глобальных доступны еще 3 типа областей:

  • Local — значение по умолчанию;
  • Script — работает в рамках скрипта или модуля;
  • Private — работает в рамках одной области.

Так как по умолчанию создаются переменные Local, работающих только в своих окружениях, следующий скрипт, с одинаковой переменной, выдаст два разных значения:

При этом локальные переменные доступны внутри функций:

Такие типы можно объявлять еще так:

Изменение с Set-Variable

Изменить значение переменной можно двумя путями. Первый — способом описанным раннее:

Аналогичный способ, но с использованием команды:

Если переменная не была создана раннее таким образом ее можно создать:

Есть возможность фильтрации и массового изменения переменных с помощью параметров описанных раннее, но вряд ли это когда-то понадобится:

Можно изменить типы переменных. Нужно помнить, что константу изменить нельзя например.

Очистка и удаление

Есть два командлета, которые удаляют значения:

  • Clear-Variable — удалит только значение, после чего переменная будет равна Null;
  • Remove-Variable — удаляет значение и саму переменную.

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

Дело в том, что вызов несуществующей переменной в Powershell не приводит к ошибке. Такая переменная будет равна Null. Вот и со случаем удаления, через Remove-Variable происходит так же.

Передача в качестве параметров команды

Интересной возможностью использования переменных — это передача как параметров. Рассмотрим команду получения процессов:

Команды могут содержать бесконечно длинный список аргументов. Есть возможность его сократить используя hashtable. Команда ниже выполняет ту же процедуру, что и выше:

Как видно мы просто передали переменную с массивом обозначив ее знаком @.

Powershell Get-Member работа с методами и свойствами объекта на примерах

Методы и функции

Переменные в Powershell это такой же объект, который имеет свои методы и свойства. Посмотреть на них можно так:

Как вы можете увидеть, в зависимости от типа данных, у нас доступны разные методы. Используя строки, например, мы можем посчитать длину:

Можно выполнить замену значений используя метод replace:

Большинство методов доступны в виде команд. Пример действия которого аналогичны предыдущему:

Передача на удаленный компьютер с Invoke-WebRequest

Если вы работаете с PSRemoting, который позволяют выполнять команды на удаленном компьютере, вы попробуете сделать так:

Мы либо получим неверный вывод либо ошибки:

  • Не удается проверить аргумент для параметра «Name». Аргумент пустой или имеет значение NULL.
  • Cannot validate argument on parameter ‘Name’. The argument is null or empty.

Для передачи переменных, а так же функций, нужно добавлять $Using:

Импорт из файла

Если у вас хранятся значения в файле со следующим синтаксисом, то мы можем их импортировать:

Для этого нам нужно получить содержимое файла и объявить значение заново:

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

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

Оцените статью