PowerShell Tips & Tricks: het verschil tussen Foreach en Foreach-Object
PowerShell bestaat al sinds 2006 en kan worden ingezet om de meeste taken voor Microsoft-producten te automatiseren. In 2016 heeft Microsoft PowerShell Core op de markt gebracht. Sindsdien ondersteunt PowerShell niet alleen Windows, maar ook andere platformen zoals MacOS en Linux.
In de vorm van een blogserie zal ik een aantal specifieke onderdelen van PowerShell behandelen. Hierbij ga ik steeds in op hoe het onderdeel werkt en hoe je het op de juiste manier kunt inzetten.
In dit blog kijken we naar het verschil tussen ForEach en ForEach-Object. Dit zijn 2 methodes die op het eerste gezicht dezelfde functionaliteit hebben, maar om verschillende redenen toch hun eigen plek hebben binnen PowerShell scripting.
Wat doen de ForEach of ForEach-Object methodes?
Het is mogelijk om met het ForEach commando door een lijst (array) te lopen en er per regel een actie aan te koppelen.
- $Range | ForEach-Object {}
- ForEach ($Number in $Range) {}
Ondanks dat de methodes hetzelfde eindresultaat hebben, doen ze hun werk op verschillende manieren. Laten we eerst eens kijken hoelang het duurt als we PowerShell alle waardes tussen 1 en 1.000.000 laten weergeven. Met het commando Measure-Command kunnen we meten hoelang een commando duurt.
We beginnen met ForEach-Object.
We zien hier dat het ForEach-Object commando 2.878 seconden heeft geduurd. Laten we dezelfde actie nogmaals uitvoeren, maar nu met het ForEach commando.
Dit ForEach commando heeft maar 0.565 seconden geduurd.
Wat veroorzaakt het verschil in snelheid?
Laten we de stappen die beide methodes doen eens onder elkaar zetten om te zien waar het verschil in zit.
Wat doet het ForEach-Object commando:
- Pak de eerste opvolgende waarde.
- Voer het commando met deze waarde uit.
Wat doet het ForEach commando:
- Laad de array ($Range) in het geheugen.
- Pak de eerste opvolgende waarde.
- Voer het commando met deze waarde uit.
Nu we de stappen hebben uitgeschreven, kunnen we duidelijk zien waar het tijdsverschil tussen beide methodes vandaan komt. ForEach laadt eerst alle waardes in het geheugen, terwijl ForEach-Object de array verwerkt als een stream en meteen begint met het uitvoeren van het commando.
Waarom soms toch ForEach-Object gebruiken?
ForEach-Object mag dan trager zijn dan het ForEach commando, maar er is zeker een reden om dit commando in te zetten.
Als er gebruik wordt gemaakt van een groot array met meerdere velden en vele waardes, kan de PowerShell taak erg veel werkgeheugen innemen als er gebruik wordt gemaakt van de ForEach methode. Mocht dit de stabiliteit van de machine beïnvloeden, dan is het verstandig om toch voor het tragere ForEach-Object te kiezen.
Peter Barendse, DevOps Engineer