Get-Aduser -Filter akzeptiert keine Variable

8

Ich möchte überprüfen, ob ein Benutzerkonto bereits im System vorhanden ist.

%Vor%

Ich bin nicht sicher warum, aber $User gibt immer null zurück, auch wenn {sAMAccountName -eq "$SamAc"} wahr sein soll.

Was fehlt mir hier?

Bearbeiten:

Das ist was fehlte:

%Vor%

Anmerkung des Redakteurs: Der Skriptblock ( { ... } ) wurde durch eine Zeichenkette ersetzt.

    
JustAGuy 19.11.2013, 15:27
quelle

6 Antworten

19

Es gibt wertvolle Informationen in den vorhandenen Antworten, aber ich denke, eine genauere Zusammenfassung ist hilfreich:

tl; dr

  • Verwenden Sie NIE einen Skriptblock - { ... } - , um ein -Filter -Parameter-Argument, für beliebiges Cmdlet zu erstellen .

    • Es funktioniert nur in sehr begrenzten Situationen - siehe unten.
    • Es gibt den falschen Eindruck, dass der Filter ein PowerShell -Code ist, was er nicht ist (er unterstützt nur einige Operatoren, deren Verhalten sich teilweise von ihren PowerShell-Gegenstücken unterscheidet - siehe Get-Help about_ActiveDirectory_Filter ).
  • Verwenden Sie IMMER eine Zeichenfolge , um ein -Filter -Parameter-Argument zu erstellen, weil der tatsächliche Typ des Parameters [string]

Der korrekte und robuste Ansatz besteht darin, eine Zeichenfolge zu erstellen

  • Jedes Argument, das Sie an -Filter übergeben, wird sowieso zuerst in eine Zeichenfolge umgewandelt, vor wird jedoch an das Cmdlet Get-ADUser übergeben, weil% Der Parameter "co_de%" hat den Typ -Filter - über alle Cmdlets, die diese Parameter unterstützen. Überprüfen Sie mit [string]

  • Bei Get-ADUser -? ist es im Allgemeinen das Cmdlet , diese Zeichenfolge unter Verwendung einer domänenspezifischen Sprache zu interpretieren, die häufig wenig gemeinsam hat mit PowerShell .

    • Im Falle von -Filter ist diese domänenspezifische Sprache (Abfragesprache) in Get-ADUser

Verwenden Sie PowerShell Zeichenfolgeninterpolation (oder String-Verkettung aus Literalen und Variablenreferenzen / -ausdrücken), um beliebige Variablenreferenzen in die Zeichenfolge / em>, nach vorne .

Die folgenden Befehle funktionieren beispielsweise alle und sind funktional gleichwertig. Sie verwenden verschiedene PowerShell -Techniken, um die Zeichenfolge mit Variationen in den Anführungszeichen und im Escape-Zeichen zu erstellen:

%Vor%

Der wichtige Teil besteht darin, sicherzustellen, dass Get-Help about_ActiveDirectory_Filter vor dem -Ersatz (ersetzt durch seinen Wert) erweitert wird, entweder über eine Zeichenfolge in doppelten Anführungszeichen $SamAc oder durch explizite Zeichenfolgenverkettung ( "..." ).

Wenn + $SamAc + ... zum Beispiel $SamAc enthält, übergibt die obige Anweisung eines der folgenden (äquivalenten) Literale an jdoe :

%Vor%

Wenn Sie einen Skriptblock angeben - was Sie vermeiden sollten :

Wenn ein Skriptblock in eine Zeichenfolge konvertiert wird, führt dies dazu, dass der literale Inhalt zwischen -Filter und { - keine Variablenerweiterung (Interpolation) stattfindet:

%Vor%

Daher wird literal } an sAMAccountName -eq "$SamAc" übergeben.

Get-ADUser , in einem fehlgeleiteten Versuch, die Skriptblock-Syntax zu unterstützen / mehr PowerShell-ähnlich, unterstützt die Referenzierung einer Variablen nicht-quoted - Beachten Sie das Fehlen von Get-ADUser around " :

%Vor%

Dh, $SamAc hat eine eigene, Powershell- wie Interpretation der Zeichenkette literal Get-ADUser : genauso wie Sie kein Variable Referenz in sAMAccountName -eq $SamAc in einem PowerShell-Ausdruck (z. B. "..." ), Sie müssen hier auch nicht - und tatsächlich darf nicht , wie der Versuch des OP belegt scheitern.

