Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

SID des angemeldeten Benutzers auslesen und in Variable (in Batch) setzen.

Frage Entwicklung Batch & Shell

Mitglied: evinben

evinben (Level 2) - Jetzt verbinden

12.07.2012, aktualisiert 24.07.2012, 9728 Aufrufe, 29 Kommentare

SID per Batch auslesen

Hallo,

ich versuche SID des angemeldeten Benutzers in Batch auszulesen und in einer Variable zu setzen, damit ich mit dieser den Pfad zum Papierkorb
Laufwerk:\$Recycle.Bin\S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx
ergänzen kann und generell für andere Zwecke in der Zukunft. Ich habe zwar ein VB-Skript, welches mit alle SID anzeigt bzw. anhand der angegebenen SID den Benutzernamen, allerdings sollte die Ausgabe in Batch sein.

Wäre es möglich die SID direkt mit Batch auszulesen oder nur über Umwege mit VBS? Das Letzere wäre natürlich auch eine vollständige und akzeptable Lösung.

Vielen Dank euch.

Gruß
evinben
29 Antworten
Mitglied: DerWoWusste
12.07.2012 um 14:11 Uhr
Moin.

Ich kenne in Batch nur das Kommandozeilentool user2sid hierfür.
http://evgenii.rudnyi.ru/soft/sid/sid.txt
Kompilierte Versionen gibt es merkwürdigerweise vom Autor nicht mehr, aber Google findet einige.
Bitte warten ..
Mitglied: ColdZero89
12.07.2012, aktualisiert um 14:21 Uhr
Moin,

wenn du ein VBS hast das dir die SID ausließt, lass das VBS doch in Batch entstehen und von Batch ausführen, so kannst du dann die allgemeinen Variablen in batch und in VBS nutzen und die ausgabe der SIDs dann in eine TXT datei o.ä. schreiben lassen.

Gruß Zero

P.S.: Poste dein VBS doch mal hier, dann kann ich mein gelerntes Wissen (durch bastla haha) auch mal nutzen ;)

Ich nutze diese Variante ja selbst in einigen Batches wie du in meinen schon gestellten Fragen sicherlich siehst.
Bitte warten ..
Mitglied: bastla
12.07.2012 um 14:50 Uhr
@DWW
Es gibt ja fast nix, was es bei SysInternals nicht gibt ...

Grüße
bastla
Bitte warten ..
Mitglied: bastla
12.07.2012 um 14:52 Uhr
@ColdZero89
... wobei es ja kein Problem ist, auch ein VBScript aus dem Batch aufzurufen und die (mit "WScript.Echo" erzeugte) Ausgabe zu übernehmen - schematisch etwa:
for /f "delims=" %%i in ('cscript //nologo "C:\Utils\GetSID.vbs"') do set "SID=%%i"
Grüße
bastla
Bitte warten ..
Mitglied: ColdZero89
12.07.2012, aktualisiert um 15:04 Uhr
... wobei es ja kein Problem ist, auch ein VBScript aus dem Batch aufzurufen und die (mit "WScript.Echo" erzeugte)
Ausgabe zu übernehmen - schematisch etwa:

DAS wusste ich nun bisher nicht, dennoch finde ich die Variante "All in One" am ende schöner, somit kann man das script theoretisch hin und her schieben. (sofern Pfadangaben dann nicht absolut sind sondern relativ)

Aber so frisch ich mein wissen halt weiter auf ;P

Gruß Zero

P.S. was heißt eigentlich immer Delims? und ja die schöne Funktion For /? habe ich genutzt - kapier nur den kleinen satz wenig xD

"Gibt einen Satz von Trennzeichen an. Diese ersetzen die Standardtrennzeichen TAB und Leerzeichen."
HEIßT? was solls bewirken? ^^
Bitte warten ..
Mitglied: evinben
12.07.2012, aktualisiert um 15:03 Uhr
Hallo DerWoWusste,

externe Tools gibt es sicherlich viel und fast bei Microsoft (PsGetSid von Sysinternals: http://technet.microsoft.com/de-de/sysinternals/bb897417.aspx).
Danke dennoch.
Die Variante von ColdZero89 werde ich bevorzugen, da der Batch auf mehreren PCs werkeln wird.


hallo ColdZero89,

und die ausgabe der SIDs dann in eine TXT datei o.ä. schreiben lassen.
OK. Dann werde ich den vbs-Schnipsel im Batch einbauen. Verratest du bitte wie die vb-Ausgabe in txt-Datei (in dem gleichen Arbeitsverzeichnis unbedingt) erfolgen soll?
(Im Batch wäre dies mir soweit klar: echo kukuk >tmp.txt)

Anbei ist der vbs-Schnipsel:
01.
'This set it to the local Machine 
02.
'	strComputer = "." 
03.
'Use a Network Computer Name here or it IP Address to run on a Network Computer 
04.
'	strComputer = "COMPUTER_NAME OR IP_ADDRESS_HERE" 
05.
 
06.
 
07.
Option Explicit 
08.
 Dim ColItems, ObjItem, Sid, strComputer, Wmi 
09.
 strComputer = "." 
10.
  Set Wmi = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")  
11.
  Set ColItems = Wmi.ExecQuery("SELECT * FROM Win32_UserAccount",,48)  
12.
   For Each ObjItem in ColItems  
13.
        Sid = Sid & _ 
14.
         "SID " & vbTab & objItem.SID & vbCrLf &_ 
15.
         "Name" & vbTab & objItem.Name & vbCrLf & vbCrLf 
16.
   Next 
17.
  MsgBox Sid, 0 + 32, "Sid Values"
dann kann ich mein gelerntes Wissen (durch bastla haha)
Kein haha ;). Der Man (oder die Frau?) hat echt viel Wissen.

Gruß
evinben
Bitte warten ..
Mitglied: ColdZero89
12.07.2012, aktualisiert um 15:24 Uhr
Moin,

in die Batch baust du das sos ein
01.
set "%S%=%temp%\SID_auslesen.vbs" 
02.
 
03.
> "%S%" echo 'This set it to the local Machine  
04.
>> "%S%" echo '	strComputer = "."  
05.
>> "%S%" echo 'Use a Network Computer Name here or it IP Address to run on a Network Computer  
06.
>> "%S%" echo '	strComputer = "COMPUTER_NAME OR IP_ADDRESS_HERE"  
07.
>> "%S%" echo Option Explicit  
08.
>> "%S%" echo Dim ColItems, ObjItem, Sid, strComputer, Wmi  
09.
>> "%S%" echo strComputer = "."  
10.
>> "%S%" echo  Set Wmi = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")   
11.
>> "%S%" echo  Set ColItems = Wmi.ExecQuery("SELECT * FROM Win32_UserAccount",,48)   
12.
>> "%S%" echo   For Each ObjItem in ColItems   
13.
>> "%S%" echo        Sid = Sid & _  
14.
>> "%S%" echo         "SID " & vbTab & objItem.SID & vbCrLf &_  
15.
>> "%S%" echo         "Name" & vbTab & objItem.Name & vbCrLf & vbCrLf  
16.
>> "%S%" echo   Next  
17.
>> "%S%" echo  MsgBox Sid, 0 + 32, "Sid Values" 
18.
 
19.
cscript //nologo "%S%"
(ich hab ne böse vermutung da is mir irgendwo nen fehler unterlaufen und bastla rügt mich gleich )

Du musst nun nur noch die Ausgabe gegen Gesetzte Variable tauschen und diese dann, wie du es gesagt hast mit echo in eine Datei schreiben.

Die Variablen rufst du in VBS mit "%VARIABLE%" auf.

Ich hoffe soweit ist alles richtig mir im Kopf geblieben ^_^ ansonsten bastla? Berichtige mich wenn ich was falsches erzählt/geschrieben habe.

Gruß Zero

P.S.: Ja bastla is nen Genie! (Egal ob Mann oder Frau - Hut ab ^-^)
Bitte warten ..
Mitglied: bastla
12.07.2012, aktualisiert um 18:29 Uhr
Hallo ColdZero89!

Rügen werde ich Dich sicher nicht, aber wenn die Ausgabe in den Batch (und / oder in eine Datei) soll, besser wie oben angesprochen "WScript.Echo" anstelle von "MsgBox" ...

... dann funktioniert nämlich zB auch
cscript //nologo "%S%">SID.txt
Für die Weiterverarbeitung würde es sich aber anbieten, SID und Name ohne zusätzliche Angaben in einer Zeile auszugeben, etwa:
WScript.Echo objItem.SID & vbTab & objItem.Name
wobei das Trennzeichen natürlich kein TAB sein muss ...
Übrigens zu "for" und "delims": Es gibt hier doch ein so schönes Tutorial ...

Grüße
bastla

P.S.: Bin keine "bastlarine", nehme die Blumen aber trotzdem gerne an ...
Bitte warten ..
Mitglied: rubberman
12.07.2012 um 23:37 Uhr
Hallo Zusammen!

@evinben

