2009-06-26 7 views
2

Ich versuche, eine .NET (3.5) Kommandozeilen-Programm innerhalb einer VBScript-Datei auszuführen, die zwei wichtigsten Dinge tut:VBScript: WScript.Shell Mit einem Kommandozeilenprogramm auszuführen, das Active Directory Greift

  • Stellt eine Verbindung zu einem Active Directory her, das sich in derselben Domäne wie der Server befindet, auf dem das Skript gehostet wird, um einen Attributwert abzurufen. Ich suche AD mit dem ersten Befehlszeilenargument, das ein Benutzername ist.
  • Erstellt ein DTO mit diesem Attributwert und dem zweiten Befehlszeilenargument, das dann in einem WCF-Serviceaufruf verwendet wird.

Wenn ich die Anwendung explizit ausführen, funktioniert alles. Auf Active Directory wird zugegriffen, das Attribut wird abgerufen und der WCF-Dienst wird mit dem korrekten Ergebnis aufgerufen (wie durch Überprüfen der Datenbank überprüft).

(Edit:. Ich entschuldige mich, vergaß ich zu setzen, was die aktuelle Ausgabe)

Als ich das Skript ausführen, scheint es, als ob ich nicht Active Directory in meinem .NET-Code zugreifen kann (die MyProgram App).

Der VBScript-Code:

Dim objResult 

Set objShell = WScript.CreateObject("WScript.Shell")  
objResult = objShell.Run("MyProgram " & strUsername & " 0", 1, True) 

Hat das WScript.Shell Objekt spezielle Berechtigungen für die Datei benötigen? Ich habe sie überprüft und die Execute-Berechtigung ist da. Normalerweise würde das zweite Argument, das ich an die .Run() - Methode übergebe, 6 sein, ich wollte, dass es 1 für das Debugging ist.

Gibt es eine andere Möglichkeit, ein Programm in VBScript auszuführen?

+1

Es wäre hilfreich, sehr explizit anzugeben, was im fehlerhaften Fall passiert. – EricLaw

+0

Sorry, ich war so in den anderen Details gefangen, dass ich den wichtigsten vergessen habe. Der Zugriff auf AD scheint in der MyProgram-App nicht zu erfolgen. –

Antwort

1

Das Problem erwies sich als Zertifikat bezogen. Der WCF-Dienst, der von der Konsolenanwendung aufgerufen wird, verwendet ein X509-Zertifikat für die Authentifizierung, das auf den Servern installiert ist, auf denen dieses Skript gehostet und ausgeführt wird.

auf anderen Servern, in denen die gleichen Dienstleistungen verbraucht werden, wurden die Zertifikate wie folgt konfiguriert:

winhttpcertcfg.exe -g -c LOCAL_MACHINE\My -s "certificate-name" -a "NETWORK SERVICE" 

Als sie im Rahmen der IIS lief. Wenn das Skript jedoch wie in der Produktion ausgeführt wurde, befindet es sich im Kontext des Benutzers selbst. Daher musste das Skript wie folgt geändert werden:

Sobald diese Änderung vorgenommen wurde, war alles in Ordnung. Danke an alle, die Hilfe angeboten haben.

0

Wenn Sie WScript.Shell ausführen, wird es unter dem lokalen Systemkonto ausgeführt. Dieses Konto verfügt über vollständige Rechte auf dem Computer, aber keine Rechte in Active Directory.

http://support.microsoft.com/kb/278319

+0

Das Skript wird über eine gehostete Desktop-Anwendung ausgeführt (Citrix ist beteiligt). Es läuft meines Wissens sowieso nicht im Kontext von IIS. –

0

Einnahme von Shiraz Idee und es läuft ...

in Ihrer Anwendung definieren Sie explizit ein Domäne-Benutzerkonto und Passwort AD zugreifen?

Wenn Sie die Anwendung explizit ausführen, verwendet sie möglicherweise Ihre Anmeldeinformationen (Ihr derzeit angemeldetes Domänenkonto), um AD abzufragen. Beim Aufruf der Anwendung über das Skript weiß ich jedoch nicht, ob sich die Anwendung im Systemkontext befindet.

