- Работа с переменными окружения в Powershell Env
- Изменение переменных окружения пользователя в Powershell
- Изменение переменных Env компьютера в Powershell
- Создание новых переменных Environment в Powershell
- Переменные в Powershell и работа с типами данных — объявление и вывод
- Создание
- Типы данных
- Кавычки и форматирование строк
- Системные $_ и $PSItem и конвейер
- Команды
- Получение списка с Get-Variable
- Создание с New-Variable
- Приватные и публичные
- Options
- Локальные и глобальные
- Изменение с Set-Variable
- Очистка и удаление
- Передача в качестве параметров команды
- Методы и функции
- Передача на удаленный компьютер с Invoke-WebRequest
- Импорт из файла
Работа с переменными окружения в 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] — массив типа ключ и значение.
В большинстве случаев нет необходимости объявлять тип переменной, так как 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
Переменные бывают приватными и публичными. По умолчанию всегда создаются публичные. Для получения списка таких переменных и значений используйте этот командлет:
Есть несколько ключей, которые мы можем использовать для фильтрации:
- 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 их изменить нельзя:
Вы можете увидеть переменные, которые уже созданы как константы:
Одна из таких переменных $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 пробелы: