2012-01-25 35 views
7

修復此腳本的可行性如何?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 

回答

20

SPListCollection在更新其屬性(字段,事件接收器等)時傾向於修改集合。您可以使用一個for循環,而不是:

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

你可以嘗試複製您當前迭代到另一個集合(數組或列表的集合)然後迭代新的集合。

像這樣:

$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

0

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