Как и где использовать регулярные выражения powershell и regex

Шаг 1. Создание пула носителейStep 1: Create a storage pool

Сначала необходимо сгруппировать доступные физические диски в один или несколько пулов носителей.You must first group available physical disks into one or more storage pools.

  1. В области навигации диспетчер сервера выберите файл и службы хранилища.In the Server Manager navigation pane, select File and Storage Services.

  2. В области навигации выберите страницу Пулы носителей .In the navigation pane, select the Storage Pools page.

    По умолчанию доступные диски включаются в пул под названием primordial.By default, available disks are included in a pool that is named the primordial pool. Если в разделе ПУЛЫ НОСИТЕЛЕЙ нет пула primordial, это значит, что хранилище не соответствует требованиям к дисковым пространствам.If no primordial pool is listed under STORAGE POOLS, this indicates that the storage does not meet the requirements for Storage Spaces. Убедитесь, что диски соответствуют требованиям, перечисленным в разделе «Предварительные условия».Make sure that the disks meet the requirements that are outlined in the Prerequisites section.

    Совет

    Если выбрать пул носителей Primordial, доступные физические диски будут представлены в разделе ФИЗИЧЕСКИЕ ДИСКИ.If you select the Primordial storage pool, the available physical disks are listed under PHYSICAL DISKS.

  3. В разделе Пулы носителейвыберите список задачи , а затем выберите новый пул носителей.Under STORAGE POOLS, select the TASKS list, and then select New Storage Pool. Откроется мастер создания пула носителей.The New Storage Pool Wizard will open.

  4. На странице перед началом выполнения нажмите кнопку Далее.On the Before you begin page, select Next.

  5. На странице Укажите имя и подсистему пула носителей введите имя и необязательное описание пула носителей, выберите группу доступных физических дисков, которую вы хотите использовать, а затем нажмите кнопку Далее.On the Specify a storage pool name and subsystem page, enter a name and optional description for the storage pool, select the group of available physical disks that you want to use, and then select Next.

  6. На странице Выбор физических дисков для пула носителей выполните следующие действия, а затем нажмите кнопку Далее.On the Select physical disks for the storage pool page, do the following, and then select Next:

    1. Установите флажок рядом с каждым физическим диском, который нужно включить в пул носителей.Select the check box next to each physical disk that you want to include in the storage pool.

    2. Если вы хотите назначить один или несколько дисков в качестве горячего резервирования, в разделе выделениещелкните стрелку раскрывающегося списка и выберите горячий запас.If you want to designate one or more disks as hot spares, under Allocation, select the drop-down arrow, then select Hot Spare.

  7. На странице Подтверждение выбора Проверьте правильность параметров и нажмите кнопку создать.On the Confirm selections page, verify that the settings are correct, and then select Create.

  8. На странице Просмотр результатов убедитесь, что все задачи завершены, а затем нажмите кнопку Закрыть.On the View results page, verify that all tasks completed, and then select Close.

    Примечание

    Либо, чтобы перейти непосредственно к следующему шагу, можно установить флажок Создать виртуальный диск при закрытии мастера.Optionally, to continue directly to the next step, you can select the Create a virtual disk when this wizard closes check box.

  9. Убедитесь, что новый пул носителей представлен в списке ПУЛЫ НОСИТЕЛЕЙ.Under STORAGE POOLS, verify that the new storage pool is listed.

Поиск по содержимому файлов через Powershell

Мы можем искать внутри файлов, т.е. вхождение строк:

SimpleMatch — строка, которую мы хотим найти внутри файла

В случае выше, для всего что слева от pipeline | , будет идти поиск внутри файлов на упоминание строки fixmypc.

Командлет Select-String может использоваться для поиска файлов:

Разница в том, что он будет искать только в текущей папке, а не во вложенных. Он так же будет искать вхождение в каждом файле, что при большом объеме существенно увеличит время работы. Т.е. эта команда предназначена уже для отфильтрованных значений, например после Get-ChildItem.

