2017-06-21 7 views
0

Wie viele andere ist mein Hintergrund in Linux ohne Powershell-Erfahrung. Diese objektorientierte Programmierung bringt mich durcheinander.Eingabe von einer PSSession und Senden an eine andere

Ich muss VMware Horizon für VMs mit Benutzern durchsuchen, die ihnen zugewiesen sind, und dann prüfen, ob sie in AD deaktiviert sind. Wenn sie in AD deaktiviert sind, möchte ich die VM recyceln.

Im Moment habe ich die SIDs für die Benutzer von VMware Horizon bin ziehen, aber wenn ich versuche, diese in einem invoke-Kommando gegen AD ich folgende Fehlermeldung auf eine Instanz

„Objektverweis nicht gesetzt erhalten zu verwenden ein Objekt“

Das Script bisher

function getlist() { 
$temp=Invoke-Command -ComputerName $vdiserver -ScriptBlock { add-pssnapin vmware.view.broker; get-desktopvm | select user_sid } 
$list=$temp | Select-Object user_sid 
#$list 
} 
$vdi1="server1" 
$vdi2="server2" 
$test=Test-Connection -ComputerName $vdi1 -Quiet 
$test2=Test-Connection -ComputerName $vdi2 -Quiet 
if ($test -eq "True"){ 
$vdiserver=$vdi1 
getlist 
} 
elseif ($test2 -eq "True"){ 
$vdiserver=$vdi2 
getlist 
} 
else {echo "No servers to connect to"} 

ForEach ($user in $list) #{ 
#echo $user 
#sleep 1 
#} 
{Invoke-Command -ComputerName domaincontroller -ScriptBlock {param($p1) get-aduser -identity $p1 } -argumentlist $user} 
+0

bearbeiten und schließen die Fehlermeldung? Es sieht nicht so aus, als sollte es in deinem Skript passieren. – TessellatingHeckler

Antwort

0

also die objektorientierte Programmierung ist Unordnung mich.

Sie versuchen also, zum Shell-Skript zurückzukehren und doppelt so viel Code zu schreiben, um halb so viel Arbeit zu erreichen.

Das wichtigste Bit Sie fehlt sind, ein Objekt als eine Sammlung von Dingen, sich vorzustellen - wie, stellen Sie arbeiten mit /etc/passwd und jede Zeile hat eine Benutzer-ID und eine Gruppen-ID und ein Zuhause Verzeichnis und eine Login-Shell .. und Sie die gesamte Linie auf einmal übergeben, das ist Ihr analoges Objekt.

Ein Objekt hat viele Eigenschaften, genau so (aber insgesamt leistungsfähiger).

Wenn Sie Select user_sid Sie wählen dieses Feld in der 'Zeile' bleiben, aber die Zeile ist immer noch so etwas wie :::user_sid:::: mit den anderen Feldern jetzt leer. (Ca). Aber sie sind immer noch da und auf dem Weg. Um direkt damit arbeiten zu können, musst du es komplett aus der "Linie" herausholen - wirf den Container weg und hab nur die user_sid außerhalb davon.

get-desktopvm | select user_sid 

-> 

get-desktopvm | select -expandproperty user_sid 

die "sid1", "sid2", "sid3", aber keine Container für jeden SID macht.


Diese

function getlist() { 
    $temp=Invoke-Command -ComputerName $vdiserver -ScriptBlock { add-pssnapin vmware.view.broker; get-desktopvm | select user_sid } 
    $list=$temp | Select-Object user_sid 
} 

im Wesentlichen sagt

function getlist() { 
    #do any amount of work here, and throw it all away. 
} 

Da die Funktion nichts zurückgibt, und es ändert keine Daten auf der Festplatte oder irgendetwas, so dass, wenn die Funktion beendet ist, Die Variablen werden aus dem Speicher gelöscht, und Sie können sie anschließend nicht mehr verwenden.


Dieses:

if ($test -eq "True"){ 

ist ein bisschen ein Unsinn. Es könnte funktionieren, aber es funktioniert nicht wie erwartet, weil es zufällig ist, dass "eine Zeichenfolge mit Inhalt" im Vergleich zu einem booleschen True True ist, unabhängig von der Zeichenfolge, die das englische Wort "True" enthält oder nicht.Aber es ist auch redundant - $test ist selbst wahr oder falsch, Sie müssen nicht mit etwas zu vergleichen. if ($test). Oder sogar if (Test-Connection -ComputerName $vdi -Quiet)


Aber stillll, so viel Arbeit. Verbinden Sie sich einfach mit allen, und lassen Sie sie für diejenigen fehlschlagen, mit denen sie nicht in Kontakt kommen können. Fügen Sie vielleicht -ErrorAction SilentlyContinue hinzu, wenn Sie den Fehler nicht sehen möchten.

$VMs = Invoke-Command -ComputerName Server1,Server2 -ScriptBlock { 
    Add-PsSnapin vmware.view.broker 
    Get-DesktopVm 
} 

Jetzt haben Sie alle VMs, die Benutzer/deaktivierten Zustand

foreach ($VM in $VMs) { 

    $Sid = $VM.user_sid 

    $AdEnabled = Invoke-Command -ComputerName domaincontroller -ScriptBlock { 
     (Get-AdUser -Identity $using:Sid).Enabled 
    } 

    $VM| Add-Member -NotePropertyName 'AdEnabled' -NotePropertyValue $AdEnabled 

} 

Jetzt sollten Sie idealerweise $ VM als ein Array von Objekten erhalten aktiviert, die jeweils alle VM Desktop-Eigenschaften - und auch der True/False-Status der AD Enabled-Eigenschaft für dieses Benutzerkonto.

$VM | Out-Gridview 

oder

$VM | Export-Csv Report.csv 

oder

$VM | Where-Object { -not $_.AdEnabled } 
+1

Nagel auf den Kopf, ich will immer mit stdout arbeiten und meine eigene perzeptive Logik auf alles anwenden. Danke, dass Sie sich alle Mühe gegeben haben, jeden Schritt zu erklären. Der einzige Kommentar, den ich bis jetzt habe, ist, dass ich die Variable, die aus der Funktion erstellt wurde, später im Skript aufrufen kann (Sie können die kommentierten Zeilen sehen, wo ich das teste). – TurboAAA

+0

Meine nächste Frage bezieht sich auf das Testen der Serververfügbarkeit. Nehmen wir an, der erste Server antwortet, während der zweite fehlschlägt. Würde die fehlerhafte Verbindung die vom funktionierenden Server erstellte Variable nicht mit dem Fehler überschreiben? Oder erkennt Powershell, dass ein Fehler aufgetreten ist, und nimmt keine Änderungen vor, wenn dies geschieht? – TurboAAA

+0

Ich verstehe nicht, wie Ihre auskommentierten Testlinien funktionieren. Wenn Sie eine einfache Testdatei erstellen: Funktion getlist {$ list = get-childitem c: \}; getlist; $ list' und führen Sie es in einer neuen Powershell-Sitzung aus, es gibt keine Ausgabe. (Ich habe es gerade jetzt versucht). Bezüglich der Serververfügbarkeit - in meiner Version wird die gesamte Ausgabe von "Invoke-Command" beibehalten, es gibt kein Überschreiben. Jeder Server, der antwortet, geht in '$ VMs'. Wenn ein Server antwortet, erhalten Sie seine Ausgabe, wenn beide antworten, erhalten Sie ihre get-desktopvm Ergebnisse zusammen in '$ VMs'. Wenn keiner antwortet, bekommst du nichts. – TessellatingHeckler

Verwandte Themen