2012-01-25 69 views
7

このスクリプトを修正する方法は?PowerShell - コレクションを列挙してコレクションを変更する

はい、foreachループでコレクションを変更しています。これがこのエラーの原因です。

コレクションで列挙中にエラーが発生しました:コレクションが変更されました。列挙操作はCで.. を実行しない場合があります:\ Users \ユーザーの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

あなたは現在、別のコレクション(配列またはリスト)へ反復しているコレクションをコピーしてみてくださいすることができますその新しいコレクションを反復処理します。このような

何か:$copy変数が別のコレクションを指すこと

10 2 3 4 
1 2 3 4 

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

上記のコードは次のような出力が得られます。

+0

$ webAppSites = $ webApp.sitesのような意味ですか?私はすべてのコレクションをコピーし、その後私はforeachを使用しています – LaPhi

+0

@LaPhi:いいえ、そうではありません。あなたが話しているのは単なる割り当てであり、コピーではありません。配列のコピー方法を示すために私の答えを更新しました。 – Gebb

+1

サイト全体のディープコピーは、アイデアのベストではありません。定期的な 'for'ループが行く方法です。 – Servy

0

チェック:ここ

http://soreddymanjunath.blogspot.in/2014/07/collection-was-modified-enumeration.htmlが削除されます、それがループするforeachを通過します初めて同じ問題

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例ですフリースタイルの時間をサポートしているカルチャでは、2回目の繰り返しでループすると例外が発生します。「コレクションは変更されました。列挙操作が実行されない可能性があります "

上記の問題は、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() 
} 
関連する問題