Diese Emulation eines regulären PowerShell-Skriptblocks ist jedoch nicht nur verwirrend - weil Benutzer immer noch annehmen, dass sie Anführungszeichen enthalten müssen - aber auch halbgebacken und daher spröde :

  • Es funktioniert nicht mit Eigenschaftenverweisen oder Methodenaufrufen :

    %Vor%
  • Es funktioniert nicht mit implizit remoting Modulen , weil die Variable auf der entfernten Maschine erweitert wird.

Die Quelle der Skriptblock-Verwirrung

Während:

Mit einer Ausnahme verwenden die Beispiele nur Literale , in denen das Problem nie auftaucht.Diese eine Ausnahme (zum jetzigen Zeitpunkt) ist:

%Vor%

Dieses Beispiel funktioniert - es verwendet eine einfache Variablenreferenz ohne Anführungszeichen - aber aufgrund der Wahl eines Nicht-String -Wertes ist niemand versucht, fälschlicherweise Anführungszeichen in zu verwenden Fall - anders als beim Vergleich von string Feldern.

Die Syntax des Skriptblocks ist verführerisch und praktisch , weil das Zitieren einfacher wird: Sie brauchen kein verschachteltes Zitieren.
Aus allen genannten Gründen sollte dies jedoch vermieden werden.

    
mklement0 25.05.2017 15:56
quelle
10

Das hat mich ein bisschen gebissen, als ich anfing, mit dem ActiveDirectory-Modul zu arbeiten, und es war ein Schmerz, es herauszufinden.

Der Parameter -Filter für die ActiveDirectory-Modul-Cmdlets sucht tatsächlich nach einer Zeichenfolge. Wenn Sie {sAMAccountName -eq "$SamAc"} als Wert verwenden, sucht es tatsächlich nach "sAMAccountName -eq ""'$SamAc"""

Grundsätzlich analysiert Powershell den Parameter und wandelt seinen Wert in eine Zeichenfolge um und interpoliert die Variable nicht. Versuchen Sie, die Zeichenfolge vor der Hand zu erstellen, und es sollte funktionieren.

In etwa so:

%Vor%     
Joseph Alcorn 19.11.2013 19:13
quelle
2

Ich muss dazu etwas sagen, weil es mich wirklich verärgert hat, das zu klären.

Joseph Alcorn hat die richtige Idee. Der Filterparameter nimmt eine Zeichenfolge und bewertet diese dann, um den Filter zu verarbeiten. Was die Leute davon in die Irre führt, ist die Option, geschweifte Klammern anstelle von {} zu verwenden, und das funktioniert nicht so, wie Sie es erwarten würden, wenn Sie Where ... verwenden würden. Es muss immer noch wie eine Zeichenfolge behandelt werden.

%Vor%

Ich empfehle, in Anführungszeichen zu bleiben, um es für Sie und andere klarer / lesbarer zu machen und mögliche Syntaxfehler zu vermeiden, oder halten Sie sich an Where {} in der Pipeline. Wenn ich dies tue, finde ich es am besten, doppelte Anführungszeichen auf der Außenseite zu verwenden. einfache Anführungszeichen auf der Innenseite, so dass Sie immer noch IntelliSense Erkennung der Variable erhalten.

    
Rob Traynere 04.12.2015 18:57
quelle
0

Entfernen Sie einfach die Anführungszeichen um Ihre Variable:

$SamAc = Read-Host 'What is your username?'

$User = Get-ADUser -Filter {sAMAccountName -eq $SamAc}

Das sollte gut funktionieren.

    
Tim 01.12.2015 18:30
quelle
0
%Vor%     
John Longmuir 14.07.2016 03:47
quelle
-1

Okay, ich habe meins, um endlich mit der folgenden Syntax zu arbeiten und benutze das folgende Beispiel von oben:

Vorher:

%Vor%

Arbeitsversion:

%Vor%

Ich musste $ ($) zu $ ​​SamAc hinzufügen, bevor PowerShell auf den Variablenstring zugreifen konnte.

Hoffentlich hilft das jemandem!

    
itmadez 30.03.2017 01:19
quelle