PowerShell - 枚举整个集合并更改集合

问题描述:

修复此脚本的可行性如何?PowerShell - 枚举整个集合并更改集合

是的,我正在改变foreach循环中的集合,这就是这个错误的原因。

通过集合枚举时发生错误:集合被修改;枚举操作可能不会执行.. 在C:\用户\用户\文档\ PowerShell的\ ChangeAllListsV2.ps1:47字符:20 +的foreach < < < <(在$ webLists $列表) + CategoryInfo:InvalidOperation:(微软.Share ...上+ 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 

SPListCollection在更新其属性(字段,事件接收器等)时倾向于修改集合。您可以使用一个for循环,而不是:

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

你可以尝试复制您当前迭代到另一个集合(数组或列表的集合)然后迭代新的集合。

像这样:

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

上面的代码给出以下输出:

10 2 3 4 
1 2 3 4 

注意,$copy变量指的是不同的集合。

+0

您的意思是像$ webAppSites = $ webApp.sites?我复制每个集合,之后我使用foreach – LaPhi

+0

@LaPhi:不,不是那样的。你在谈论的只是一项任务,而不是复制。我更新了我的答案,以显示数组如何被复制。 – Gebb

+1

整个网站的深层复制并不是最好的想法。常规的'for'循环是要走的路。 – Servy

检查: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() 
    } 

anonther例如首次将经过循环的foreach将删除第一次支持文化,第二次循环时,它会抛出异常“集合被修改;枚举操作可能不会执行“,

解决上述问题的方法是存储要在Arraylist中修改的值并尝试修改哪些可以解决问题,在这里我存储名为enumcul的Arraylist并将值插入并修改它...

$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() 
}