Глава 5. Работа с поставщиками

Одной из потенциально сбивающих с толку сторон PowerShell выступает применение им поставщика (provider). Поставщик предоставляет доступ к специальным хранилищам данных для более простых просмотра и управления. Такие данные появляются в PowerShell в неком устройстве.

Мы предупреждаем вас, что часть данной главы может показаться вам слегка корректирующей. Мы ожидаем, например, что вы знакомы с файловой системой и, скорее всего, знаете все команды, необходимые для управления файловой системой из оболочки. Но потерпите, мы намерены указать на вещи особым образом с тем, чтобы мы могли применить имеющееся у вас знакомство с файловой системой для упрощения понимания концепции поставщиков. Кроме того, имейте в виду, что PowerShell это не Bash. Вы можете обнаружить в данной главе некоторые вещи, которые покажутся вам знакомыми, однако уверяем вас, они делают нечто совершенно отличное от того, к чему вы привыкли.

Что представляет собой поставщик?

Поставщик PowerShell, или PSProvider, это некий переходник. Он спроектирован с тем, чтобы получать некий вид хранимых данных, таких как Реестр Windows, Active Directory или даже локальную файловую систему и заставлять её выглядеть как дисковое устройство. Вы можете обнаружить перечень установленных поставщиков PowerShell прямо внутри своей оболочки:


PS C:\Scripts\> Get-PSProvider
Name                 Capabilities                              Drives
----                 ------------                              ------
Alias                ShouldProcess                             {Alias}
Environment          ShouldProcess                             {Env}
FileSystem           Filter, ShouldProcess, Credentials        {/}
Function             ShouldProcess                             {Function}
Variable             ShouldProcess                             {Variable}
		

В оболочку также можно добавлять поставщиков, обычно совместно с неким модулем, которые являются двумя способами расширения PowerShell. (Мы рассмотрим эти расширения позднее в своей книге.) Порой, при включении определённых функциональных возможностей PowerShell может создаваться некий новый PSProvider. Например, вы можете манипулировать переменными среды при помощи поставщика Environment, которого мы рассмотрим в разделе 5.5 и которого вы можете наблюдать здесь:


PS C:\Scripts> Get-PSProvider
Name                 Capabilities                              Drives
----                 ------------                              ------
Alias                ShouldProcess                             {Alias}
Environment          ShouldProcess                             {Env}
FileSystem           Filter, ShouldProcess, Credentials        {/}
Function             ShouldProcess                             {Function}
Variable             ShouldProcess                             {Variable}
		

Обратите внимание на то, что каждый поставщик обладает различными возможностями (capabilities). Это важно, потому как это оказывает воздействие на те пути, коими может применяться каждый поставщик. Вот некоторые из распространённых возможностей, которые вы можете наблюдать:

  • ShouldProcess - Данный поставщик поддерживает применение параметров -WhatIf и -Confirm, позволяющие вам "проверять" определённые действия перед их фиксацией.

  • Filter - Этот поставщик поддерживает параметр -Filter в тех командлетах, которые манипулируют содержимым поставщика.

  • Credentials - Этот поставщик допускает для вас определять альтернативные полномочия при подключении к хранимым данным. Для этого имеется параметр -Credential.

Для создания некого PSDrive {устройства PowerShell} вы применяете поставщика. PSDrive для подключения к хранилищу данных использует отдельного поставщика. Вы создаёте соответствие устройству и, благодаря имеющимся поставщикам, некое PSDrive имеет возможность подключаться к намного большему чем к дискам. Для просмотра перечня подключённых в настоящее время устройств выполните такую команду:


PS C:\Scripts> Get-PSDrive
 
Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
/                 159.55        306.11 FileSystem    /
Alias                                  Alias
Env                                    Environment
Function                               Function
Variable                               Variable
		

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


