PowerShell - 枚举集合并更改集合

LaP*_*Phi 7 powershell foreach sharepoint

如何修复此脚本?

是的,我在foreach循环中更改了集合,这就是导致此错误的原因.

通过集合枚举时发生错误:集合已被修改; 枚举操作可能无法执行..在C:\ Users\user\Documents\PowerShell\ChangeAllListsV2.ps1:47 char:20 + foreach <<<<($ list in $ 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
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 20

SPListCollection在更新其属性(字段,事件接收器等)时,往往会修改集合.您可以使用for循环:

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


小智 7

我知道这是一个很旧的线程。这适用于最终访问此页面寻找答案的任何人。

正如其他答案所建议的那样,这个想法是将集合(使用clone()方法)复制到另一个集合并迭代“另一个”并修改循环内的原始变量,而不必使用for代替foreach

ArrayList 类型的集合:

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

输出:

PS H:\> $collection1
Foo
baz
Run Code Online (Sandbox Code Playgroud)

Hashtable 类型的集合:

[System.Collections.Hashtable]$collection2 = @{
        "Forum" = "Stackoverflow"
        "Topic" = "PowerShell"
        }

$($collection2.Clone())| foreach {
$collection2.Remove("Forum")
}
Run Code Online (Sandbox Code Playgroud)

输出: PS H:> $collection2

Name                           Value                                                              
----                           -----                                                              
Topic                          PowerShell                                                         
Run Code Online (Sandbox Code Playgroud)

并且,一个基本数组:

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

输出:

PS H:\> $collection3
10
10
10
10
Run Code Online (Sandbox Code Playgroud)

只要您的收藏不是固定大小的。