Arhn - архитектура программирования

PowerShell - перечисление по коллекции и изменение коллекции

Как можно исправить этот скрипт?

Да, я меняю коллекцию в цикле foreach, и это причина этой ошибки.

Ошибка при перечислении в коллекции: Коллекция была изменена; операция перечисления может не выполняться .. По адресу C: \ Users \ user \ Documents \ PowerShell \ ChangeAllListsV2.ps1: 47 символов: 20 + foreach ‹*** (список $ в $ webLists) + CategoryInfo: InvalidOperation: (Microsoft.Share. ..on + SPEnumerator: SPEnumerator) [], RuntimeException + FullyQualifiedErrorId: BadEnumeration

#Script change in all lists the required field property "testfield" to false


#Part 0 - Configuration

$urlWebApp = "http://dev.sharepoint.com"
$countFound = 0
$countList = 0
$countFoundAndChange = 0

#Part 1 - PreScript  

$snapin = Get-PSSnapin | Where-Object {$_.Name -eq "Microsoft.SharePoint.Powershell"}

if ($snapin -eq $null)

{
    Write-Host “Loading SharePoint Powershell”
    Add-PSSnapin Microsoft.SharePoint.Powershell
}

#Part 2 - Script

$webApp = Get-SPWebApplication $urlWebApp

#$webApp | fl

    $webAppSites = $webApp.sites

    foreach($site in $webAppSites)
    {
        Write-Host "***********************************************************************"
        Write-Host "Found site: " $site -foreground blue

        $siteAllWebs = $site.AllWebs

        foreach($web in $siteAllWebs)
        {
            Write-Host "Found web: " $web -foreground blue
            #$web | fl

           $webLists = $web.Lists

            foreach($list in $webLists)
            {
             $countList ++

             Write-Host "Found list: " $list -foreground blue

                #Change list property

                $field = $Null
                $field = $list.Fields["testfield"]

                    if($field){
                    Write-Host "Field found: " $list -foreground green
                    #Write-Host "in web: " $web -foreground green
                    $countFound ++

                        try{

                            if($field.Required)
                            {

                            #######################################################
                            $field.Required = $False
                            $field.Update()
                            #######################################################

                            $field = $Null
                            Write-Host "Done!: Change list: " $list -foreground  green
                            $countFoundAndChange ++                    

                            }else{ 
                            Write-Host "Already!: Change list: " $list -foreground  green       

                            }

                        }
                        catch{
                            $field = $Null
                            Write-Host "Error!: Change list: " $list -foreground red
                            Write-Host "in web: " $web -foreground red
                            $_

                        }

                    }


            } 


        }


    }



Write-Host "Found lists: " $countList
Write-Host "Found lists with column [testfield]: " $countFound
Write-Host "Change lists with column [testfield]: " $countFoundAndChange

Ответы:


1

SPListCollection имеет тенденцию изменять коллекцию при обновлении ее свойств (полей, приемников событий и т. Д.). Вместо этого вы можете использовать цикл for:

for ($i = 0; $i -lt $webLists.Count; $i++)
{
  $list = $web.Lists[$i];
  # ...
}
25.01.2012

2

Вы можете попробовать скопировать коллекцию, которую вы выполняете в данный момент, в другую коллекцию (массив или список), а затем выполнить итерацию в этой новой коллекции.

Что-то вроде этого:

$collection = @(1, 2, 3, 4)
$copy = @($collection)
$collection[0] = 10
$collection -join " "
$copy -join " "

Приведенный выше код дает следующий результат:

10 2 3 4
1 2 3 4

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

25.01.2012
  • Вы имеете в виду что-то вроде $ webAppSites = $ webApp.sites? Я копирую каждую коллекцию и после этого использую foreach 25.01.2012
  • @LaPhi: Нет, не так. То, о чем вы говорите, - это просто задание, а не копирование. Я обновил свой ответ, чтобы показать, как копируется массив. 25.01.2012
  • Полная копия всего сайта - не лучшая идея. Обычный цикл for - лучший вариант. 25.01.2012
  • @Servy Я не предлагал глубокое копирование. 27.01.2012

  • 3

    Я знаю, что это довольно старая ветка. Это для всех, кто заходит на эту страницу и ищет ответ.

    Идея, как и в других ответах, заключается в том, чтобы скопировать коллекцию (с помощью метода clone ()) в другую и повторить другую и изменить исходную переменную внутри цикла без необходимости использовать for < / strong> вместо foreach:

    Коллекция типа ArrayList:

    [System.Collections.ArrayList]$collection1 = "Foo","bar","baz"
    $($collection1.Clone()) | foreach {
    $collection1.Remove("bar")
    }
    

    Вывод:

    PS H:\> $collection1
    Foo
    baz
    

    Коллекция типа Hashtable:

    [System.Collections.Hashtable]$collection2 = @{
            "Forum" = "Stackoverflow"
            "Topic" = "PowerShell"
            }
    
    $($collection2.Clone())| foreach {
    $collection2.Remove("Forum")
    }
    

    Вывод: PS H: ›$ collection2

    Name                           Value                                                              
    ----                           -----                                                              
    Topic                          PowerShell                                                         
    

    И базовый массив:

    [System.Array]$collection3 = 1, 2, 3, 4
    $($collection3.Clone()) | foreach {
    $collection3[$collection3.IndexOf($_)] = 10
    }
    

    Вывод:

    PS H:\> $collection3
    10
    10
    10
    10
    

    Если ваша коллекция не фиксированного размера.

    16.10.2020

    4

    Проверьте: http://soreddymanjunath.blogspot.in/2014/07/collection-was-modified-enumeration.html

    Вот еще один пример той же проблемы

        if($web.IsMultilingual -eq $true  )
      {
    
        foreach($cul in $web.SupportedUICultures)
       {
         if($cul.LCID -ne  $webCul.LCID -and $cul.LCID -ne "1033")
         {    
    
           $web.RemoveSupportedUICulture($cul)
    
    
          }
        }
     $web.Update()
      }
    

    впервые он будет проходить цикл. foreach сначала удалит поддерживаемую культуру, а когда дело доходит до цикла для второй итерации, он выдаст вам исключение «Коллекция была изменена; операция перечисления может не выполняться »,

    Решение вышеуказанной проблемы состоит в том, чтобы сохранить значения для изменения в Arraylist и попытаться изменить, что устранит проблему. Здесь я сохраняю Arraylist, называемый enumcul, и вставляю в него значения и изменяю его ...

    $enumcul=New-Object Collections.ArrayList
    $i=0
    if($web.IsMultilingual -eq $true  )
      {
    
        foreach($cul in $web.SupportedUICultures)
       {
         if($cul.LCID -ne  $webCul.LCID -and $cul.LCID -ne "1033")
         {
    
          $enumcul.Insert($i, $cul)
          $i=$i+1
          }
    
       }
    
    
     foreach( $k in $enumcul)
     {
    
        $web.RemoveSupportedUICulture($k)
        $web.Update()
     }
    
    03.07.2014
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..


    © 2024 arhn.ru, Arhn - архитектура программирования