Unterschiede im Aufruf und Funktion von FOREACH in Powershell
Hallo Gemeinde,
ich bin vor kurzem über eine für mich seltsame Sache in einem Powershellscript gestoßen die ich nicht verstehe.
Im Beispiel befindet sich die gesuchte Gruppe immer in Domain1. Meiner Logik nach sollten also beide Funktionen - welche ja erst ein Domain1 und dann in Domain2 suchen - diese in Domain1 finden und diese mit Return zurückgeben. Nach dem Return ist die Funktion beendet:
Die Ausgabe sieht wie folgt aus:
In domain1
Rückgabewert Funktion A: domain1
In domain1
Nicht in Unter "DC=domain2" kann kein Objekt mit der ID "securitygroup" gefunden werden.
Rückgabewert Funktion B: domain1
Warum führt Funktion B noch die Suche in Domain 2 aus?
Für Aufklärung bin ich dankbar.
Gruß Sam
ich bin vor kurzem über eine für mich seltsame Sache in einem Powershellscript gestoßen die ich nicht verstehe.
Im Beispiel befindet sich die gesuchte Gruppe immer in Domain1. Meiner Logik nach sollten also beide Funktionen - welche ja erst ein Domain1 und dann in Domain2 suchen - diese in Domain1 finden und diese mit Return zurückgeben. Nach dem Return ist die Funktion beendet:
function Test-Function-A {
$Forest = @('domain1','domain2')
ForEach ($Domain in $Forest) {
try {
Get-ADGroup -Identity 'securitygroup' -Server $Domain | out-null
write-host "In $Domain" -ForegroundColor Green
Return $Domain
} catch {
write-host "Nicht in $Domain" -ForegroundColor red
}
}
}
function Test-Function-B {
$Forest = @('domain1','domain2')
$Forest | ForEach-object {
try {
Get-ADGroup -Identity 'securitygroup' -Server $_ | out-null
write-host "In $_" -ForegroundColor Green
Return $_
} catch {
write-host "Nicht in $_" -ForegroundColor red
}
}
}
write-host "Rückgabewert Funktion A: $(Test-Function-A)"
write-host ''
write-host "Rückgabewert Funktion B: $(Test-Function-B)"
Die Ausgabe sieht wie folgt aus:
In domain1
Rückgabewert Funktion A: domain1
In domain1
Nicht in Unter "DC=domain2" kann kein Objekt mit der ID "securitygroup" gefunden werden.
Rückgabewert Funktion B: domain1
Warum führt Funktion B noch die Suche in Domain 2 aus?
Für Aufklärung bin ich dankbar.
Gruß Sam
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 306010
Url: https://administrator.de/contentid/306010
Ausgedruckt am: 22.11.2024 um 07:11 Uhr
3 Kommentare
Neuester Kommentar
Weil du erstens im catch-Teil nicht mit "Break" aus der Foreach-Schleife springst :-P sondern nur eine Ausgabe auf der Konsole machst ...
Denn dein try catch befindet sich ja innerhalb der Schleife und nicht drumherum.
Und zweitens überspringt ein "Return" mit dem foreach-cmdlet nur das aktuelle Element in der Pipeline und beendet nicht die Function ...
Und ich würde das anders machen und das Ergebnis der Suche einer Variablen zuweisen welche man dann auf Inhalt prüft, oder noch einfacher per where-object
Zu den Unterschieden der beiden Methoden siehe:
http://www.admin-source.de/BlogDeu/905/powershell-foreach-und-foreach-o ...
Gruß skybird
Zur Veranschaulichung:
Denn dein try catch befindet sich ja innerhalb der Schleife und nicht drumherum.
Und zweitens überspringt ein "Return" mit dem foreach-cmdlet nur das aktuelle Element in der Pipeline und beendet nicht die Function ...
Und ich würde das anders machen und das Ergebnis der Suche einer Variablen zuweisen welche man dann auf Inhalt prüft, oder noch einfacher per where-object
Zu den Unterschieden der beiden Methoden siehe:
http://www.admin-source.de/BlogDeu/905/powershell-foreach-und-foreach-o ...
Gruß skybird
Zur Veranschaulichung:
# Gibt 1-10 aus ohne die 5
1..10 | %{
if ($_ -eq 5){
return
}else{
$_
}
}
# Gibt 1-4 aus weil Schleife mit Break verlassen wird
1..10 | %{
if ($_ -eq 5){
break
}else{
$_
}
}
Schlauer bin ich allerdings noch nicht.
Dann genehmige dir erst mal einen Kaffee, siehe meine Beispiele oben ...return verlässt in dem CMD-Let nicht die Funktion sondern überspringt nur das Element in der Schleife. Break hingegen beendet die Pipeline in der du dich ja mit foreach-objekt befindest weil es ein cmdlet ist.
Also :
Das hier ist ein Foreach via PIPELINE als CMDLet Version:
$Forest | %{}
foreach($domain in $forest){
#.....
}
Das ist der ganze Unterschied. Man kann also generell nicht sagen das return immer eine Funktion verlässt. In der Pipeline macht ein Return eben das nicht, dort benutzt du break zum verlassen, und übergibst zum Schluss noch per return das Ergebnis z.B. einer Variablen.
Im Endeffekt lässt sich das ganze aber auch auf das hier verkürzen:
function Test-Function{
return (@('domain1','domain2') | ?{Get-ADGroup -Identity 'securitygroup' -Server $_ -EA Ignore})
}