Как получить доступ к дополнительным свойствам объекта в конвейере после цикла по одной коллекции свойств объектов

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

Function DoThings {
   Process { $_.memberof).where{ $_ -match "Team_" }.foreach{ Remove-ADGroupMember $_ $_.samaccountname}
                  }#did things

Проблема в том, что, поскольку цикл foreach используется для вывода where, я ограничился тем, что не могу получить доступ к остальным свойствам объекта.

Я хочу перебрать подмножество свойств объектов, но мне также нужно иметь возможность получить доступ к другой информации из свойств пользователя, чтобы передать ее командлету (например, имя пользователя).

Пока единственное, что мне удалось выяснить, - это присвоить $ _. Samaccountname временной переменной, а затем вызвать ее позже, но это неэлегантно.

Есть ли более чистый способ сделать это?

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

Bill_Stewart 13.09.2018 19:27

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

Phatmandrake 13.09.2018 19:36

Я не знаю, что вы имеете в виду под «прерыванием потока», но в любом случае я бы рекомендовал переформатировать ваш код. Рекомендации и руководство по стилю PowerShell - хороший справочник.

Bill_Stewart 13.09.2018 20:15
0
3
53
2

Ответы 2

Это можно было бы считать более элегантным:

Function DoThings {
    Process {
        ($_.memberof) | 
            Where-Object { $_ -match "Team_" } -PipelineVariable pipevar | 
                ForEach-Object { Remove-ADGroupMember $_ $pipevar.samaccountname}
}#did things

подробнее о PipelineVariable

Это в основном то, что я искал, за исключением использования методов foreach / where. На самом деле это не требование, а предпочтение, поэтому я, вероятно, выберу этот путь.

Phatmandrake 13.09.2018 22:16

Используя методы where () и foreach (), вы можете указать параметр.

Function DoThings {

    Param ($user)

    Process {

    $_.memberof.Where{
    $_ -match "Team_" }.foreach{
    Remove-ADGroupMember $_ $user.samaccountname}

            }

}#did things

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

DoThings $Userlist

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

Function DoThings {

    [cmdletbinding()]
    param([Parameter(ValueFromPipeline = $true)]$user)

    Process {

    $_.memberof.where{ 
    $_ -match "Team_" }.foreach{ 
    Remove-ADGroupMember $_ $user.samaccountname}

            }

}#did things

Затем будет работать как

$Userlist DoThings 

Базовая функция принимает ввод конвейера, но доступна только через автоматическую переменную $ _. В моем тестировании с использованием автоматической переменной $ input имеет доступ к исходным свойствам объекта, но, по-видимому, может использоваться только один раз для каждой функции.

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

Тот же метод можно использовать с командлетами ForEach-Object и Where-Object без создания новой переменной.

Другие вопросы по теме