Dienstag, 6. November 2018

IEnumerable-ToList() - alternative in PowerShell

Jeder weiß (oder lernt schnell), dass ein IEnumerable nicht verändert werden darf, während es durchlaufen wird.
Speziell im SharePoint-Bereich gilt also, wenn man das folgende in PowerShell versucht:

(Get-SPSite http://mein.sharepoint).AllWebs `
  | select -ExpandProperty Lists `
  | select -ExpandProperty Fields `
  | %{ $_.Update() }

Führt dies zu einer Menge von Fehlern die wie folgt aussehen:
An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute.....

In C# würde ich einfach ToList() einstreuen. Dies würde dazu führen, dass eine flache Kopie des IEnumerable erstellt wird und in weiteren Verarbeitungen der Liste dieser Fehler nicht auftritt.
(Es führt natürlich auch dazu, dass der Enumerator an dieser Stelle vollständig durchlaufen wird, und man all die schönen Vorteile des IEnumerables (d.h. "Lazy Evaluation") verliert)

Eine schöne PowerShell-alternative zu ToList() ist im PowerShell Team Blog verfügbar:

function ToArray {
  begin {
    $output = @(); 
  }
  process {
    $output += $_; 
  }
  end {
    return ,$output; 
  }
}

Dadurch sieht der Aufruf dann wie folgt aus:

(Get-SPSite http://mein.sharepoint).AllWebs `
  | select -ExpandProperty Lists `
  | select -ExpandProperty Fields `
  | ToArray `
  | %{ $_.Update() }

und Funktioniert fehlerfrei.


Keine Kommentare:

Kommentar veröffentlichen