Falls dir WMIC zur Verfügung steht, wäre auch dies möglich:
01.
@echo off &setlocal 
02.
for /f %%i in ('WMIC USERACCOUNT Where "Name='%username%'" Get SID /value') do ( 
03.
  for /f %%j in ("%%i") do set "%%j" 
04.
05.
 
06.
echo %SID% 
07.
pause
Grüße
rubberman
Bitte warten ..
Mitglied: ColdZero89
13.07.2012, aktualisiert um 11:02 Uhr
Moin,

Ah gut dann war soviel nicht Falsch, nur wieder zu kurz gedacht das man einige befehle sich einfach sparen kann und zusammenpacken kann.

Gruß Zero

P.S.: ALso dann doch lieber Bier oder nen schöner Wein? (Weiß ja nicht in welchem Alter du bist)
Bitte warten ..
Mitglied: evinben
13.07.2012, aktualisiert 22.07.2012
Hallo ColdZero89,

danke dir für deine Bereitschaft mir zu helfen.
P.S. was heißt eigentlich immer Delims?...
delims kommt von Delimeter und heißt auf Deutsch Trennzeichen. Wenn du diesen Parameter weg lässt, dann ist das standardmäßige Trennzeichen in der FOR-Schleife das Leerzeichen (SPACE) und/oder das TAB-Zeichen. Wenn du allerding eine txt-Datei bearbeiten möchtest, in welcher folgendes auf einer Zeile steht
01.
ColdZero89|Tel=123,Bastla|Tel=007,evinben|Tel=noch kein
und du möchtest alle Kontakte voneinander trennen (also die Tokens in Variablen abfangen) dann benutzst du gerne den Parameter delims, z. B. so:
01.
for /f „delims=,“ %%d in (KontakteKommagetrennt.csv) do echo %%d &echo %%d>>KontakteUntereinander.txt
Hoffe es ist dir nun etwas verständlicher geworden. Der Beitrag von Friemler ist einfach spitze, den habe ich mehrmals gelesen und kann nur weiter empfehlen.

Hallo bastla,

bin keine "bastlarine",…
Das klingt ja gar nicht schlecht. Der Tipp mit der VB-Ausgabe wird sicherlich eine Anwendung bald finden.


Hallo rubberman,

ich wusste es doch, dass es mit WIMC gehen müsste und daher bin sehr froh für deinen Tipp!
Der Trick mit
01.
for /f %%j in ("%%i") do set "%%j"
und genauer hier mit set "%%j", um die bestehende Ausgabe SID= gleich als neuer Variablen-Name zu benutzen, ist sehr raffiniert.
Der Befehl Set erfordert normalerweise einen Namen vor dem Gleichheitszeichen, also wie folgt: set SID=%%j
(nur set "%%j" sah es für mich irgendwie auf dem ersten Blick falsch aus
Ich vermute, dass es nur daher mit der abgekürzten SET-Schreibweise geht, da in der WMIC-Ausgabe ein Gleichheitszeichen vorhanden ist. Stimmt es?

Vielen Dank euch allen!
Projekt abgeschlossen.

Gruß
evinben
Bitte warten ..
Mitglied: rubberman
13.07.2012 um 18:31 Uhr
Hallo evinben.

Die zweite FOR /F Schleife wäre für die meisten Verarbeitungen einer Befehlsausgabe so unnütz wie ein Kropf. Die Ausgabe von WMIC ist jedoch (abhängig von der Version) in Unicode. Daran verschluckt sich die CMD einmal kräftig und spuckt einen verunglückten Zeilenumbruch (<CR><CR><LF>) aus. Eine erneute Verwurstung dieser Ausgabe in der 2. Schleife beseitigt diesen Fehler.

Und ja, der Inhalt von %%j wird expandiert bevor der SET Befehl ausgeführt wird. Somit kommt das '=' im Wert zum Tragen.

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
14.07.2012 um 11:18 Uhr
Hallo rubberman,

Daran verschluckt sich die CMD einmal kräftig und spuckt einen verunglückten Zeilenumbruch (<CR><CR><LF>) aus. Eine erneute Verwurstung dieser Ausgabe in der 2. Schleife beseitigt diesen Fehler.

Es geht eigentlich, wenn anstatt delims=* nur der zweite Token mit tokens=2 verwendet wird
01.
for /f "delims== tokens=2" %%i in ('WMIC USERACCOUNT Where "Name='%UserName%'" Get SID /value') do (set SID=%%i) 
02.
echo %SID%
Es gibt aber ein anderes größeres Problem. Diese Batch-Datei wird nur mit Administratorrechten ausgeführt (UAC erscheint, das Administrator-Konto wird gewählt und das Passwort eingegeben). Die Umgebungsvariable %UserName% läuft also unter fremdem Kontext, nämlich des Administrators. Nun ist die große Frage:
Wie kann der Namen des wahren „aktiven“ Benutzers ausgelesen werden? Nicht der Name irgendwelcher angemeldeten anderen Benutzer, da diese ja mehrere sein können, sondern von demjenigen, der die Batch-Datei ausführt?

Zur Not lasse ich momentan am allerersten den Benutzernamen ohne Administrator-Rechten in einer TEMP-Datei ausgeben (die später von der FOR-Schleife ausgelesen wird)
01.
 if not exist tmp.txt echo %UserName% >tmp.txt
und nach der Eingabe des Passwortes wird der Batch erneut - diesmal mit Administrator-Rechten – ausgeführt und es läuft so weiter, so dass die korrekte SID ausgegeben wird.

Für jegliche Tipps, wie das Problem besser umgegangen werden könnte, wäre ich euch dankbar!

Gruß
evinben
Bitte warten ..
Mitglied: rubberman
14.07.2012, aktualisiert um 13:43 Uhr
Hallo evinben,

so ganz verstehe ich das nicht.
1. brauchst du dieses WMI Query nicht als Admin laufen zu lassen. UAC Prompt kommt auch nicht.
2. selbst wenn ich das Ding als Admin rennen lasse (mit meinem Account unter erhöhten Rechten), kommt immer noch die richtige Ausgabe.

Wenn du natürlich mit dem Adminaccount angemeldet bist (oder per RunAs) gibt es die SID des Admin Accounts. Was auch sonst?
Klar kannst du alle Accounts und die zugehörige SID als Liste bekommen, aber woher soll ein "dummes" Batchscript wissen, wer nun üblicherweise an dieser Kiste angemeldet ist? Wir haben in unserer Firma Rechner, an denen sitzen immer mal wieder andere Praktikanten. Unsere IT verpasst jedem von denen ihren eigenen Account. Mittlerweile sind da bestimmt 20 oder 30 Profile drauf... Wer ist denn da nun der User, den du benötigst? Kannst du irgend eine Regel definieren?

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
14.07.2012 um 16:31 Uhr
Hallo rubberman,

1. brauchst du dieses WMI Query nicht als Admin laufen zu lassen. UAC Prompt kommt auch nicht.
Das ist eine komplexere Batch-Datei, die nur mit Administratorrechten ausgeführt werden kann.
2. selbst wenn ich das Ding als Admin rennen lasse (mit meinem Account unter erhöhten Rechten), kommt immer noch die richtige Ausgabe.
Weil dein Benutzerkonto die Administratorrechte hat. Ausführung auf einem Benutzer ohne Administratorrechte erfordert nach UAC-Abfrage die Auswahl eines Benutzers mit erhöhten Rechten, unter welchem Kontext die Umgebungsvariablen eingelesen werden.

Wenn du natürlich mit dem Adminaccount angemeldet bist (oder per RunAs) gibt es die SID des Admin Accounts. Was auch sonst?
Die Benutzer sind nicht mit dem Administratorkonto angemeldet.

Klar kannst du alle Accounts und die zugehörige SID als Liste bekommen, aber woher soll ein "dummes" Batchscript wissen, wer nun üblicherweise an dieser Kiste angemeldet ist? Wir haben in unserer Firma Rechner, an denen sitzen immer mal wieder andere Praktikanten. Unsere IT verpasst jedem von denen ihren eigenen Account. Mittlerweile sind da bestimmt 20 oder 30 Profile drauf... Wer ist denn da nun der User, den du benötigst? Kannst du irgend eine Regel definieren?
Ja klar: derjenige Benutzer, der die Datei ausführt und das Passwort auf Vertrauen des Administrators eingibt.
Wie ich oben erwähnt habe, geht es auch mit der Ausgabe in eine txt-Datei. Da ich immer wieder lernen und alles wissen will, frage ich nach besseren Möglichkeiten nach und es klappt meistens - z. B. mit deiner Lösung mit WMIC.

Gruß
evinben
Bitte warten ..
Mitglied: rubberman
14.07.2012 um 17:20 Uhr
Hallo evinben.

Zitat von evinben:
Ja klar: derjenige Benutzer, der die Datei ausführt
Das ist ja in dem Fall der Administratoraccount, denn ausgeführt wird die Datei erst nach UAC Prompt mit Passworteingabe.

Zitat von evinben:
und das Passwort auf Vertrauen des Administrators eingibt.
Dann sollte der Admin soviel Vertrauen haben, und dem Benutzer gleich die nötigen Rechte einräumen. Das macht deutlich mehr Sinn, als sein Passwort weiter zu geben.

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
14.07.2012 um 17:42 Uhr
Hallo rubberman,

Dann sollte der Admin soviel Vertrauen haben, und dem Benutzer gleich die nötigen Rechte einräumen. Das macht deutlich mehr Sinn, als sein Passwort weiter zu geben.
Hier hast du wohl Recht. In der Praxis ist es öfter anders und da führt der Admin die Datei in der Schnelle selber aus.

OK, dann bleibt die Variante, wie es momentan ist - sie ist ebenso vollwertig.


Ein schönes Wochenende!

Gruß
evinben
Bitte warten ..
Mitglied: rubberman
14.07.2012, aktualisiert um 22:22 Uhr
Hallo evinben.

Irgend eine Möglichkeit findet sich immer
Einmal von hinten durch die Brust ins Knie:
01.
@echo off &setlocal 
02.
if "%~1" == "" ( 
03.
  for /f %%i in ('WMIC USERACCOUNT Where "Name='%username%'" Get SID /value') do ( 
04.
    for /f %%j in ("%%i") do set "%%j" 
05.
06.
  set "me=%~f0" 
07.
  set "vbs=%temp%\uac.vbs" 
08.
  setlocal EnableDelayedExpansion 
09.
    >"!vbs!" echo CreateObject^("Shell.Application"^).ShellExecute """!comspec!""", " /c ""!me!"" !SID!", "" , "runas", 1 
10.
    call "!vbs!" 
11.
    del "!vbs!" 
12.
  endlocal 
13.
  goto :eof 
14.
15.
 
16.
echo SID: %1 
17.
pause
Ganz ohne temporäres VBScript geht's diesmal nicht. Starte per Doppelklick. Der UAC Prompt kommt später.
Dort wo momentan das echo SID: %1 steht kommt der Code den du als Admin ausführen willst.

Auch ein schönes WE!

rubberman
Bitte warten ..
Mitglied: evinben
15.07.2012 um 00:37 Uhr
Hallo rubberman,

danke sehr. Mit ähnlicher Methode, über VB-Skript, werden die Bach-Dateien ausgeführt. Das temporäre VB-Skript sieht dann so aus:
01.
CreateObject("Shell.Application").ShellExecute "D:\Projekte All User\Joint all files on current direction.bat","E:\Projekte 2012\Daten 07.2012.txt D:\Projekte All User\Daten 07.2012.txt",,"runas",1
Allerdings schaffe ich immer noch nicht die übergebenen Argumente (hier im Beispiel beide Pfade zu den txt-Dateien) im Batch als zwei Argumente richtig zu empfangen, da diese nicht in Anführungszeichen stehen (ohne Anführungszeichen werden diese bedingt durch die vorhandenen Leezeichen in mehreren Argumenten zerlegt).

Etwas anders, was ich vor Kurzem heute festgestellt habe:
Alle Dateien, die in den erwähnten $Recycle.Bin-Ordner per Batch verschoben werden, werden nicht mehr für den Benutzer (mit der dazugehörigen SID) im Papierkorb im Windows Explorer angezeigt. Folgenderweise werden die Dateien in den Ordner $Recycle.Bin\%SID% verschoben:
01.
move "%FullFileName%" "D:\$Recycle.Bin\S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx" 
02.
rem oder auf dem Laufwerk C:\ 
03.
move "FullFileName%" "C:\$Recycle.Bin\S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx"
In der Eingabeaufforderung im Gegensatz werden alle diese Dateien mit dem DIR-Befehl wie folgt aufgelistet:
01.
dir /s  "D:\$Recycle.Bin\S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx"
pause >nul
angezeigt werden.

Woran könnte es liegen?

Gruß
evinben
Bitte warten ..
Mitglied: rubberman
15.07.2012 um 01:07 Uhr
Hallo evinben.

zum ersten:
CreateObject("Shell.Application").ShellExecute "D:\Projekte All User\Joint all files on current direction.bat","""E:\Projekte 2012\Daten 07.2012.txt"" ""D:\Projekte All User\Daten 07.2012.txt""",,"runas",1
In VBScript stehen Strings in Anführungszeichen eingeschlossen. Anführungszeichen innerhalb eines Strings müssen verdoppelt werden.
Willst du die umschließenden Anführungszeichen im Batch wieder entfernen, dann mit Tilde arbeiten (%~1 %~2).

zum zweiten:
So wie du denkst, liegen die Daten nicht im Papierkorb vor. Das Ding ist sicher ein Shellfolder und irgendwie virtualisiert. Ich müsste aber jetzt auch erst die Suchmaschine anwerfen ...

Grüße
rubberman
Bitte warten ..
Mitglied: rubberman
15.07.2012, aktualisiert um 17:21 Uhr
Hallo evinben.

Habe mal etwas gespielt. Also, ja, der Papierkorb ist ein Shellfolder. Mit den normalen Methoden des Filesystems kommst du nicht weit. Hier musst du dich auf VBS stützen, um mit Bordmitteln arbeiten zu können. Aber der Reihe nach ...

Auf meiner Kiste hier habe ich 2 Partitionen, C: und D:. Auf jeder Partition habe ich eine leere Textdatei erstellt und in den Papierkorb geschoben ("Neues Textdokument.TXT" auf C: und "Neues Textdokument_2.TXT" auf D: ).

Zunächst hab ich mir mal angesehen, was sich im Papierkorb befindet, und zwar mittels Batch seitens Filesystem:
*.bat
01.
dir /a /s C:\$recycle.bin\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000 
02.
echo(&echo ------------------------------------------------------------------&echo( 
03.
dir /a /s D:\$recycle.bin\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000
Ausgabe:
 Datenträger in Laufwerk C: ist Acer 
 Volumeseriennummer: 0XXX-XXXC 
 
 Verzeichnis von C:\$recycle.bin\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000 
 
16.07.2012  15:36    <DIR>          . 
16.07.2012  15:36    <DIR>          .. 
16.07.2012  15:36               544 $I9FHN32.TXT 
16.07.2012  15:35                 0 $R9FHN32.TXT 
13.04.2012  20:34               129 desktop.ini 
               3 Datei(en),            673 Bytes 
 
     Anzahl der angezeigten Dateien: 
               3 Datei(en),            673 Bytes 
               2 Verzeichnis(se), 215.856.205.824 Bytes frei 
 
------------------------------------------------------------------ 
 
 Datenträger in Laufwerk D: ist Volume 
 Volumeseriennummer: CXXX-XXX6 
 
 Verzeichnis von D:\$recycle.bin\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000 
 
16.07.2012  15:36    <DIR>          . 
16.07.2012  15:36    <DIR>          .. 
16.07.2012  15:36               544 $I36FXMR.TXT 
16.07.2012  15:35                 0 $R36FXMR.TXT 
13.04.2012  23:27               129 desktop.ini 
               3 Datei(en),            673 Bytes 
 
     Anzahl der angezeigten Dateien: 
               3 Datei(en),            673 Bytes 
               2 Verzeichnis(se), 38.474.506.240 Bytes frei
Weit und Breit nichts von den Originaldateinamen zu sehen. Dafür scheint es so dass je eine Datei beginnend mit $R existiert die die Originaldatei repräsentiert, sowie eine Datei beginnend mit $I die eine Binärdatei ist in der u. A. der ursprüngliche Pfad und Dateiname zu finden ist.
Somit sollte klar sein dass ein Verschieben einer Datei in den Papierkorb mittels Batch nicht funktionieren wird. Die Datei befindet sich dann zwar in diesem Verzeichnis, die Funktionen des Papierkorbs (angefangen bei der Anzeige im Explorerfenster, bis hin zu der Wiederherstellung der Datei) sind aber dafür nicht verfügbar.

Ergo - Shellfolder in VBScript austesten. Namespace 0x0A repräsentiert den Papierkorb des Benutzers:
*.vbs
01.
Set oShApp = CreateObject("Shell.Application") 
02.
Set oRecycler = oShApp.Namespace(&h0A) 
03.
Set colItems = oRecycler.Items() 
04.
 
05.
For Each oItem in colItems 
06.
  txt = txt & oItem.Name & vbNewLine & oItem.Path & vbNewLine & vbNewLine 
07.
Next 
08.
WScript.Echo txt
Ausgabe:
Neues Textdokument_2.TXT 
D:\$RECYCLE.BIN\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000\$R36FXMR.TXT 
 
Neues Textdokument.TXT 
C:\$Recycle.Bin\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000\$R9FHN32.TXT
Aha! Das sieht schon besser aus. Fehlt zwar die Beziehung zur $I Datei, aber egal.

Wir bekommen ja auch noch den gesamten Papierkorb (gesammelte Werke aus C: und D: ), also Probe auf's Exempel:
*.vbs
01.
Set oShApp = CreateObject("Shell.Application") 
02.
Set oRecycler = oShApp.Namespace("C:\$Recycle.Bin\S-1-5-21-4XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX2-1000") 
03.
Set colItems = oRecycler.Items() 
04.
 
05.
For Each oItem in colItems 
06.
  txt = txt & oItem.Name & vbNewLine & oItem.Path & vbNewLine & vbNewLine 
07.
Next 
08.
WScript.Echo txt
Der Witz ist, dass ich trotzdem den Inhalt des gesamten Papierkorbs bekomme und nicht nur von C:. Warum? Ich hab keine Ahnung!

However. Du versuchst ja per Script eine Datei in den Papierkorb zu verschieben. Mit:
*.vbs
01.
oRecycler.moveHere "C:\Pfad\Datei.ext"
... hatte ich Erfolg. Siehe Folder.MoveHere method

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
16.07.2012 um 12:34 Uhr
Hallo rubbermann,

Der Witz ist, dass ich trotzdem den Inhalt des gesamten Papierkorbs bekomme und nicht nur von C:. Warum? Ich hab keine Ahnung!

Das ist normal. Und wie du es oben selbst schreibst: „Da der Papierkorb ein spezieller Ordner ist…“, zeigt dieser die Inhalte verknüpfter Recycle.Bin-Ordner aller Laufwerke an, allerdings aus Sicherheitsgründen nur diejenige, die von dem Benutzer persönlich gelöscht worden sind (derjenige Benutzer muss also angemeldet sein, um seine gelöschten Dateien sehen zu können).
Schaltest du den D:\-Laufwerk aus, so werden die Inhalte, die in diesem Laufwerk physikalisch verbleiben, nicht mehr im Papierkorb neben den anderen mit angezeigt.

oRecycler.moveHere "C:\Pfad\Datei.ext"
Du bist spitze!
Namespace 0x0A repräsentiert den Papierkorb des Benutzers:
Es würde mich brennend interessieren, wie du überhaupt auf die Idee gekommen bist Namespace 0x0A zu benutzen!

Projekt abgeschlossen

Schönen Gruß
evinben
Bitte warten ..
Mitglied: rubberman
16.07.2012 um 14:06 Uhr
Zitat von evinben:
Es würde mich brennend interessieren, wie du überhaupt auf die Idee gekommen bist Namespace 0x0A zu benutzen!

Hallo evinben.

Steht alles geschrieben, man muss nur wissen wo
ShellSpecialFolderConstants enumeration

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
21.07.2012, aktualisiert 24.07.2012
Hallo rubberman,

wenn ich mit dem folgenden VB-Skript in einer Schleife alle Pfade der zu löschenden Dateien aus der temporär erstellen Text-Datei FullFileNames_tmp.txt zeilenweise einlese, werden leider keine Dateien gelöscht - der Befehl objRecycler.moveHere begleitend mit der Variable Zeile zeigt keine Reaktion.
01.
Set objWShell = WScript.CreateObject("Wscript.Shell") 
02.
Set objShellApp = CreateObject("Shell.Application") 
03.
Set objRecycler = objShellApp.Namespace(&h0A) 
04.
 
05.
'EingabePfad = "C:\Users\" 
06.
 
07.
'Bei Pfad mit Umgebungsvariable folgende Zeile benutzen 
08.
EingabePfad = objWShell.ExpandEnvironmentStrings("%TMP%\") 
09.
 
10.
EingabeDatei = "FullFileNames_tmp.txt" 
11.
 
12.
Const ForReading = 1 
13.
Const ForWriting = 2 
14.
 
15.
Set fso = CreateObject("Scripting.FileSystemObject") 'Objekt für Dateisystem erstellen 
16.
Set objEingabe = fso.OpenTextFile(EingabePfad & EingabeDatei, ForReading) 
17.
 
18.
Do Until objEingabe.AtEndOfStream 
19.
	Zeile = objEingabe.Readline 
20.
	msgbox Zeile	'Test: vollständigen Pfad zur Datei anzeigen, die gelöscht werden soll 
21.
	objRecycler.moveHere Zeile 
22.
Loop
Schreibe ich allerdings nach objRecycler.moveHere anstatt der Variable "Zeile" den Pfad zu der Datei, die gelöscht werden soll:
01.
objRecycler.moveHere "D:\Entwurf.txt"
dann geht es.
Es ist echt frustrierend… da es keine Logik ergibt, warum es nicht funktionieren soll...

Aber auch außerhalb der DO-Schleife funktioniert moveHere mit der Variable "Zeile" nicht. Annbei der Abschnitt als Einzeiler, um allen Fehler aus dem Weg zu gehen:

01.
CreateObject("Shell.Application").Namespace(&h0A).moveHere Zeile
Gruß
evinben
Bitte warten ..
Mitglied: rubberman
22.07.2012, aktualisiert um 17:23 Uhr
Hallo evinben.

Dein Script funktioniert bei mir im Test ohne Probleme. Es liegt also die Vermutung nahe dass irgendwas mit dem Inhalt der Textdatei nicht stimmt. Ich gehe davon aus, dass dir deine Zeile 20 was ausspuckt? Falls nicht, hättest du es erwähnt, hoffe ich
Nun weiß ich nicht wie die Datei aussieht oder erzeugt wird. Darum kann ich dir erst mal nur Tipps geben, wie du die Ursache heraus bekommst.
1. Du könntest deine Zeile 20 mal wie folgt ändern:
	msgbox """" & Zeile & """"
Damit wird ersichtlich, ob du Leerzeichen am Zeilenende hast o.Ä.

2. Öffne die Datei in einem HEX Editor und schau dir an in welchem Zeichensatz der Inhalt vorliegt. Vielleicht liegt es daran dass die Datei im UTF-8 oder Unicode Format gespeichert ist.

3. Schreib mal eine Datei per Hand mit dem guten alten Notepad Editor. Achte beim Speichern auf das oben Genannte. (Keine Leerzeichen am Ende, Codierung ANSI)

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
24.07.2012 um 07:55 Uhr
Hallo rubberman,

noch zwei Stunden habe ich probiert das Skript in Bewegung zu bringen, dennoch zeigt die 21. Zeile immer noch keine Reaktion. Folgendes habe ich schrittweise versucht.
1. Den Inhalt des VB-Skriptes in einer neuen TXT-Datei kopiert und als ANSI abgespeichert.
2. Alle Leerzeichen, die am Ende jeder Zeile vorhanden waren, entfernt.
3. Die Datei auf einem anderen Computer ausgeführt
4. Die TXT-Datei, welche eingelesen wird, neuerstellt und einen Pfad zu einer Datei (die gelöscht bzw. korrekter ausgedruckt in den Papierkorb verschoben werden soll) in Anführungszeichen angegeben.

Es liegt also die Vermutung nahe dass irgendwas mit dem Inhalt der Textdatei nicht stimmt. Ich gehe davon aus, dass dir deine Zeile 20 was ausspuckt? Falls nicht, hättest du es erwähnt, hoffe ich
Doch, msgbox zeigt mir den Pfad vollständig an (also ohne Leerzeichen am Anfang und am Ende der Zeichenkette – auch zusätzlich mit msgbox """" & Zeile & """" geprüft).

Wie hast du es genauer bei dir getestet, als Einzeiler ohne Variable oder lasst du wie ich eine txt-Datei mit Pfade zu Dateien, welche in den Papierkorb verschoben werden sollen, einlesen und als Variable an objRecycler.moveHere übergeben? Das letztere funktioniert bei mir definitiv nicht.
Die Pfade bestehen nur aus lateinischen Buchstaben und ich glaube keine Sonderzeichen verwendet zu haben.

Für jeden weiteren Tipp wäre ich sehr dankbar!
Eventuell lässt sich das Skript irgendwie umstrukturieren?

Schade, dass ich keine Datei hier hochladen kann, ansonsten hätte ich einfach das Skript hier hochgeladen. Der Code oben wurde aus der VB-Datei ohne Zwischenveränderung 1:1 übernommen.

Gruß
evinben
Bitte warten ..
Mitglied: evinben
24.07.2012, aktualisiert um 08:41 Uhr

GESCHAFT!


Die Pfade in der txt-Datei, welche eingelesen wird, dürfen nicht in Anführungszeichen sein!
Seltsam, da wenn der Pfad in Anführungszeichen anstatt mit Variable direkt wie folgt eingegeben wird
01.
objRecycler.moveHere "C:\user\Archiv_2010.txt"
dann funktioniert es. Der Logik nach sollte es ebenso mit einer Variablen möglich sein. Aber leider nein und an der Stelle streitet VBS.

Ähhh, so viel Zeit verschwendet. Warum machen es die VB-Designer so? Wenn ich wüsste wie, dann würde ich denen gerne einen Verbesserungevorschlag abgeben.

rubberman@ vielen Dank noch mal beim Mitschwitzen.
Ich glaube also bei dir hat es mit der Variable ebenso nicht funktioniert.

Gruß
evinben
Bitte warten ..
Mitglied: rubberman
24.07.2012 um 12:49 Uhr
Zitat von evinben:
Ich glaube also bei dir hat es mit der Variable ebenso nicht funktioniert.

Hallo evinben,

ich hatte keine umschließenden Anführungszeichen in meiner Testdatei. Hat tadellos funktioniert.

Die Anführungszeichen sind die Kennzeichnung für einen String im Quellcode, um einen String von eigentlichen Code (Variablen etc.) zu separieren. Sie sind letztlich nicht Bestandteil des Strings bei der Verabeitung der Zeichenfolge.

Grüße
rubberman
Bitte warten ..
Mitglied: evinben
24.07.2012 um 13:30 Uhr
Sie sind letztlich nicht Bestandteil des Strings bei der Verabeitung der Zeichenfolge.

OK! Das sollte eine Lehre für mich sein. Im Batch nämlich wird die Zeichenkette (der String) problemlos mit den Anführungszeichen eingelesen und unbedingt als Bestandteil in die Variable gesetzt, das Verhalten ist also andersrum: wenn die Anführungszeichen in der Variable doch nicht benötigt werden, müssen diese etwa wie
01.
set var=%var:"=%
zuerst gefiltert werden (in der FOR-Schleife oder in dem IF-Befehl dann mit %~nx usw.).

Gut, andere Zeiten, andere Sprachen.

Danke für den Tipp!

Gruß
evinben
Bitte warten ..
Neuester Wissensbeitrag
Humor (lol)

Linkliste für Adventskalender

(3)

Information von nikoatit zum Thema Humor (lol) ...

Heiß diskutierte Inhalte
Router & Routing
gelöst Ipv4 mieten (22)

Frage von homermg zum Thema Router & Routing ...

Windows Server
DHCP Server switchen (20)

Frage von M.Marz zum Thema Windows Server ...

Exchange Server
gelöst Exchange 2010 Berechtigungen wiederherstellen (20)

Frage von semperf1delis zum Thema Exchange Server ...

Hardware
gelöst Negative Erfahrungen LAN-Karten (19)

Frage von MegaGiga zum Thema Hardware ...