Но в Select-String есть дополнительные ключи, которые могут быть полезны. Вот часть из них:

  • CaseSensitive — в обычных командлетах и сравнениях Powershell «а» и «А» одинаковые буквы. Если поставить этот ключ, то они станут разными
  • Pattern — если с ключом SimpleMatch мы можем найти конкретную строку (нельзя использовать * звездочку), то с этим ключом мы можем использовать регулярные выражения.

Иногда есть необходимость найти файл, по содержащимся в нем словам, или же найти все строки содержащие нужный паттерн. Рассмотрим несколько вариантов поиска по тексту в Powershell

Для примера я буду искать в логах Exchange 2013 нужного мне отправителя

Использовать командлет Select-String можно разными способами. Например подавать содержимое файлов через конвейер:

Как видно это весьма медленный вариант.

Указывая список файлов аргументом Select-String мы получим значительный прирост скорости поиска.

Workflow

Я попробовал несколько вариантов использования Select-String в Workflow. Сначала вариант с циклом:

На удивление, никакого прироста скорости поиска я не получил, даже увеличивая значение «-throttlelimit»

Самым быстрый вариант

Здесь в блоке parallel мы, используя InlineScript, заносим результат Select-String в массив

Не могу объяснить за счет чего именно достигается увеличение скорости поиска, тем не менее, при необходимости найти документ или строки в большом объеме данных, можно использовать эту конструкцию. Можно искать по всем дискам компьютера, или же и вовсе по списку компьютеров. Думаю в этом случае мы получим прирост по времени, значительно больший чем 3 секунды

Я знаю, что этот вопрос может быть «вопросом нового парня», но я, вероятно, допустил логическую ошибку.

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

я думаю, это то, что вы пытаетесь сделать:

В вашем примере вы определяете строку с именем $SEL , а затем проверяете, равна ли она $null (что, конечно, всегда будет иметь значение false , поскольку определяемая вами строка не является $null ! )

Кроме того, если файл содержит шаблон, он вернет что-то вроде:

Поэтому не забудьте переключить свои -eq на -ne или поменять местами свои команды if/else , потому что в настоящее время вы повторяете Contains String , когда $SEL равен $null , то есть назад.

Проверьте SS64 для объяснений и полезных примеров для всего в PowerShell и cmd

Другой способ проверить, существует ли строка в файле:

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

Политика выполненияExecution Policy

Вопреки распространенному мнению, политика выполнения в PowerShell не является средством обеспечения безопасности.Contrary to popular belief, the execution policy in PowerShell is not a security boundary. Она предназначена для предотвращения непреднамеренного выполнения сценария пользователем.It’s designed to prevent a user from unknowingly running a script. Определенный пользователь может без труда обойти политику выполнения в PowerShell.A determined user can easily bypass the execution policy in PowerShell. В таблице 1-2 показана политика выполнения по умолчанию для текущих операционных систем Windows.Table 1-2 shows the default execution policy for current Windows operating systems.

Версия операционной системы WindowsWindows Operating System Version Политика выполнения по умолчаниюDefault Execution Policy
Server 2019Server 2019 Удаленно подписаннаяRemote Signed
Server 2016Server 2016 Удаленно подписаннаяRemote Signed
Windows 10Windows 10 С ограниченным доступомRestricted

Любая команда PowerShell может выполняться в интерактивном режиме, независимо от настройки политики выполнения.Regardless of the execution policy setting, any PowerShell command can be run interactively. Политика выполнения влияет только на команды, выполняемые в сценарии.The execution policy only affects commands running in a script. Командлет используется для определения текущего параметра политики выполнения, а командлет используется для изменения политики выполнения.The cmdlet is used to determine what the current execution policy setting is and the cmdlet is used to change the execution policy. Рекомендуется использовать политику RemoteSigned, которая требует, чтобы предназначенные для выполнения скачиваемые сценарии были подписаны доверенным издателем.My recommendation is to use the RemoteSigned policy, which requires downloaded scripts to be signed by a trusted publisher in order to be run.

Проверка текущей политики выполненияCheck the current execution policy:

Если для политики выполнения задано С ограниченным доступом, сценарии PowerShell вообще не запускаются.PowerShell scripts can’t be run at all when the execution policy is set to Restricted. Это параметр по умолчанию для всех клиентских операционных систем Windows.This is the default setting on all Windows client operating systems. Чтобы продемонстрировать проблему, сохраните следующий код как файл с именем .To demonstrate the problem, save the following code as a file named .

Эта команда выполняется в интерактивном режиме без ошибок при условии, что PowerShell запущена с повышенными правами администратора.That command runs interactively without error as long as PowerShell is run elevated as an administrator. Но при сохранении в виде файла сценария и попытке выполнить сценарий выдается ошибка.But as soon as it’s saved as a script file and you try to execute the script, it generates an error:

Обратите внимание, что в сообщении об ошибке, приведенном в предыдущем наборе результатов, указывается точная проблема (в этой системе отключено выполнение сценариев).Notice that the error shown in the previous set of results tells you exactly what the problem is (running scripts is disabled on this system). При выполнении в PowerShell команды, которая создает сообщение об ошибке, обязательно следует прочесть сообщение об ошибке, а не просто перезапустить команду и надеяться на ее успешное завершение.When you run a command in PowerShell that generates an error message, be sure to read the error message instead of just rerunning the command and hoping that it runs successfully

Измените политику выполнения PowerShell на удаленно подписанную.Change the PowerShell execution policy to remote signed.

Обязательно прочтите предупреждение, которое отображается при изменении политики выполнения.Be sure to read the warning that’s displayed when changing the execution policy. Кроме того, рекомендуется ознакомиться с разделом справки about_Execution_Policies, чтобы знать о влиянии изменения политики выполнения на безопасность.I also recommend taking a look at the about_Execution_Policies help topic to make sure you understand the security implications of changing the execution policy.

Теперь, когда для политики выполнения задано значение Удаленно подписанная, сценарий будет выполняться без ошибок.Now that the execution policy has been set to RemoteSigned, the script runs error free.

Прежде чем продолжить, запустите службу времени Windows. В противном случае могут возникнуть непредвиденные проблемы.Be sure to start your Windows Time service before continuing otherwise you may run into unforeseen problems.

Через файл ntuser.dat

Каждый раз, как пользователь входит в систему все его настройки загружаются из файла ntuser.dat, который находится в домашнем каталоге ‘C:\Users\UserName\’. При выходе из системы все настройки записываются в этот же файл. То есть мы можем получить имя пользователя по дате изменения этого файла.

В этом примере вернутся все каталоги пользователей:

Получим даты изменения файлов ‘ntuser.dat’:

Извлечем из пути имя пользователя и уберем лишние колонки:

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

Это же мы можем использовать с командой Get-ChildItem. Соединим все это в функцию:

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

Ключ ‘-ErrorAction SilentlyContinue’ нужен для игнорирования ошибок связанных с выключенными компьютерами. Если его не написать вы получите ошибки формата:

Get-ChildItem : Cannot find path ‘\\CL2\C$\Users\’ because it does not exist.

Отмечу несколько моментов:

  1. В отличие от первого скрипта Get-ChildItem может принимать массивы. Изменив строки на массивы вы можете немного ускорить работу скрипта. То есть вы можете написать
    «Get-Childitem -Path ‘\\Computer1\C$\Users’, ‘\\Computer2\C$\Users’ «;
  2. LogoffDate — это отдельный тип данных даты и времени, а это значит, например, что мы можем увидеть кто вышел за последний час/сутки. Пример будет ниже.
  3. Если вы выполняете команды типа ‘Invoke-Command’ (удаленные команды) — они тоже могут изменить файл ntuser.dat. То есть вы возможно захотите исключить часть пользователей из финального списка. Пример ниже.

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

Исключить пользователей мы можем так же:

Экспорт для Excel аналогичен предыдущему примеру:

Вам так же будет интересно:

Получения результата соответствия по шаблону и группировка

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

