Nano Hash - криптовалюты, майнинг, программирование

PowerShell не создает массив

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

Пример:

$groups = "group1","Group2","Group3" # to be excluded
foreach ($group in $groups) {
    $dns = (Get-ADGroup "$Group").DistinguishedName
}
Write-Host $dns

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

(Get-ADGroup "$Group").DistinguishedName | Out-File c:\list.txt

Я получу все 3. То же самое и с `Get-ADUser, если я попытаюсь получить пользователя из массива.

Любое реальное решение, с которым кто-нибудь сталкивался?


Ответы:


1

PowerShell не создает массив волшебным образом только потому, что вы этого хотите. Поскольку $dns не является массивом с самого начала, ваш код заменяет его значение на каждой итерации, поэтому после завершения цикла вы получите только последнее значение.

У вас есть 2 способа решить эту проблему:

  • Определите $dns как массив перед циклом и добавьте к этому массиву внутри цикла.

    $dns = @()
    foreach ($group in $groups) {
        $dns += (Get-ADGroup "$Group").DistinguishedName
    }
    

    Хотя практически все делают это таким образом, этот подход НЕ РЕКОМЕНДУЕТСЯ из соображений производительности. Добавление к массиву требует больших затрат, потому что оно по существу создает новый массив увеличенного размера, перемещает все существующие элементы и помещает новый элемент в новый свободный слот, а затем заменяет исходный массив.

  • Выведите результаты внутри цикла и соберите весь вывод цикла в переменную.

    $dns = foreach ($group in $groups) {
        (Get-ADGroup "$Group").DistinguishedName
    }
    

    Этот подход имеет значительно лучшую производительность, чем добавление внутри цикла. Однако стоит отметить, что если цикл производит ноль или один элемент, результатом будет либо $null, либо простое значение, а не массив. Однако вы можете принудительно использовать его в массиве, поместив цикл в оператор построения массива:

    $dns = @(foreach ($group in $groups) {
        (Get-ADGroup "$Group").DistinguishedName
    })
    

Дополнение: Как упоминалось в комментариях @Clijsters, на самом деле существует третий способ решить эту проблему, используя коллекцию .Net вместо базовых массивов PowerShell:

$dns = New-Object System.Collections.ArrayList
foreach ($group in $groups) {
    $dns.Add((Get-ADGroup "$Group").DistinguishedName) | Out-Null
}

Добавление к коллекции обходится намного дешевле, чем добавление к массиву PowerShell. Однако создание экземпляра коллекции сопряжено с некоторыми накладными расходами. Вы получите наилучшую производительность, просто собрав выходные данные цикла в переменную ($dns = foreach (...) {...}).

31.01.2018
  • Спасибо, Ансгар, на самом деле я делаю это, экспортируя всех пользователей из группы, но исключая тех, кто является членом еще трех групп, которые я проверю. $groups="group1","Group2","Group3" # to be excluded ForeacH($group in $groups){ $dns=(Get-ADGroup "$Group").DistinguishedName } Foreach($dn In $dns){ get-ADGroupMember -Identity "GroupA" |get-aduser -prop memberof |where{$_.memberof -notcontains $dn}|select name } 31.01.2018
  • Не стоит ли упомянуть ArrayLists и их метод Add? 31.01.2018
  • У коллекций @Clijsters есть свои недостатки, потому что их первоначальное создание, как правило, дорого. Сбор вывода цикла в переменную на самом деле является самым быстрым способом сделать такого рода вещи, по крайней мере, насколько мне известно. 31.01.2018
  • @DhruvSaxena Пожалуйста, не перемещайте цель. Если у вас есть новый или дополнительный вопрос: опубликуйте новый вопрос. 31.01.2018
  • @AnsgarWiechers Разве вы не упомянули добавление массива, которое само по себе (как указано в вашем ответе) довольно неэффективно? Было бы интересно сравнить их и иметь представление, при каком размере предмета стоит рассматривать... 31.01.2018
  • @Clijsters Я упоминал об этом, потому что именно так большинство людей (или, по крайней мере, большинство людей, которые задают вопросы здесь, на SO), похоже, обрабатывают вывод цикла, который они хотят, в массиве. И я, кажется, припоминаю, что явно отговаривал людей от фактического использования этого подхода. ;) 31.01.2018
  • @AnsgarWiechers Лол, не волнуйся, это не к тебе вопрос 01.02.2018
  • Накладные расходы на создание объектов почти полностью обусловлены накладными расходами, которые добавляет вызов New-Object. $dns = @() и $dns = [System.Collections.ArrayList]::new() примерно равны по производительности. В любом случае, поскольку вы создаете экземпляр $dns только один раз, влияние на производительность, скорее всего, будет минимальным, независимо от того, как вы это сделаете. 01.02.2018

  • 2

    Проблема в том, что ваш Write-Host находится вне вашего цикла!

    $groups = "Group1", "Group2", "Group3"
    foreach ($group in $groups) {
        $dns = (Get-ADGroup $group).DistinguishedName
        Write-Host $dns # <--- it's inside, now!
    }
    

    Это запишет значение для каждой группы, а не только для последней.

    31.01.2018
  • Хотя это правильно, на самом деле он не нацелен на ядро ​​​​f вопроса, который указывает на то, что $dns имеет только одно значение, а не массив. 31.01.2018
  • Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

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

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..