PS C:\Scripts> Get-Command -Noun *item*
Capability      Name
----------      ----
Cmdlet          Clear-Item
Cmdlet          Clear-ItemProperty
Cmdlet          Copy-Item
Cmdlet          Copy-ItemProperty
Cmdlet          Get-ChildItem
Cmdlet          Get-Item
Cmdlet          Get-ItemProperty
Cmdlet          Invoke-Item
Cmdlet          Move-Item
Cmdlet          Move-ItemProperty
Cmdlet          New-Item
Cmdlet          New-ItemProperty
Cmdlet          Remove-Item
Cmdlet          Remove-ItemProperty
Cmdlet          Rename-Item
Cmdlet          Rename-ItemProperty
Cmdlet          Set-Item
Cmdlet          Set-ItemProperty
		

Чтобы приступить к работе с имеющимися в нашей системе поставщиками мы будем пользоваться этими командлетами и их псевдонимами. Поскольку, скорее всего, он является одним из наиболее знакомых вам, мы начнём с файловой системы - с PSProvider FileSystem.

Понимание того как организована имеющаяся файловая система

Определённая файловая система организуется вокруг двух основных типов объектов - папок и файлов. Папки (Folders) это к тому же некий вид контейнера, способного содержать как файлы, так и прочие папки. Файлы (Files) не являются неким типом контейнера; они более схожи с объектами конечных точек.

Скорее всего вы более знакомы с просмотром файловой системы через Finder в macOS, браузер файлов в Linux или Проводник (Explorer) в устройстве Windows (Рисунок 5.1), в которых становится очевидной иерархия устройств, папок и файлов.

 

Рисунок 5-1


Просмотр файлов, папок и устройств в Finder и в Windows Explorer

Терминология PowerShell неким образом отличается от имеющейся в соответствующей файловой системе. Поскольку PSDrive может не указывать на файловую систему - например, PSDrive способен устанавливать соответствие с конечными точками Environment, Registry или даже SCCM, которые очевидно не файловая система - PowerShell не пользуется терминами file и folder (папка). Вместо этого он ссылается на эти объекты более общим термином item (элемент). И файл, и папка рассматриваются как элементы, хотя, очевидно, это различные типы элементов. Именно по этой причине показанные нами ранее названия командлетов применяют в своём существительном Item.

Элементы способны, а часто это так и есть, обладать свойствами. Например, элемент файла может обладать свойствами, содержащими время его последней записи, доступен он или нет исключительно на чтение и тому подобными. Некоторые элементы, например, папки, могут обладать дочерними элементами (child items), которые являются элементами, содержащимися внутри данного элемента. Знание этих фактов поможет вам понять смысл тех глаголов и существительных, которые присутствуют в приведённом ранее списке команд:

  • Такие глаголы как Clear, Copy, Get, Move, New, Remove, Rename и Set, все они, могут применяться к элементам (например, файлам и папкам) и к свойствам элементов (например, значению даты последней записи или является ли он доступным только на запись).

  • Само существительное Item ссылается на индивидуальные объекты, таким как файлы и папки.

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

  • Существительное ChildItem ссылается на те элементы (например на файлы в подчинённых папках), которые содержатся внутри некого элемента (например, в папке).

Имейте в виду, что эти командлеты намеренно являются универсальными, поскольку они предназначены для работы с различными хранилищами данных. Некоторые возможности командлетов в определённых ситуациях не имеют смысла. Например, поскольку поставщик файловой системы не поддерживает возможность транзакций, ни один из параметров командлета -UseTransaction не будет работать с элементами на дисках такой файловой системы. {Прим. пер.: с появлением поддерживающих транзакции файловые системы, возможно, мы увидим и здесь изменения.}

Некоторые PSProviders не поддерживают свойства элементов. Например, PSProviders Environment это нечто, применяемое для превращение в доступное для PowerShell устройства ENV: . Данное устройство предоставляет доступ к имеющимся переменным среды, однако как это показывает приводимый далее пример, они не обладают свойствами элемента:


PS C:\Scripts> Get-ItemProperty -Path Env:\PSModulePath
Get-ItemProperty : Cannot use interface. The IPropertyCmdletProvider
interface is not supported by this provider.
		

Тот факт, что не все PSProvider похожи, возможно, превращает поставщиков в столь сбивающий с толку для новичков PowerShell. Вам придётся представлять то, к чему каждый поставщик предоставляет вам доступ и понимать, что даже если применяемый командлет знает как делать нечто, это не означает что этот конкретный поставщик, с которым вы работаете, будет поддерживать данную операцию.