По шаблону ниже мы ищем значения, где есть от 1 до 3 цифр, пробел после которого идет слово ‘rub’:

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

Захват с $Matches

При использовании групп у нас появляется специальная переменная $Matches, которая хранит найденные по шаблонам результаты:

Первая группы, которая попадает в $Matches — это весь шаблон от кавычки до кавычки. Далее идут совпадения, которые находятся в круглых скобках (). Проблема в том, что в $Matches появляется только первый найденный результат и из-за этого значение в ‘200 руб’ у нас не отображается. О том как это исправить будет рассмотрено в следующей главе.

Сам $Matches имеет тип hashtable, который позволяет получать значения по именам:

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

  • (?<Имя>шаблон)
  • (?Имяшаблон)

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

Когда нужно исключить группу для сохранения в $Matches, можно использовать ‘?:’ :

Как видно у нас сохранилась только одна общая группа (между кавычками).

Захват всех результатов с Select-String

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

Конечно можно использовать конвейер и обращаться к значениям напрямую:

 

Получение списка программ

Ключ реестра, который содержит все программы следующий:

Список программ можно получить так:

Если взглянуть на вывод, то можно подумать, что нам нужно свойство Name, так как оно лучше всего соответствует названию программы, но этот выбор будет некорректный. Вместо значений свойства Name можно увидеть идентификаторы приложения, а вот DisplayName выглядит корректно:

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

Команда, которая вернет только версию и отображаемое имя:

Примеры скриптов проверяются на Windows Server 2019 и Windows 10. На серверной версии появляются пустые строки связанные с нестандартными объектами:

Я решил их не включать в список программ, так как они относятся к системным  программам установленными вместе с ОС. Скрипт, который исключит их, выглядит так:

Создание новых элементов (New-Item)Creating New Items (New-Item)

Чтобы создать новый элемент в файловой системе, используйте командлет New-Item .To create a new item in the file system, use the New-Item cmdlet. Включите параметр Path с путем к элементу и параметр ItemType с значением file или directory.Include the Path parameter with path to the item, and the ItemType parameter with a value of «file» or «directory».

Например, чтобы создать каталог с именем «New.Directory» в каталоге C:\Temp, введите:For example, to create a new directory named «New.Directory»in the C:\Temp directory, type:

Чтобы создать файл, измените значение параметра ItemType на file.To create a file, change the value of the ItemType parameter to «file». Например, чтобы создать файл с именем file1.txt в каталоге New.Directory, введите:For example, to create a file named «file1.txt» in the New.Directory directory, type:

Тот же метод можно использовать для создания нового раздела реестра.You can use the same technique to create a new registry key. На самом деле, раздел реестра создать проще, так как единственный тип элементов в реестре Windows — это раздел.In fact, a registry key is easier to create because the only item type in the Windows registry is a key. (Записи реестра — это свойства элементов.) Например, чтобы создать ключ с именем _Test в подразделе CurrentVersion, введите:(Registry entries are item properties .) For example, to create a key named «_Test» in the CurrentVersion subkey, type:

При вводе пути реестра не забудьте добавить двоеточие ( ) в имена дисков Windows PowerShell: HKLM: и HKCU:.When typing a registry path, be sure to include the colon ( ) in the Windows PowerShell drive names, HKLM: and HKCU:. Без двоеточия Windows PowerShell не распознает имена дисков в пути.Without the colon, Windows PowerShell does not recognize the drive name in the path.

Системные $_ и $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 — самый частый пример использования таких переменных, так как по умолчанию он не позволяет использовать несколько условий.

Использование хэш-таблицUsing hash tables

Используя хэш-таблицы в массиве, можно сортировать разные свойства в разном порядке.You can sort different properties in different orders by using hash tables in an array.
Каждая хэш-таблица использует ключ Expression для указания имени свойства в виде строки и ключ Ascending (по возрастанию) или Descending (по убыванию) для указания порядка сортировки по или .Each hash table uses an Expression key to specify the property name as string and an Ascending or Descending key to specify the sort order by or .
Ключ Expression является обязательным.The Expression key is mandatory.
Ключи Ascending или Descending являются необязательными.The Ascending or Descending key is optional.