Ein VBScript-Beispiel würde wie folgt aussehen:

Dim objConnection As ADODB.Connection 
    Set objConnection = CreateObject("ADODB.Connection") 
    objConnection.Provider = "ADsDSOObject" 
    objConnection.Properties("User ID") = "MyDomain\MyAccount" 
    objConnection.Properties("Password") = "MyPassword" 
    objConnection.Open "Active Directory Provider" 

Wenn dies funktioniert, natürlich wäre es am beste Praxis zu schaffen und ein Dienstkonto speziell für diese Aufgabe zu verwenden, und auf dieses Konto interaktive Login zu verweigern .

+0

In meiner Active Directory-Dienstprogrammklasse verbinde ich mich mit einem nicht-privilegierten Konto (kann Kennwörter nicht ändern, kann aber nach Benutzern suchen). Der Name des Kontos und sein verschlüsseltes Passwort werden in der Datei app.config (oder MyProgram.exe.config) gespeichert. DirectoryEntry-Eintrag = neuer DirectoryEntry ("LDAP: // MyLDAP", "Nicht privilegiertes Konto", Entschlüsseln ("EncryptedPassword"), AuthenticationType.Secure); Das ist im Grunde, wie ich mit AD verbinden. Ich verwende dann ein DirectorySearcher-Objekt mit einem Filter für die Suche nach Benutzern. DirectorySearcher searcher = neuer DirectorySearcher (Eintrag); –

+0

In diesem Fall bin ich ratlos. Hast du getan, wie Soonts vorschlägt (unten) und Process Explorer benutzt, um tiefer zu graben? – Izzy

1

Dies ist keine Antwort (ich kann keine Kommentare), nur einige zufällige Ideen könnten hilfreich sein. Leider habe ich mich nie mit Citrix beschäftigt, sondern nur mit normalen Windows Servern.

_0. Stellen Sie sicher, dass Sie kein Opfer der Windows-Firewall oder einer anderen persönlichen Firewall sind, die Prozesse selektiv blockiert.

Fügen Sie der ersten Zeile Ihrer .NET-Anwendung 10 Minuten Sleep() hinzu, führen Sie dann sowohl die VBScript-Datei als auch Ihre eigenständige Anwendung aus, führen Sie den Process Explorer von sysinternals aus und vergleichen Sie 2 Prozesse.

_1. Gleiche Registerkarte, "Befehlszeile" und "aktuelles Verzeichnis". Stellen Sie sicher, dass sie gleich sind.

_2. Registerkarte "Umgebung" Stellen Sie sicher, dass sie gleich sind. Normalerweise erben untergeordnete Prozesse die Umgebung, aber dieses Verhalten kann leicht geändert werden.

Die folgende Überprüfung ist erforderlich, wenn durch „mein Skript ausführen“ Sie alles bedeuten sonst dann einen Doppelklick auf die VBS-Datei:

_3. Registerkarte Bild, "Benutzer". Wenn sie sich unterscheiden, kann dies bedeuten, dass der Benutzer keinen Zugriff auf das Netzwerk hat (wie bei einem lokalen System) oder ein Benutzer-Token auf Delegierung beschränkt ist und daher nur auf lokale Ressourcen zugreifen kann (wie im Fall von IIS NTLM) lokale Dateien, die es will.

+0

Danke für den Vorschlag. Ich habe den Process Explorer heruntergeladen und festgestellt, dass die Befehlszeile und die aktuellen Verzeichnisse beim Ausführen des Programms über VBScript unterschiedlich waren. Letzteres war in diesem Fall ein Laufwerk auf dem Netzwerk, das von der aufrufenden Anwendung verwendet wurde. Ich bin mir nicht sicher, ob das bedeutet, dass ich meine Anwendung von diesem Verzeichnis aus ausführen muss oder ob ich meinen Ansatz überdenken muss. –