Навигация по файловой системе

Другой командлет, который вам необходимо знать при работе с поставщиками это Set-Location. Именно он применяется для изменения текущего положения оболочки в другой элемент с типом контейнера, например в папку:


Linux / macOS
PS /Users/tplunk> Set-Location -Path /
PS />
 
Windows
PS C:\Scripts> Set-Location -Path /
PS />
		

Скорее всего, вам более знаком псевдоним этой команды, cd, который соответствует команде Change Directory из Bash. Вот как мы применяем этот псевдоним и передаём значение желаемого пути в качестве позиционного параметра:


Linux / macOS
PS /Users/tplunk> cd /usr/bin
PS /usr/bin>
 
Windows
PS C:\Scripts\> cd C:\Users\tplunk
PS C:\Users\tplunk<
		
[Замечание]Устройства в не- Windows операционных системах

macOS и Linux не пользуются устройствами (drives) для ссылки на дискретно подключаемые устройства хранения. Вместо этого вся их операционная система целиком обладает единым корнем (root), представляемого слешем (в PowerShell также применяется обратный слеш). Однако PowerShell для прочих поставщиков всё же предоставляет в не- Windows операционных системах PSDrives (устройства PowerShell). Попробуйте исполнить Get-PSDrive чтобы увидеть что доступно.

Одна из самых хитроумных задач в PowerShell это создание новых элементов. Например, как вы создадите новый каталог? Попробуйте выполнить New-Item и вы неожиданно получите приглашение на ввод:


PS C:\Users\tplunk\Documents> New-Item testFolder
Type:
		

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


PS C:\Users\tplunk\Documents> New-Item testFolder -ItemType Directory
 
 
    Directory: C:\Users\tplunk\Documents
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----           5/26/19 11:56 AM                testFolder
		

PowerShell Windows на самом деле содержит команду mkdir, о которой многие люди полагают, что она псевдоним для New-Item. Однако mkdir не требует от вас определять значение directory -ItemType. По причине конфликта со встроенной командой mkdir, данная функция mkdir была удалена в PowerShell Core для не- Windows платформ.

Применение символов подстановки и буквальных путей

Большинство поставщиков позволяют вам определять при использовании командлетов Item пути двумя способами. Данный раздел обсудит эти два способа определения путей. Командлеты Item содержат параметр -Path, и по умолчанию данный параметр принимает символы подстановки. Рассмотрим полную подсказку для Get-ChildItem, к примеру, раскрывающую следующее:


-Path <String[]>
    Specifies a path to one or more locations. Wildcards are
    permitted. The default location is the current directory (.).
    Required?                    false
    Position?                    1
    Default value                Current directory
    Accept pipeline input?       true (ByValue, ByPropertyName)
    Accept wildcard characters?  True
		

Символ замены * служит для нуля или более символов, в то время как символ замены ? представляет собой любой единственный символ. Несомненно вы применяете их время от времени, возможно, с псевдонимом Dir для Get-ChildItem:


PS C:\Scripts> dir y*
 
 
    Directory: C:\Scripts
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
--r---            5/4/19 12:03 AM          70192 yaa
--r---            5/4/19 12:02 AM          18288 yacc
--r---            5/4/19 12:03 AM          17808 yes
		

В Linux и macOS, большинство таких символов подстановки допускается как часть значений имён элементов в их файловой системе, а также в большинстве прочих хранилищ. В Environment, к примеру, вы можете обнаружить несколько значений с именами, содержащими ?. Это представляет некую проблему: Когда вы применяете в неком пути * или ?, предполагает ли PowerShell их трактовку как символа подстановки или как буквальный символ? Если вы ищите элементы с названием variable?, желаете ли вы получить элемент с названием variable? или же вы хотите трактовать ? в качестве символа подстановки, получая вместо этого свои элементы, такие как variable7 и variable8?

Решением PowerShell для этой проблемы выступает некий альтернативный параметр -LiteralPath. Данный параметр не принимает символы подстановки:


-LiteralPath <String[]>
    Specifies a path to one or more locations. Unlike the Path
    parameter, the value of the LiteralPath parameter is used exactly
    as it is typed. No characters are interpreted as wildcards. If
    the path includes escape characters, enclose it in single
    quotation marks. Single quotation marks tell PowerShell
    not to interpret any characters as escape sequences.
    Required?                    true
    Position?                    named
    Default value
    Accept pipeline input?       true (ByValue, ByPropertyName)
    Accept wildcard characters?  False
		

Когда вы желаете чтобы * и ? воспринимались буквально, вместо параметра -Path вы применяете параметр -LiteralPath. Обратите внимание на то, что параметр -LiteralPath не является позиционным; если вы планируете его применять, вам придётся набирать -LiteralPath. Когда вы предоставляете некий путь в первой позиции (скажем, y*), он будет интерпретироваться как предназначенный для параметра -Path. К тому же символы замены также воспринимаются.

Работа с прочими поставщиками

Одним из лучших способов ощутить таких прочих поставщиков и то как работают различные командлеты item, это поупражняться с неким устройством PowerShell (PSDrive), которое не является конкретной файловой системой. Из всех встроенных в PowerShell поставщиков, вероятно, Environment является наилучшим примером для работы с ним (частично потому, что он доступен во всех системах).

Мы создадим некую переменную среды. Обрамите внимание на то, что для данного упражнения мы пользуемся терминалом Ubuntu, но вы можете следовать ему вне зависимости от того применяете ли вы его в машине Windows или macOS (вот она прелесть кроссплатформенности). Начнём с перечисления всех переменных среды:


PS /Users/tplunk> Get-ChildItem env:*
 
Name                           Value
----                           -----
XPC_FLAGS                      0x0
LANG                           en_US.UTF-8
TERM                           xterm-256color
HOME                           /Users/tplunk
USER                           tplunk
PSModulePath                   /Users/tplunk/.local/share/powershell/Modu...
HOMEBREW_EDITOR                code
PWD                            /Users/tplunk
COLORTERM                      truecolor
XPC_SERVICE_NAME               0
		

Затем установим для переменной среды A значение 1:


PS /Users/tplunk> Set-Item -Path Env:/A -Value 1
PS /Users/tplunk> Get-ChildItem Env:/A*
 
Name                           Value
----                           -----
A                              1
		

Реестр Windows

Другой поставщик, который мы можем наблюдать в машине Windows это Реестр (Registry). Давайте начнём с изменения в части HKEY_CURRENT_USER Реестра, выставляемой как устройство HKCU: :


PS C:\> set-location -Path hkcu:
		
[Замечание]Замечание

Возможно, вам придётся запустить PowerShell от имени Администратора.

Затем переместимся в верную часть своего Реестра:


PS HKCU:\> set-location -Path software
PS HKCU:\software> get-childitem
    Hive: HKEY_CURRENT_USER\software
Name                           Property
----                           --------
7-Zip                          Path64 : C:\Program Files\7-Zip\
                               Path   : C:\Program Files\7-Zip\
Adobe
Amazon
AppDataLow
AutomatedLab
BranchIO
ChangeTracker
Chromium
Clients
 
PS HKCU:\software> set-location microsoft
PS HKCU:\software\microsoft> Get-ChildItem
    Hive: HKEY_CURRENT_USER\software\microsoft
Name                           Property
----                           --------
Accessibility
Active Setup
ActiveMovie
ActiveSync
AppV
Assistance
AuthCookies
Avalon.Graphics
Clipboard                      ShellHotKeyUsed : 1
Common
CommsAPHost
ComPstUI
Connection Manager
CTF
Device Association Framework
DeviceDirectory                LastUserRegistrationTimestamp : {230, 198, 218, 150...}
Edge                           UsageStatsInSample                 : 1
                               EdgeUwpDataRemoverResult           : 2
                               EdgeUwpDataRemoverResultDbh        : 1
                               EdgeUwpDataRemoverResultRoaming    : 0
                               EdgeUwpDataRemoverResultData       : 1
                               EdgeUwpDataRemoverResultBackupData : 1