В следующем примере объекты сортируются в порядке убывания по LastWriteTime и в порядке возрастания по Name .The following example sorts objects in descending LastWriteTime order and ascending Name order.

Вы также можете установить блок скрипта для ключа Expression .You can also set a scriptblock to the Expression key.
При выполнении командлета выполняется блок сценария, а его результат используется для сортировки.When running the cmdlet, the scriptblock is executed and the result is used for sorting.

В следующем примере объекты сортируются в порядке убывания в промежутке времени между CreationTime (временем создания файла) ​​и LastWriteTime (временем последней записи).The following example sorts objects in descending order by the time span between CreationTime and LastWriteTime .

windows — Как получить текущее имя пользователя в Windows Powershell?

Я подумал, что было бы полезно обобщить и сравнить приведенные ответы.

Если вы хотите получить доступ к переменной среды :

(более простой/короткий/незабываемый вариант)

  • ::UserName — @ThomasBratt
  • $env:username — @Eoin
  • whoami — @galaktor

(более надежный вариант)

::GetCurrent().Name — @MarkSeemann

Сравнение

@Kevin Panko комментирует @Mark Seemann ответ на вопрос о выборе одной из категорий над другой:

— самый безопасный ответ, потому что пользователь может использовать переменную $env: USERNAME, но это не обманет, сделав это.

Короче говоря, параметр переменной окружения более краткий, а опция токена доступа к окну более надежна.

Мне пришлось использовать подход к токенам доступа к окну @Mark Seemann в PowerShell script, который я запускал из приложения С# с олицетворением. Приложение С# запускается с моей учетной записью пользователя и запускает powershell script в качестве учетной записи службы. Из-за ограничения того, как я запускаю PowerShell script из С#, экземпляр PowerShell использует переменные среды моей учетной записи пользователя, даже если он запущен как пользователь учетной записи службы. В этой настройке параметры переменной среды возвращают мое имя учетной записи, а параметр токена доступа к окну возвращает имя учетной записи службы (именно это я и хотел), а параметр входа в систему возвращает мое имя учетной записи.

Тестирование

Кроме того, если вы хотите сравнить параметры самостоятельно, вот script, который вы можете использовать для запуска script в качестве другого пользователя. Вам нужно использовать командлет Get-Credential для получения объекта учетных данных, а затем запустить этот script с помощью script для запуска в качестве другого пользователя в качестве аргумента 1, а объект учетных данных — как аргумент 2.

Применение:

Содержание Run-AsUser.ps1 script:

Входные данные конвейераPipeline Input

Если требуется, чтобы функция принимала входные данные конвейера, необходимо написать дополнительный код.When you want your function to accept pipeline input, some additional coding is necessary. Как говорилось ранее в этой книге, команды могут принимать входные данные конвейера по значению (по типу) или по имени свойства.As mentioned earlier in this book, commands can accept pipeline input by value (by type) or by property name. Вы можете писать свои функции так же, как машинные команды, чтобы они принимали один тип входных данных или оба.You can write your functions just like the native commands so that they accept either one or both of these types of input.

Чтобы принимать входные данные конвейера по значению, укажите атрибут параметра для этого конкретного параметра.To accept pipeline input by value, specified the parameter attribute for that particular parameter. Помните, что входные данные конвейера по значению можно принимать только от одного из каждого типа данных.Keep in mind that you can only accept pipeline input by value from one of each datatype. Например, если есть два параметра, принимающих строковые входные данные, то только один из них может принимать входные данные конвейера по значению, так как, если это условие указано для обоих строковых параметров, входным данным конвейера будет неизвестно, к какому параметру следует выполнить привязку.For example, if you have two parameters that accept string input, only one of those can accept pipeline input by value because if you specified it for both of the string parameters, the pipeline input wouldn’t know which one to bind to. Это еще одна причина, по которой я называю этот тип входных данных конвейера по типу вместо по значению.This is another reason I call this type of pipeline input by type instead of by value.

