Hallöchen,
sitze nun schon seit geraumer Zeit an einer GUI, die mir und meinen Kollegen die tägliche Arbeit in unseren Umgebungen erleichtern soll. Bin allerdings nun an einen Punkt gekommen, wo ich absolut nicht wirklich weiterkomme und hoffe hier vielleicht den entscheidenen Hinweis zu bekommen.
Vorabinfo:
Wir betreiben eine große Infrastruktur mit 4 unterschiedlichen Domains (2x Produktiv-, 2x Test-/Intigrationsumgebung, aktuell noch AD-W2003 / Citrix / NetApp usw.) und dazugehörenden Filesystemen. In jedem Benutzerkonto sind die relevanten Pfade (User Home, Profil, Exd.-Share und TS-Profil im UNC-Format hinterlegt. Sofern ein Benutzer das Unternehmen verlässt, werden diese Pfade entsprechend entfernt, um natürlich auch keine Altlasten oder Leichen zu pflegen (bei mehr als 8000 Miatrbeitern, Auszubildenden und Praktikanten kann man sich vorstellen was für eine Fluktuation hier entsteht ). Dabei besitzt jetzt nun jedes Userkonto 4 UNC-Pfade in der Produktivumgebung (Domain1) , 4 UNC-Pfade in der Test-/Intigrationsumgebung(Domain2) die es zu entfernen gilt, wenn ich 1 Benutzerkonto lösche.
Klar, es gibt diverse 3rd Party-Anwendungen und auch diverse MS-Boardmittel mit den das ggf. eleganter (und auch Kostenintensiver) zu lösen sei - in unserem Admintrupp sind wir uns aber einig, eine eigene - massgeschneiderte - Lösung mit AutoIT sei für uns idealer. Abgesehen davon ist ja auch gerne der Weg das Ziel.
Alles gut und schön - AD-Abfragen, Gui, Prüfroutinen etc... alles weniger das Problem (mittlerweile hat uns ja echt das AutoIT-Fieber gepackt)... aber bei zwei Funktionen fährt das ganze Ding aktuell vor die Wand. -> DirGetSize als auch DirRemove.
Problem:
Mit DirGetSize (als Array-Ausgabe mit Files und Folders) eruieren wir vor dem Löschen von jedem Pfad dessen Volumen, Anzahl Dateien und Ordner um ein Log damit zu füttern (man kann ja nie wissen). In Folge käme dann ein entsprechender DirRemove. Dies funktioniert auch ohne weiteres - jedoch nur, wenn ich dieses auch in der gleichen Domain ausführe (als Domain-Admin) in der die File-Server stehen. Ziel ist es allerdings das ganze letztendlich ausschließlich auf der Produktivseite auszuführen und die entsprechende Testumgebung gleich mit abzufackeln. Zwar bestehen entsprechende Trusts zwischen den Domains, allerdings werden alle Benutzerkonten dieser beiden Domains seperat verwaltet und habe z.b auch unterschiedliche Kontennamen / Kennwörter. Auslesen der entsprechenden Pfade aus den AD-Konten war soweit auch kein Problem, jedoch werden beim Zugriff auf Fileebene entsprechende Credentials der jeweiligen Domain erwarten, die ich aktuell dem Befehl ja nicht mitgebe (oder kann). Diese sollen auch nicht auf irgendeine Weise ausgehebelt werden, das es grundsätzlich gilt beide Umgebungen strikt zu trennen (zumindest für den Otto-Normal-Benutzer).
Z.B. AD-Abfragen (u.ä.) stellen weniger das Problem dar, da die hier genutzten UDF`s (riesigen Dank hier gleich mal an Water für die grandiose AD.au3!!) die Mitgabe von Domain / Benutzername / Kennwort erlauben. Allerdings habe ich bislang keine Möglichkeit gefunden DirGetSize, als auch DirRemove in anderen Kontext laufen zu lassen, als in der des ausführenden Benutzers.
Die Frage ist nun, wie ich aus einer Domain hinaus DirGetSize (oder ggf. auch ganze andere Funktionen) auf Filesystemen eine anderen Domain zum laufen bekomme. Persönlich wäre es mir dabei am liebsten, dass ich dieses komplett in AutoIT umsetzten kann und nicht auf CMD / VBS oder Powershell angewiesen bin. Entsprechende Konten und Berechtigungen zur generellen Ausführung in allen Domains sind nicht das Thema. Wobei ich schon inbetracht gezogen habe, ein Dienstkonto dafür zu nutzen (ist aber eine andere Geschichte) - dieses jedoch ebenfalls daran scheitert, dass eine Möglichkeit her muss, um für eine andere Domain entsprechende Anmeldedaten mitgeben zu können.
Prinzipiell in ganz einfacher Art und Weise...
[autoit]
Global $DirPfadProd = "\\Server1\Profile$\UserXYZ" ; Befindet sich innerhalb Domain 1
Global $DirPfadTest = "\\Server2\Profile$\UserXYZ" ; Befindet sich innerhalb Domain 2
; folgender Passage läuft im Kontext des startenden User (Admin) in Domain 1
Func _Folder1($DirPfadProd)
Local $tmpSize = DirGetSize($DirPfadProd, 1)
Local $DirSize = "" & Round($tmpsize[0] / 1024 / 1024)
Local $DirFiles = $tmpsize[1]
Local $DirFolder = $tmpsize[2]
DirRemove($DirPfad, 1)
if FileExists($DirPfad) Then
MsgBox(0,"Meldung","Verzeichnis noch vorhanden")
Else
MsgBox(0,"Meldung",$DirSize&" MB, "&$DirFolder&" Ordner und "&$DirFiles&" Dateien wurden entfernt.")
EndIf
EndFunc
; theoretisch hier Abfrage von Benutzerdaten....?! - aber wie, damit nachfolgender Befehl diese nutzen kann?
; folgender Passage muss mit einer anderen Userkennung (Admin) in Domain 2 ausgeführt werden
Func _Folder2($DirPfadTest)
Local $tmpSize = DirGetSize($DirPfadTest, 1)
$DirSize = "" & Round($tmpsize[0] / 1024 / 1024)
$DirFiles = $tmpsize[1]
$DirFolder = $tmpsize[2]
DirRemove($DirPfadTest, 1)
if FileExists($DirPfadTest) Then
MsgBox(0,"Meldung","Verzeichnis noch vorhanden")
Else
MsgBox(0,"Meldung",$DirSize&" MB, "&$DirFolder&" Ordner und "&$DirFiles&" Dateien wurden entfernt.")
EndIf
Alle Pfade sind wie gesagt im UNC-Format hinterlegt (\\Server\Profile$\UserXYZ), jedoch kam bislang ein Mapping der Ressourcen (hier im Beispiel die Freigabe "Profile$") nicht in Frage. Das Unterverzeichnis "UserXYZ" könnte man verbinden, aber der Ordner "UserXYZ" soll ja ebenfalls gelöscht werden. Die $-Freigabe wäre im Notfall noch denkbar, jedoch müsste ich dann Berechtigungen (Konzept!) umbauen, was ich aber strikt vermeiden will. Dazu kommt, dass es sich nicht um Windows File-Server, sondern um NetAPP / EMC-Maschinen mit entsprechenden V-Filer / CIFS-Servern handelt und da schrauben wir prinzipiell nicht gerne an Berechtigungen rum . Sonst muss einer von uns noch über die Planke.... "haaaarrrrrrrr"
Gefunden habe ich in ähnlichem Bezug nur noch folgenden Ansatz (der mir jedoch noch nicht 100%ig klar ist). Eine solche Abfrage wäre völlig ausreichend... nur die Anwendung... ähm... ja...
Spoiler anzeigen
#include <APIDlgConstants.au3>
#include <Crypt.au3>
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>
#include <WinAPIDlg.au3>
Local $hBitmap = _WinAPI_LoadImage(0, @ScriptDir & '\Extras\Authentication.bmp', $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE)
Local $aData[3] = ['', '', 0]
While 1
$aData = _WinAPI_ShellUserAuthenticationDlg('Authentication', 'To continue, type a login and password, and then click OK.', $aData[0], $aData[1], 'MyScript', BitOR($CREDUI_FLAGS_ALWAYS_SHOW_UI, $CREDUI_FLAGS_EXPECT_CONFIRMATION, $CREDUI_FLAGS_GENERIC_CREDENTIALS, $CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX), 0, $aData[2], $hBitmap)
If @error Then Exit
If (StringCompare($aData[0], 'AutoIt')) Or (StringCompare($aData[1], StringEncrypt(False, 'DC7E430A1C88', '123'))) Then
If $aData[2] Then
_WinAPI_ConfirmCredentials('MyScript', 0)
EndIf
MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'You have typed an incorrect login or password, it should be "AutoIt" and "123".')
Else
If $aData[2] Then
_WinAPI_ConfirmCredentials('MyScript', 1)
EndIf
ExitLoop
EndIf
WEnd
Func StringEncrypt($bEncrypt, $sData, $sPassword)
_Crypt_Startup() ; Start the Crypt library.
Local $sReturn = ''
If $bEncrypt Then ; If the flag is set to True then encrypt, otherwise decrypt.
$sReturn = _Crypt_EncryptData($sData, $sPassword, $CALG_RC4)
Else
$sReturn = BinaryToString(_Crypt_DecryptData($sData, $sPassword, $CALG_RC4))
EndIf
_Crypt_Shutdown() ; Shutdown the Crypt library.
Return $sReturn
EndFunc ;==>StringEncrypt
Man möge verzeihen, dass meine Kollegen und ich noch AutoIT-Anfänger sind ! Bin daher für jede Idee und Rat dankbar.
Dank und Grüße
Gibbs