EdgeUpdate                     LastLogonTime-Machine : 132798161806442449
EdgeWebView                    UsageStatsInSample : 1
EventSystem
Exchange
F12
Fax
		

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


PS HKCU:\software\microsoft> Set-Location .\Windows
PS HKCU:\software\microsoft\Windows> Get-ChildItem
    Hive: HKEY_CURRENT_USER\software\microsoft\Windows
Name                           Property
----                           --------
AssignedAccessConfiguration
CurrentVersion
DWM                            Composition                  : 1
                               ColorPrevalence              : 0
                               ColorizationColor            : 3288334336
                               ColorizationColorBalance     : 89
                               ColorizationAfterglow        : 3288334336
                               ColorizationAfterglowBalance : 10
                               ColorizationBlurBalance      : 1
                               EnableWindowColorization     : 0
                               ColorizationGlassAttribute   : 1
                               AccentColor                  : 4278190080
                               EnableAeroPeek               : 1
Shell
TabletPC
Windows Error Reporting        LastRateLimitedDumpGenerationTime : 
➥ 132809598562003780
Winlogon
		

Обратите внимание на значение Реестра EnableAeroPeek. Давайте изменим его на 0:


PS HKCU:\software\microsoft\Windows> Set-ItemProperty -Path dwm -PSProperty
EnableAeroPeek -Value 0
		

Также вы могли бы воспользоваться параметром –Name вместо –PSProperty. Давайте проверим это чтобы убедиться что наша замена "принята":


PS HKCU:\software\microsoft\Windows> Get-ChildItem
    Hive: HKEY_CURRENT_USER\software\microsoft\Windows
Name                           Property
----                           --------
AssignedAccessConfiguration
CurrentVersion
DWM                            Composition                  : 1
                               ColorPrevalence              : 0
                               ColorizationColor            : 3288334336
                               ColorizationColorBalance     : 89
                               ColorizationAfterglow        : 3288334336
                               ColorizationAfterglowBalance : 10
                               ColorizationBlurBalance      : 1
                               EnableWindowColorization     : 0
                               ColorizationGlassAttribute   : 1
                               AccentColor                  : 4278190080
                               EnableAeroPeek               : 0
Shell
TabletPC
Windows Error Reporting        LastRateLimitedDumpGenerationTime : 
➥ 132809598562003780
Winlogon
		

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

Лабораторные занятия

[Замечание]Замечание

Для данных лабораторных занятий вам потребуется компьютер с запущенным PowerShell v7.1 или последующим.

Из приглашения на ввод PowerShell выполните следующие задачи:

  1. Создайте новый каталог с названием Labs.

  2. Создайте файл нулевой длины с названием /Labs/Test.txt (воспользуйтесь New-Item).

  3. Можно ли воспользоваться Set-Item для изменения содержимого /Labs/Test.txt на -TESTING? Или же вы получаете ошибку. Если вы получаете ошибку, то почему?

  4. Воспользовавшись поставщиком Environment, отобразите значение для системной переменной среды PATH.

  5. Воспользуйтесь подсказкой для определения в чём разница между параметрами -Filter, -Include и -Exclude для Get-ChildItem.

Ответы лабораторных занятий

  1. New-Item -Path ~/Labs -ItemType Directory

  2. New-Item –Path ~/labs -Name test.txt -ItemType file

  3. Поставщик FileSystem не поддерживает такое действие.

  4. Работает каждая из следующих команд:

    Get-Item env:PATH

    Dir env:PATH

  5. -Include и -Exclude должны применяться с –Recurse, или когда вы выполняете запрос для контейнера. -Filter пользуется возможностями фильтрации поставщика PowerShell (PSProvider), что поддерживают не все поставщики. Например в имеющейся файловой системе вы можете применить DIR –filter.

[Замечание]Дополнительно

У вас возникли проблемы с заданием 4? PowerShell на компьютере с Windows не чувствителен к регистру, то есть прописные и строчные буквы не имеют значения. PATH это то же самое что и path. Однако в машинах Linux и macOS заглавные буквы имеют значение: PATH это не то же самое что и path.