Входные данные конвейера поступают в один элемент за раз аналогично тому, как элементы обрабатываются в цикле .Pipeline input comes in one item at a time similar to the way items are handled in a loop.
Если в качестве входных данных принимается массив, для обработки каждого из этих элементов требуется как минимум блок .At a minimum, a block is required to process each of these items if you’re accepting an array as input. Если в качестве входных данных принимается только одно значение, блок не требуется, но я по-прежнему рекомендую указывать его для обеспечения согласованности.If you’re only accepting a single value as input, a block isn’t necessary, but I still recommend specifying it for consistency.

Прием входных данных конвейера по имени свойства происходит аналогично, за исключением того, что указывается с помощью атрибута параметра и может быть указан для любого числа параметров независимо от типа данных.Accepting pipeline input by property name is similar except it’s specified with the parameter attribute and it can be specified for any number of parameters regardless of datatype. Ключевом момент в том, что выходными данными команды, в которую передается параметр, должно быть имя свойства, совпадающее с именем параметра или псевдонимом параметра вашей функции.The key is that the output of the command that’s being piped in has to have a property name that matches the name of the parameter or a parameter alias of your function.

Блоки и являются необязательными. and blocks are optional. указывается перед блоком и используется для выполнения всех начальных задач до получения элементов из конвейера. would be specified before the block and is used to perform any initial work prior to the items being received from the pipeline

Разобраться с этим очень важно.This is important to understand. Переданные значения недоступны в блоке .Values that are piped in are not accessible in the block

Блок указывается после блока и используется для очистки после обработки всех переданных элементов.The block would be specified after the block and is used for cleanup once all of the items that are piped in have been processed.

Использование массивов

Передача массивов в виде параметров

В предыдущих статьях было множество примеров по работе с массивами и хэш таблицами. Их же, как и любой другой тип данных, мы можем передавать в функцию. Для примера все команды Powershell, которые имеют ключ ComputerName, могут выполняться удаленно. Большинство таких команд могут принимать в виде значений массивы, то есть нам не обязательно передавать поочередно имена компьютеров.

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

Массивы так же работают по индексам, что позволяет передавать больше параметров. Такой способ не релевантный, но может когда-то пригодиться.

Хэш таблицы

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

Знак @ в команде объявляет, что данные хэш таблицы будут использоваться как параметры команды

Важно, чтобы их имена  соответствовали настоящим параметрам

Получение списка служб

Узнать статус всех служб можно так:

Каждый результат выдаваемый командами в PS представляет собою объект. Этот объект содержит разные свойства и методы. Свойства — это например имя или статус. По умолчанию мы видим не все свойства. Что бы узнать какие еще свойства есть у команды нужно выполнить следующее:

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

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

Или выведем информацию по одному сервису:

У сервисов есть короткое имя и отображаемое. Так мы выведем оба:

В именах мы можем использовать маски, а это значит что мы можем не знать полное название и использовать знак * в том месте, где не уверены в названии или написании:

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

  • Cannot find any service with service name
  • Cannot find any service with display name
  • Не удается найти службу с отображаемым именем

Кроме этого есть два ключа, которые тоже поддерживают маски:

  • Include — включают поиск по какой-то маске или точному соответствию.
  • Exclude — исключает упоминание.

Можно сравнить разницу с прошлым примером:

У сервисов несколько статусов:

  • Running — запущен.
  • Stopped — остановлен.
  • Paused — приостановлен (пауза).

По каждому из них мы можем отфильтровать результат:

Кроме этого есть 3 типа запуска:

  • Automatic — автоматический запуск вместе с системой.
  • AutomaticDelayedStart — запуск после загрузки системы.
  • Manual — ручной запуск.
  • Disabled — отключенный.

Допустим, что у нас есть какая-то проблема в операционной системе и мы хотим проверить все сервисы, который автоматически запускаются при включении ОС. Для этого нам нужно использовать несколько условий, где статус не равен Running и тип запуска равен Automatic:

