about_Foreach
Korte beschrijving
Beschrijft een taalopdracht die u kunt gebruiken om alle items in een verzameling items te doorlopen.
Lange beschrijving
De foreach instructie (ook wel een foreach lus genoemd) is een taalconstructie voor het doorlopen (herhalen) van een reeks waarden in een verzameling items.
Het eenvoudigste en meest typische type verzameling om door te gaan, is een matrix.
Binnen een foreach lus is het gebruikelijk om een of meer opdrachten uit te voeren voor elk item in een matrix.
Syntax
Hieronder ziet u de foreach syntaxis:
foreach ($<item> in $<collection>){<statement list>}
Het deel van de foreach instructie tussen haakjes vertegenwoordigt een variabele en een verzameling die moet worden herhaald. PowerShell maakt de variabele $<item> automatisch wanneer de foreach lus wordt uitgevoerd. Vóór elke iteratie door de lus wordt de variabele ingesteld op een waarde in de verzameling.
Het blok na een foreach instructie {<statement list>} bevat een set opdrachten die u wilt uitvoeren voor elk item in een verzameling.
Voorbeelden
De lus in het volgende voorbeeld geeft bijvoorbeeld foreach de waarden in de $letterArray matrix weer.
$letterArray = "a","b","c","d"
foreach ($letter in $letterArray)
{
Write-Host $letter
}
In dit voorbeeld wordt de $letterArray matrix gemaakt en geïnitialiseerd met de tekenreekswaarden "a", "b"en "c""d". De eerste keer dat de foreach instructie wordt uitgevoerd, wordt de $letter variabele ingesteld die gelijk is aan het eerste item in $letterArray ("a"). Vervolgens wordt de Write-Host cmdlet gebruikt om de letter a weer te geven. De volgende keer door de lus, $letter is ingesteld op "b", enzovoort. Nadat de foreach lus de letter d weergeeft, sluit PowerShell de lus af.
foreach instructies kunnen ook worden gebruikt samen met cmdlets die een verzameling items retourneren. In het volgende voorbeeld doorloopt de Foreach-instructie de lijst met items die worden geretourneerd door de Get-ChildItem cmdlet.
foreach ($file in Get-ChildItem)
{
Write-Host $file
}
U kunt het voorbeeld verfijnen met behulp van een if instructie om de resultaten te beperken die worden geretourneerd. In het volgende voorbeeld voert de foreach instructie dezelfde lusbewerking uit als in het vorige voorbeeld, maar er wordt een if instructie toegevoegd om de resultaten te beperken tot bestanden die groter zijn dan 100 kilobytes (KB):
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100KB)
{
Write-Host $file
}
}
In dit voorbeeld gebruikt de foreach lus een eigenschap van de $file variabele om een vergelijkingsbewerking ($file.length -gt 100KB) uit te voeren. De $file variabele bevat alle eigenschappen in het object dat wordt geretourneerd door de Get-ChildItem cmdlet. Daarom kunt u meer dan alleen een bestandsnaam retourneren.
In het volgende voorbeeld retourneert PowerShell de lengte en de laatste toegangstijd in de lijst met instructies:
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100KB)
{
Write-Host $file
Write-Host $file.length
Write-Host $file.lastaccesstime
}
}
In dit voorbeeld bent u niet beperkt tot het uitvoeren van één opdracht in een instructielijst.
U kunt ook een variabele buiten een foreach lus gebruiken en de variabele binnen de lus verhogen. In het volgende voorbeeld worden bestanden geteld van meer dan 100 kB:
$i = 0
foreach ($file in Get-ChildItem) {
if ($file.length -gt 100KB) {
Write-Host $file "file size:" ($file.length / 1024).ToString("F0") KB
$i = $i + 1
}
}
if ($i -ne 0) {
Write-Host
Write-Host $i " file(s) over 100 KB in the current directory."
}
else {
Write-Host "No files greater than 100 KB in the current directory."
}
In het voorgaande voorbeeld wordt de $i variabele ingesteld op 0 buiten de lus en wordt de variabele in de lus verhoogd voor elk bestand dat groter is dan 100 kB. Wanneer de lus wordt afgesloten, evalueert een if instructie de waarde van $i het weergeven van een telling van alle bestanden van meer dan 100 kB. Of er wordt een bericht weergegeven met de mededeling dat er geen bestanden van meer dan 100 kB zijn gevonden.
In het vorige voorbeeld ziet u ook hoe u de resultaten van de bestandsgrootte opmaken:
($file.length / 1024).ToString("F0")
De waarde wordt gedeeld door 1024 om de resultaten in kilobytes weer te geven in plaats van bytes. De resulterende waarde wordt vervolgens opgemaakt met behulp van de notatieaanduiding voor vaste punten om eventuele decimale waarden uit het resultaat te verwijderen. De 0 maakt de notatieaanduiding geen decimalen weergeven.
In het volgende voorbeeld parseert de functie die is gedefinieerd PowerShell-scripts en scriptmodules en retourneert de locatie van functies die zijn opgenomen in. In het voorbeeld ziet u hoe u de MoveNext methode gebruikt (die vergelijkbaar is met skip X een For lus) en de Current eigenschap van de $foreach variabele in een foreach-scriptblok. De voorbeeldfunctie kan functies in een script vinden, zelfs als er ongebruikelijke of inconsistente functiedefinities zijn die meerdere regels omvatten.
Zie Enumerators gebruiken voor meer informatie.
function Get-FunctionPosition {
[CmdletBinding()]
[OutputType('FunctionPosition')]
param(
[Parameter(Position = 0, Mandatory,
ValueFromPipeline, ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('PSPath')]
[System.String[]]
$Path
)
process {
try {
$filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) {
Write-Verbose "From pipeline"
$_
} else {
Write-Verbose "From parameter, $Path"
Get-Item -Path $Path
}
$parser = [System.Management.Automation.Language.Parser]
Write-Verbose "lets start the foreach loop on `$filesToProcess with $($filesToProcess.count) as count"
foreach ($item in $filesToProcess) {
Write-Verbose "$item"
if ($item.PSIsContainer -or
$item.Extension -notin @('.ps1', '.psm1')) {
continue
}
$tokens = $errors = $null
$parser::ParseFile($item.FullName, ([REF]$tokens),
([REF]$errors)) | Out-Null
if ($errors) {
$msg = "File '{0}' has {1} parser errors." -f $item.FullName,
$errors.Count
Write-Warning $msg
}
:tokenLoop foreach ($token in $tokens) {
if ($token.Kind -ne 'Function') {
continue
}
$position = $token.Extent.StartLineNumber
do {
if (-not $foreach.MoveNext()) {
break tokenLoop
}
$token = $foreach.Current
} until ($token.Kind -in @('Generic', 'Identifier'))
$functionPosition = [pscustomobject]@{
Name = $token.Text
LineNumber = $position
Path = $item.FullName
}
Add-Member -InputObject $functionPosition `
-TypeName FunctionPosition -PassThru
}
}
}
catch {
throw
}
}
}