Benutzer mit den meisten Antworten
Windows Freigabe erstellen per remot oder umc Pfad?

Frage
-
Hallo, ich versuche gerade ein kleines Programm zu schreiben womit ich Freigaben von eiem Rechner auslesen und auf einem anderen wieder einspielen kann. Das auslesen funktioniert super aber beim einlesen kann ich immer nur einen Lokalen-Pfad angeben, ich würde aber gerne per umc Pfad und oder über remote Freigaben anlegen können.
Das ist der Code den ich habe:
void QshareFolder() { //String FolderPath = @"D:\TestFreigabe"; //String ShareName = "TestFreigabe"; //String Description = "Eine Test-Freigabe"; DataTable dtFreigaben; try { // Create a ManagementClass object ManagementClass managementClass = new ManagementClass("Win32_Share"); dtFreigaben = (DataTable)dbgFreigaben.DataSource; foreach (DataRow dtRow in dtFreigaben.Rows) { // Create ManagementBaseObjects for in and out parameters ManagementBaseObject inParams = managementClass.GetMethodParameters("Create"); ManagementBaseObject outParams; // Set the input parameters inParams["Description"] = ""; inParams["Name"] = dtRow["Freigabe"]; inParams["Path"] = dtRow["LocalPath"]; inParams["Type"] = 0x0; // Disk Drive //Another Type: // DISK_DRIVE = 0x0 // PRINT_QUEUE = 0x1 // DEVICE = 0x2 // IPC = 0x3 // DISK_DRIVE_ADMIN = 0x80000000 // PRINT_QUEUE_ADMIN = 0x80000001 // DEVICE_ADMIN = 0x80000002 // IPC_ADMIN = 0x8000003 //inParams["MaximumAllowed"] = int maxConnectionsNum; // Invoke the method on the ManagementClass object outParams = managementClass.InvokeMethod("Create", inParams, null); // Check to see if the method invocation was successful if ((uint)(outParams.Properties["ReturnValue"].Value) != 0) { throw new Exception("Unable to share directory."); } } } catch (Exception ex) { //MessageBox.Show(ex.Message, "error!"); } }
Kann mir jemand einen Tipp oder etwas in der Richtung geben ich komme einfach nicht mehr weiter.
Für Hilfe bin ich sehr Dankbar und hoffe auf Hilfe.
Gruß Olli
Antworten
-
Sind diese beiden Methoden nicht theoretisch das selbe von der Funktionalität her?
ManagementClass managementClass = new ManagementClass("Win32_Share"); ManagementScope Scope = new ManagementScope(@"\\.\root\cimv2"); Scope.Connect();
undstring computer = "Computer_B"; string domain = "DOMAIN"; string username = "AdminUserName"; ... // create Session using computer, SessionOptions CimSession Session = CimSession.Create(computer, SessionOptions);
das kann ja schon per Definition nicht das gleiche sein. Mit dem ersten Code greifst Du auf den lokalen Rechner zu, auf dem das Skript läuft, mit dem zweiten auf einen anderen Rechner.
Das ist auch der Grund, warum Du bei letzterem die Benutzerangaben brauchst. Der Prozess mit den Anmeldedaten des aktuelle angemeldeten Benutzers ausgeführt. Lokal hat der ausreichende Rechte, aber eben wohl nicht auf dem anderen PC bzw. kann hier ggfs. keine automatische Anmeldung per NTLM verwendet werden.
Letztendlich kannst Du den Code für die Erstellung der Freigaben so beibehalten, wie Du ihn hast. Nur muss das die Win32_Share.Create Methode eben nicht lokal, sondern über die Remote WMI Verbindung auf Srv2 aufgerufen werden.
Der Einfacheit halber würde ich das mit:
ManagementScope scope = new ManagementScope("\\\\Srv2\\root\\cimv2", options); scope.Connect();
machen, wie auch im Beispiel des MSDN Artikels zu sehen.
Ein vollständiges Beispiel für den Aufruf von Win32_Share.Create inkl. Möglichkeit, zu einem Remoterechner zu verbinden, findest Du in der Doku zur Win32_Share Klasse.
private static void makeShare(string servername, string filepath, string sharename) { try { // assemble the string so the scope represents the remote server string scope = string.Format("\\\\{0}\\root\\cimv2", servername); // connect to WMI on the remote server ManagementScope ms = new ManagementScope(scope); // create a new instance of the Win32_Share WMI object ManagementClass cls = new ManagementClass("Win32_Share"); // set the scope of the new instance to that created above cls.Scope = ms; // assemble the arguments to be passed to the Create method object[] methodargs = { filepath, sharename, "0" }; // invoke the Create method to create the share object result = cls.InvokeMethod("Create", methodargs); } catch (SystemException e) { Console.WriteLine("Error attempting to create share {0}:", sharename); Console.WriteLine(e.Message); } }
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Montag, 27. August 2018 07:57
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Dienstag, 4. September 2018 11:29
Alle Antworten
-
Hallo Olli,
willst Du jetzt auf dem Quellrechner die Freigaben auslesen, die dieser Rechner selbst für andere bereitstellt oder die Remotefreigaben auf diesem PC, die auf Netzwerkfreigaben eines Servers, ... verweisen?
Eine normale Freigabe, die auf dem PC selbst angelegt wird, muss meines Wissens nach immer auf einen lokalen Ordner zeigen. (Zumindest bei Client Betriebssystemen). Daher weiß ich nicht so genau, was Du eigentlich machen willst.
Beschreib doch mal ein konretes Beispiel mit Angabe aller PCs, die involviert sind.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Bearbeitet Stefan FalzModerator Donnerstag, 23. August 2018 16:30
-
Okay, ich hab mich vielleicht ein wenig unklar ausgedrückt, also ich mach mal ein Beispiel:
Ich befinde mich auf einem Server (ich nenne Ihn mal Srv1).
Srv1 hat eine remote Verbindung zu Server 2 (Srv2).
Auf Srv1 lese ich die Freigaben aus und möchte sie unmittelbar danach auf Srv2 nachbilden.
Mit dem Code den ich oben gepostet habe kann ich ja wie auch von dir schon erwähnt nur mit einem lokalen Pfad arbeiten.
-
Hi,
das sind dann aber nicht die Win32_Shares. Das wären die Freigaben, die Srv1 selbst bereitstellt.
Wenn Du von Srv1 aus die verwendeten Netzlaufwerke auslesen willst, geht das bspw. so (hab grad nur ein VBScript Beispiel hier, es sollte aber in etwa klar sein, was das Skript macht und die Übertragung auf .NET sollte kein größeres Problem sein):
Dim WmiTarget Dim WmiService Dim Collection Dim Item WmiTarget = "." Set WmiService = GetObject( "winmgmts:\\" & WmiTarget & "\root\CIMV2" ) Set Collection = WmiService.ExecQuery( "SELECT * FROM Win32_MappedLogicalDisk" ) For Each Item in Collection Wscript.Echo "Drive letter: " & Item.DeviceID Wscript.Echo "Network Path: " & Item.ProviderName Next Set Collection = Nothing Set WmiService = Nothing
Mit WMI selbst kannst Du meines Wissens nach kein Netzlaufwerk erstellen. Dafür kannst Du aber WScript.Network verwenden.
Dim Network Dim RemoteShare Set Network = CreateObject( "WScript.Network" ) RemoteShare = "\\server\share" Network.MapNetworkDrive "X:", RemoteShare, True, "User", "Password" Set Network = Nothing
HTH
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Bearbeitet Stefan FalzModerator Donnerstag, 23. August 2018 16:59
-
Falls ich dich falsch verstanden habe und Du willst schon die lokalen Freigaben auf Srv1 selbst auslesen und die dann remote auf Srv2 anlegen: Das geht so nicht. Für die Anlage musst Du dich mit WMI auf Srv2 verbinden und dann dort den lokalen Pfad auf Srv2 angeben.
In meinem VBScript Beispiel müsstest Du dafür WmiTarget "." mit "Srv2" ersetzen.
Für ein .NET Beispiel schau mal in diese MSDN Artikel (Berechtigungen für die Zugriffe musst Du natürlich haben):
Connecting to WMI Remotely with C#
Connecting to WMI on a Remote Computer
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport
- Bearbeitet Stefan FalzModerator Donnerstag, 23. August 2018 17:01
-
Das ist genau was ich möchte. Sofort die freigegebenen Order auslesen und wieder erstellen auf einem anderen Server.
Ich hab mir alles durchgelesen aber mir wird eine Sache nicht ganz klar. Sind diese beiden Methoden nicht theoretisch das selbe von der Funktionalität her?
ManagementClass managementClass = new ManagementClass("Win32_Share"); ManagementScope Scope = new ManagementScope(@"\\.\root\cimv2"); Scope.Connect();
und
string computer = "Computer_B"; string domain = "DOMAIN"; string username = "AdminUserName"; string plaintextpassword; Console.WriteLine("Enter password:"); plaintextpassword = Console.ReadLine(); SecureString securepassword = new SecureString(); foreach (char c in plaintextpassword) { securepassword.AppendChar(c); } // create Credentials CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default, domain, username, securepassword); // create SessionOptions using Credentials WSManSessionOptions SessionOptions = new WSManSessionOptions(); SessionOptions.AddDestinationCredentials(Credentials); // create Session using computer, SessionOptions CimSession Session = CimSession.Create(computer, SessionOptions);
Oder versteh ich das falsch. Seltsam kommt mir vor das bei der ersten Methode keine Login Daten etc. verwendet werden müssen
-
Ich habe gerade einen Beitrag gefunden der ebenfalls sagt das das wohl die gleiche funktion erfüllt aber die cimSession wohl moderner ist. Aber ich versteh jetzt nicht wie ich die Freigabe erstelle.
Mit
CimSession Session = CimSession.Create(computer, SessionOptions);
habe ich zwar jetzt die Verbindung aber zu meinem Remote Computer aber soetwas kann ich ja damit nicht machen :
outParams = managementClass.InvokeMethod("Create", inParams, null);
Also mein Problem ist jetzt gerade das ich nach dem erstellen der Session nicht weiß wie ich weiter vorgehen muss :|
-
heißt das "CimSession.Create" quasi sofort eine verbindung herstellt und diese quasi "öffnet" und ich dannach einfach schon in etwa so weiter arbeiten kann? :
ManagementClass managementClass = new ManagementClass("Win32_Share"); ManagementBaseObject inParams = managementClass.GetMethodParameters("Create"); ManagementBaseObject outParams; // Set the input parameters inParams["Description"] = ""; inParams["Name"] = ""; inParams["Path"] = ""; inParams["Type"] = 0x0; // Disk Drive outParams = managementClass.InvokeMethod("Create", inParams, null); // Check to see if the method invocation was successful if ((uint)(outParams.Properties["ReturnValue"].Value) != 0) { thro
Oder ich laufe gerade total in eine gedankliche Sackgasse...
weil in meinem oberen Code mach ich das ja auch quasi so:
ManagementScope Scope = new ManagementScope(@"\\.\root\cimv2"); Scope.Connect(); dtFreigaben = (DataTable)dbgFreigaben.DataSource; foreach (DataRow dtRow in dtFreigaben.Rows) { // Create ManagementBaseObjects for in and out parameters ManagementBaseObject inParams = managementClass.GetMethodParameters("Create"); ManagementBaseObject outParams;
Hier wird ja auch ein Scope.Connect gemacht und danach bin ich ja mit dem Rechner/Server "verbunden" oder? Funktioniert das in etwa so wie ich mir das gerade vorstelle ?
- Bearbeitet Olli_Olli Donnerstag, 23. August 2018 21:15
-
Sind diese beiden Methoden nicht theoretisch das selbe von der Funktionalität her?
ManagementClass managementClass = new ManagementClass("Win32_Share"); ManagementScope Scope = new ManagementScope(@"\\.\root\cimv2"); Scope.Connect();
undstring computer = "Computer_B"; string domain = "DOMAIN"; string username = "AdminUserName"; ... // create Session using computer, SessionOptions CimSession Session = CimSession.Create(computer, SessionOptions);
das kann ja schon per Definition nicht das gleiche sein. Mit dem ersten Code greifst Du auf den lokalen Rechner zu, auf dem das Skript läuft, mit dem zweiten auf einen anderen Rechner.
Das ist auch der Grund, warum Du bei letzterem die Benutzerangaben brauchst. Der Prozess mit den Anmeldedaten des aktuelle angemeldeten Benutzers ausgeführt. Lokal hat der ausreichende Rechte, aber eben wohl nicht auf dem anderen PC bzw. kann hier ggfs. keine automatische Anmeldung per NTLM verwendet werden.
Letztendlich kannst Du den Code für die Erstellung der Freigaben so beibehalten, wie Du ihn hast. Nur muss das die Win32_Share.Create Methode eben nicht lokal, sondern über die Remote WMI Verbindung auf Srv2 aufgerufen werden.
Der Einfacheit halber würde ich das mit:
ManagementScope scope = new ManagementScope("\\\\Srv2\\root\\cimv2", options); scope.Connect();
machen, wie auch im Beispiel des MSDN Artikels zu sehen.
Ein vollständiges Beispiel für den Aufruf von Win32_Share.Create inkl. Möglichkeit, zu einem Remoterechner zu verbinden, findest Du in der Doku zur Win32_Share Klasse.
private static void makeShare(string servername, string filepath, string sharename) { try { // assemble the string so the scope represents the remote server string scope = string.Format("\\\\{0}\\root\\cimv2", servername); // connect to WMI on the remote server ManagementScope ms = new ManagementScope(scope); // create a new instance of the Win32_Share WMI object ManagementClass cls = new ManagementClass("Win32_Share"); // set the scope of the new instance to that created above cls.Scope = ms; // assemble the arguments to be passed to the Create method object[] methodargs = { filepath, sharename, "0" }; // invoke the Create method to create the share object result = cls.InvokeMethod("Create", methodargs); } catch (SystemException e) { Console.WriteLine("Error attempting to create share {0}:", sharename); Console.WriteLine(e.Message); } }
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Montag, 27. August 2018 07:57
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Dienstag, 4. September 2018 11:29