Службы могут быть зависимы от других и для проверки этих свойств есть два параметра:

  • DependentServices — кто зависит от этого сервиса.
  • RequiredServices — от кого зависит этот сервис.

Аналогично параметрам команды выше есть свойства DependentServices и ServicesDependedOn (RequiredServices). Они выводят одно и то же.

Есть несколько свойств, которые не выведены в параметры — это:

  • CanPauseAndContinue — можно ли приостановить работу сервиса и возобновить.
  • CanShutdown — может ли быть выключен.
  • CanStop — может ли быть полностью остановлен.

Эти свойства так же можно увидеть в GUI. В командлете ниже я использую алиас gsv (короткое имя Get-Service):

Каждая команда PS, где присутствует параметр ComuterName, может быть выполнена удаленно. Для удаленного управления в Powershell нужны дополнительные настройки, которые уже описывались в предыдущей статье. 

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

Передача параметров

Чаще всего функции принимают какой-то объект и возвращают. Для примера может потребоваться изменить время, когда эти логи созданы и их количество. В существующей функции такой возможности нет. Вы можете править код каждый раз, но это не подход программиста. Что бы такая возможность появилась в функции нужно добавить параметры, которая она будет принимать:

Параметры функции обозначаются в круглые скобки и пишутся после названия функции и до выражения. 

Теперь, для вызова функции, требуется передавать два параметра:

При вызове функции мы передаем два обязательных параметра со значениями. Эти значения, внутри функции, будут доступны под названиями $param1 и $param2. Эти переменные мы передаем в команду получения и фильтрации логов.

Установка значений по умолчанию

В нашей задаче, чаще всего, мы получаем только 50 последних логов и нам не хочется указывать их каждый раз. Если мы не будем указывать этот параметр в существующей функции, то получим ошибку. Что бы этого избежать нужно указать значение по умолчанию. На примере ниже я присвоил $param1 значение 50. Оно будет использоваться только в том случае, если мы не используем этот параметр при вызове:

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

Как видно на примере, если мы не указываем ключи param1 и param2 важна последовательность, так как именно в такой последовательности они будут присвоены переменным внутри функций.

Возвращение значений

В отличие от других языков, если мы присвоим переменной $result результат функции Get-DayLog, то она будет содержать значения:

Это будет работать до тех пор, пока мы не решим изменить функцию присвоив переменные:

Мы не можем получить результат используя переменную $result, так как функция не выводит информацию, а хранит ее в переменной $events. Вызывая $events мы тоже не получаем информацию, так как тут работает понятие «область видимости переменных».

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

Я бы рекомендовал всегда возвращать значения через return, а не использовать вывод используя команды типа Write-Output внутри функции. Использование return останавливает работу функции и возвращает значение, а это значит что его не стоит ставить по середине логики если так не планировалось.

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

Я вернул оба значения разделив их запятой. По умолчанию всегда возвращается массив. Массивы в Powershell это набор не именованных параметров. Более подробно  о них мы уже писали.

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

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

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

Вы можете возвращать любой тип данных и в любом формате и последовательности. Каждый из них имеет своё преимущество.

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

Все переменные объявленные до момента вызова функции могут быть ей использованы:

Такой подход не запрещает переопределить переменную внутри функции дав ей другое значение:

Как уже писалось выше, значения внутри функции не доступны вне нее и у нас есть все возможности что бы этого не потребовалось. Тем не менее есть способ объявить внутри функции переменную, которая будет доступна вне нее.

Такие переменные называются глобальными. Объявляются приставкой $global:

Как вы видите, в отличие от предыдущего примера, переменная $zarplata изменила значение. Использование глобальных переменных является нежелательным так как может привести к ошибкам. Ваш скрипт может быть импортируемым модулем и об этой переменной может никто не знать, тем не менее она будет в области видимости.

Оцените статью
Рейтинг автора
5
Материал подготовил
Андрей Измаилов
Наш эксперт
Написано статей
116
Добавить комментарий