Jump to content

BOfH_666

Expert Member
  • Gesamte Inhalte

    2.046
  • Registriert seit

  • Letzter Besuch

Alle erstellten Inhalte von BOfH_666

  1. Es gibt mehrere Möglichkeiten, so eine Authenticator App zu benutzen - z.B. kann man sich einen Zahlencode erzeugen lassen. Das ist dann das gleiche wie ein Hardware-Token ... nur eben in Software. Oder man lässt den Authentifizierungsprovider (MS) beim Smartphone anfragen, ob eine gerade anstehende Autorisierung genehmigt werden soll. Das ist etwas komfortabler, da man auf dem Phone nur noch - nach Entsperrung (gegebenenfalls mit Fingerabdruck) - bestätigen muss. Aber das Smartphone verbindet sich nicht mit dem Firmennetz. Aber wenn's sooo spezielle Anforderungen gibt, isses dann vielleicht nix für Euch.
  2. Du kannst die MS Authenticator App (oder auch viele andere Authenticator Apps) verwenden. Da wäre dann - ein entsprechendes Smartphone vorausgesetzt - die Biometrie auch gleich dabei. ... funktioniert sehr gut. PS: Das Handy geben wohl noch die wenigsten einfach aus der Hand.
  3. Geänderte Ausgangsbedingungen haben natürlich eine andere Bewertung zur Folge. Aber von mehr als einem Gerät war bisher in diesem Thread noch nicht die Rede.
  4. ... und ... funktioniert das gut? Ich würde erwarten, dass Anwender, die kein Problem damit haben, ihren Account weiterzugeben, auch kein Problem damit haben, diese Weitergabe aktuell zu halten - also das neue Passwort auch wieder weiterzugeben.
  5. Parameter -SearchScope. Bitte die Hilfe benutzen! Get-Help Get-ADUser -Full Get-ADUser
  6. Du präferierst also für ein einzelnes Gerät in Deiner Infrastruktur eine "Sonderlocke"? Obwohl Du es auch mit einem normalen W10-Client, z.B. ein Mini-PC wie ein NUC, machen könntest? Ich vermute mal, dass Du für die Windows-Geräte eine Strategie hast, sie auf dem Laufenden zu halten und zu pflegen und zu warten usw.. Du kennst Dich einigermaßen damit aus und kannst auch vermutlich Probleme beseitigen, die evtl. auftreten. Jetzt möchtest Du diese Vorteile über Bord werfen für eine OpenSource-Lösung, mit der Du keine Erfahrung hast, die Du separat patchen musst und bei der Du, falls es mal Probleme gibt, nicht auf Deine Erfahrung zurückgreifen kannst. Und Du kannst sie im Zweifel auch nicht mal schnell gegen ein Ersatzgerät austauschen, weil Du nur dieses eine hast. Und das im Zweifel in einer Situation, in der Kunden im Meeting-Raum sitzen und ein Kollege etwas präsentieren möchte - es also eilt. .... Du hast meinen Respekt - das finde ich eine sehr tapfere Einstellung.
  7. Das hängt am Ende des Tages ja immer davon ab, wem Du damit Deine Befähigung nachweisen möchtest. Wenn derjenige es als Befähigungsnachweis akzeptiert, hast Du gewonnen.
  8. Da gibt es noch eine weitere Option, die Du bisher offenbar nicht mal in Betracht ziehst. Welche bessere Gelegenheit kann es geben, ein System abzuschaffen, das die Aufgabe, für die es erdacht wurde, sowieso nicht zuverlässig erfüllt und dazu auch noch mehr Arbeit macht als es spart. Die Empfehlung, Passwörter regelmäßig zu wechseln, haben wir dem NIST zu verdanken. Und sie stammt aus der Computer-Steinzeit. Alle weiteren Empfehlung, incl. der des BSI, basierten im Prinzip darauf. ABER, und das ist ein riesen aber - angefangen mit dem NIST, haben alle relevanten Institutionen inzwischen diese Empfehlung widerrufen. Das NIST, BSI, die englische CESG, ja selbst Microsoft empfehlen inzwischen, die Passwort-Alterung zu deaktivieren, weil sie die Sicherheit nicht erhöht sondern verringert. Wenn Du dafür "Futter" für Deine Chefs oder die Administratoren oder den CSO oder CIO brauchst, brauchst Du nur danach zu suchen - Du wirst sehr schnell fündig werden. (Ich könnte auch nochmal auf die Suche gehen, wenn Dir das hilft. Also, statt wahnsinnig große Umstände zu veranstalten, die User dazu zu bewegen, ihr Passwort regelmäßig zu ändern, solltet ihr die User schulen, ein sicheres Passwort zu wählen, welches sie so lange behalten können, bis es den begründeten Verdacht gibt, dass dieses spezielle Passwort kompromittiert wurde.
  9. So lange Dein Arbeitgeber keinen Wert drauf legt und Du Dich nicht verändern möchtest, geht's wohl auch ohne. Wenn aber z.B. firmenintern ein Benefit daran hängt, oder Du für einen zukünftigen Arbeitgeber nachweisen möchtest, dass Du entsprechende Kenntnisse erworben hast, macht's wohl Sinn, denke ich.
  10. Bei uns heisst die Powershell Property mobile bzw. mobilePhone. Pick Dir doch einfach einen User raus und lass Dir ALLE Properties anzeigen. So bekommst Du den richtigen Namen raus. Also Get-ADUser -Identity <sAMAccountName des einzelnen Users> -Properties * In der produktiven Abfrage solltest Du übrigens nicht -Properties * benutzen, sondern -Properties cn,otherMobile,mobile,telephoneNumber. Also nur die Attribute, die Du brauchst. Die Properties in Powershell heißen nicht zwingend genau so wie die Attribute im AD. Teilweise gibt es nicht mal entsprechende Attribute im AD, sondern das cmdlet Get-ADUser baut im Hintergrund noch was für Dich zusammen.
  11. Kann sein, dass ich jetzt Unsinn rede, aber wenn Du noch ausrangierte PCs hast, die Du dafür verwenden könntest, würden die denn so intensiv genutzt werden, dass sich der Energie-Mehrverbrauch gegenüber einem Thin-Client so stark auswirkt, dass dabei die Kosten für einen extra Thin-Client rausspringen? Nimm doch einfach den alten Windows-PC. Der braucht ja nicht wirklich viel zu leisten.
  12. Powershell 7 ist noch nicht wirklich "production ready", auch wenn Microsoft das gern anders darstellt. PSSnapins sind eigentlich schon seit v3.0 deprecated, werden aber noch als Legacy Support bis v5.1 unterstützt. v5.1 wird auch nach bisherigen Stand zwar nicht weiterentwickelt, aber bis auf unbestimmte Zeit von MS weiter unterstützt werden. Für aktuelle Versionen von Exchange gibt es die Erweiterung als Modul. Wenn Du aber z.B. aufwändige Skripte erstellt hast, die auf die Snapins angewiesen sind, spricht nichts dagegen, die Windows Powershell und die Snapins weiterzubenutzen. Legacy Support. Mehr braucht's doch nicht. MS supported ja gern mal die ein oder andere Technologie länger als man sich's wünschen mag.
  13. Nee, siehste, das is mir glatt durchgerutscht. Gut, dass Du nochma rübergeguckt hast.
  14. Cool. Ein Fehler weniger. Du erzeugst Dein "Menü" mit Write-Host. Damit ist das Menü vom eigentlichen Code völlig unabhängig. Das sind nur Pixel auf Deinem Bildschirm ohne weitere Funktion. Wichtig ist der Code, den Du benutzt, um die Eingabe des Benutzers auszuwerten. Davon hast Du aber bisher nur ein paar lose miteinander verbundene Schnipsel gezeigt. Damit kann ich leider nicht wirklich sehen, was Du in Deinem Code machst. Aber nicht, wenn Du das switch-Statement bereits einmal erfolgreich durchlaufen hast. Dafür müsstest Du die Auswahl erneut erhalten - also das switch-Statement erneut ausführen - mit einer Schleife zum Beispiel. ... es sei denn, ich habe Dich falsch verstanden. ... kommt immer mal wieder vor ... Vielleicht machst Du Dir einfach mal ein MockUp. Also ein Script-Gerüst, welches den Script-Ablauf zeigt, ohne die eigentlichen Funktionen auszuführen. So könntest Du die Menü-Struktur testen, ohne den Balast des Codes der Funktionen mitzuschleppen. Das macht es manchmal einfacher. Dann hast Du in Deinen externen Scripten irgendwo einen logischen Fehler. Hast Du eventuell im der Script-Datei mit der Funktionsdefinition für MyBenutzer, die Funktion MyBenutzer direkt aufgerufen? Edit: Hier mal ne kleine Demo: $Menu = @' Hauptmenue ================================================== 1 : Benutzerverwaltung 2 : Gruppenverwaltung -------------------------------------------------- 0 : zurück ================================================== '@ Clear-Host Write-Host $Menu function show-input { param ( $BenutzerEingabe ) "`n `t$BenutzerEingabe`n " } $Eingabe = Read-Host -Prompt "Bitte Zahl zwischen 1 und 5 eingeben " switch ($Eingabe) { 1 { show-input -BenutzerEingabe "Du hast wohl ne '1' eingegeben " } 2 { show-input -BenutzerEingabe "Du hast wohl ne '2' eingegeben " } 3 { show-input -BenutzerEingabe "Du hast wohl ne '3' eingegeben " } 4 { show-input -BenutzerEingabe "Du hast wohl ne '4' eingegeben " } 5 { show-input -BenutzerEingabe "Du hast wohl ne '5' eingegeben " } Default { show-input -BenutzerEingabe "Das muss irgendwas Anderes als 1 bis 5 gewesen sein!" } } } Nachdem Du etwas Beliebiges an der Eingabeaufforderung eingegeben hast, wird das switch-Statement genau 1 mal durchlaufen und dann beendet.
  15. ... und es sollte natürlich auch nicht heißen, dass Du hier nicht mehr fragen darfst ... auch zu diesem Thema/Script - jederzeit - dafür sind wir alle hier. Es macht uns ja auch selber Spaß
  16. OK. Als erstes hast Du ihn Deinem MyMain einen Klammerfehler im switch-Statement. Das sollte so aussehen: Function MyMain { #Hauptmenue cls Write-Host Write-Host "Hauptmenue" Write-Host "==================================================" Write-Host "1":" Benutzerverwaltung" Write-Host "2":" Gruppenverwaltung" Write-Host "--------------------------------------------------" Write-Host "0":" EXIT" Write-Host "==================================================" $input = Read-Host "Auswahl" Switch ($input) { 0 { exit } 1 { . $m_benutzer MyBenutzer } 2 { . $m_gruppen MyGruppen } 3 { MyMain } DEFAULT { exit } } } MyMain Darf ich fragen, welchen Code-Editor Du benutzt? Sowohl die Powershell_ISE als auch VSCode würden diesen Syntaxfehler entsprechend markieren. ... oder ist das nur ein Copy-&-Paste-Fehler hier im Forum? Jetzt wo die Klammern stimmen, solltest Du, auch wenn es vielleicht im Moment funktioniert, dringend die Variable $Input ändern. $Input ist eine für Powershell reservierte Variable, die nicht für eigene Zwecke benutzt/missbraucht werden sollte, Hmm ... das switch-Statement wird von oben nach unten abgearbeitet. Wenn Du die Option 1 wählst, bist Du über die 0 schon drüber. Das kann also nicht funktionieren. ... und der Default-Zweig wird nur ausgeführt, wenn keine der zur Verfügung stehenden Optionen passt. Wenn Du immer wieder in Dein Hauptmenü zurück möchtest, wirst Du eine while oder do Schleife benutzen müssen. Es macht übrigens nicht wirklich viel Sinn, die "extenen" Scripte erst mittels dot-Sourcing in Dein Hauptscript einzubinden, wenn der entsprechende Menüeintrag gewählt wird. Einfacher wäre es, wenn Du am Anfang Deines Scriptes einfach mittels: Get-ChildItem $PSScriptRoot -Filter *.ps1 | ForEach-Object { . $_.FullName } alle weiteren Funktionen in den Scope Deines Hauptscriptes importiertest. Somit brauchst Du im Code nur noch mit den Funktionsnamen zu arbeiten. Damit wären wir beim nächsten Thema: Funktionsnamen. Wenn Du irgendwann mal Deine Scripte in Module umwandelst und diese vielleicht auch an Kollegen weitergeben möchtest, empfiehlt es sich, besonders für Funktionen, die direkt aufgerufen werden sollen, die gleiche Schreibweise zu benutzen, wie bei den eingebauten cmdlets - also <Verb>-<Nomen>. Das macht im Zweifel ihre Funktion direkt erkennbar und erleichtert das Verstehen und Debuggen. Empfehlenswerte Lektüre dazu ist The Unofficial PowerShell Best Practices and Style Guide.
  17. Yep ... zeig uns bitte den relevanten Code. ... ohne diesen, wird es bestenfalls "Raten auf hohem Niveau"! Edit: Nur schon mal als Tipp, wenn das vielleicht ein Projekt ist, welches Du in Zukunft ausbauen möchtest. Du könntest Dir die Arbeit erleichtern, wenn Du die Anzeige Deines Menüs etwas weniger statisch gestalltest: $TaskList = @( 'Benutzerverwaltung' 'Gruppenverwaltung' ) $Index = 1 $IndexedTaskList = foreach ($Task in $TaskList) { [PSCustomObject]@{ Index = $Index Task = $Task } $Index++ } Clear-Host "`n`n`tAuswahl des Tasks:`n " $IndexedTaskList | Format-Table -AutoSize -HideTableHeaders Das mag für 2 auszuwählende Tasks etwas überkandidelt erschienen, aber wenn Dein Projekt wächst, wirst Du es vermutlich zu schätzen wissen.
  18. Für alle Powershell-Nutzer, die mit VSCode unterwegs sind ... ... ich könnte gut mir vorstellen, dass das über kurz oder lang auch in der Powershell landet (natürlich nur v7 oder höher )
  19. Schau mal hier: https://gpsearch.azurewebsites.net/
  20. Möglichst bitte nicht so lange warten! ... das Wochenende steht vor der Tür ... und wir sind wegen Corona sowieso eingeschränkt ... warum nicht die Zeit sinnvoll nutzen? Soll das heißen, Du glaubst, dass ich meine Kenntnisse aus diesen beiden Quellen erhalten habe? ... Du bist ja putzig ... sagen wir einfach "Ich mache das schon lange genug, um ein wenig Erfahrung angehäuft zu haben.". "kleines bisschen Feinschliff"??? Du krempelst grade die Anforderungen um. Das hätte alles in Deine erste nachricht gehört. Fällt Dir wenigstens auf, dass Du hier die Anforderungen Stück für Stück erweiterst? 1. Was ist der Unterschied zwischen *.pdf und *.pdf. Das hast Du zwei mal. 2. Das hängt davon ab, ob Du während der Ermittlung der zu kopierenden Ordner danach suchen möchtest, oder ob Du nur die Dateien beim Copy-Job mit einschließen möchtest. Dann einfach bei robocopy ein weiteres "Datei-Muster" angeben. 3. Das lernst Du auch mit den Grundlagen von Powershell - wie die Hilfe zu lesen und zu verstehen ist. Die Hilfe ist übrigens in der Powershell eingebaut. Du kannst für jedes cmdlet in der Konsole oder in der ISE oder in VSCode einfach mit "Get-Help <cmdlet>" die Hilfe aufrufen. Hmmm ... bitte möglichst nicht falsch verstehen, aber ich glaube, das ist die Stelle, an der ich darum bitte, dass Du diese Erweiterungen selbst einbaust, sobald Du genug Powershell-Kentnisse erworben hast, um das alleine zu machen - wenigstens zum größten Teil. Angefangen hast Du - jedenfalls hab ich es so verstanden - mit PDF-Dateien in "B01_"-Ordnern, jetzt sind noch JPG-Dateien dazu gekommen - kein Problem - kannst Du bei robocopy einfach mit einschließen. Jetzt kommen aber noch "A01_"-Odner und PDF-Dateien dazu - die aber nur wenn sie mit "LF-" oder "BE-" anfangen .... Man kann so ein Script natürlich beliebig komplex gestallten. Aber je komplexer es wird, desto fehlerträchtiger und schwerer zu pflegen wird es auch gern mal. Dann kommen Wechsel- oder Nebenwirkungen dazu, die häufig sehr schwer zu ermitteln und zu beseitigen sind. Eventuell wird auch die Leistung/Verarbeitungsdauer beeinflusst. Du hattest am Anfang beschrieben, dass es um ca. 10TB an Daten in ca. 1000 Projekt-Ordnern mit den entsprechenden Unterordnern geht. Powershell ist, wenn es um Dateisytem-Operationen geht, nicht die beste (weil ziemlich langsame) Option, die man wählen kann. Deshalb ist auch robocopy immer wieder das Mittel der Wahl, weil es um Größenordnungen schneller ist. Wenn Du jetzt aber die Powershell benutzt, um quasi jede einzelne Datei zu identifizieren und robocopy dann fast nur noch einzelne Dateien kopieren soll, dann ist der Geschwindigkeits-Vorteil dahin und das Script läuft am Ende vielleicht so lange, dass es gar nicht rechtzeitig fertig wird. Vielleicht schaust Du erstmal, wie sich das Script, was Du bis jetzt hast, in der Praxis bewährt. Und in kurzer Zeit hast Du genug Powershell gelernt und kannst es entweder erweitern oder einfach ein zweites bauen, mit leicht angepassten Bedingungen.
  21. Nee ... wir werden doch jetzt nicht anfangen, Pfade oder Laufwerksbuchstaben im Code hart zu verdrahten ... ich hätte vielleicht dazusagen sollen: "Pfoten weg von meinem Code! " ... nicht meinen Code anpassen - eigenen ergänzen. Dieser Teil hier: $QuellPfad = 'C:\Quelle\Desktop\Kopier-Skript\Test\Quelle' $ZielPfad = 'C:\Ziel\Desktop\Kopier-Skript\Test\Ziel' $OrdnerSuchMuster = '\\B\d{2}_' $PotenzielleBackupOrdnerListe = Get-ChildItem -Path $QuellPfad -Directory -Recurse | Where-Object { $_.FullName -match $OrdnerSuchMuster } | ForEach-Object { $DateiSuchMuster = Join-Path -Path $_.FullName -ChildPath '*.pdf' if (Test-Path -Path $DateiSuchMuster) { [PSCustomObject]@{ FullName = $_.FullName ShortName = $_.FullName -replace [REGEX]::Escape($QuellPfad) } } } ... war doch nur dazu da, zu zeigen, wie man die zu kopierenden Ordner ermittelt und die Pfade entsprechend aufbereitet. Die damit erzeugte Liste $PotenzielleBackupOrdnerListe können wir dazu benutzen, den Zielpfad zusammenzubauen und den Copy-Job anzustoßen: foreach ($PotenzielleBackupOrdner in $PotenzielleBackupOrdnerListe) { $KopierZielPfad = Join-Path -Path $ZielPfad -ChildPath $PotenzielleBackupOrdner.ShortName "Quelle : '$($PotenzielleBackupOrdner.FullName)' - Ziel: '$($KopierZielPfad)'" # Robocopy.exe $PotenzielleBackupOrdner.FullName $KopierZielPfad *.pdf } Die robocopy-Zeile ist noch auskommentiert. Wenn Du geprüft hast, ob die ausgegebenen Pfade zu Deinen Anforderungen passen, kannst Du das "#" vor robocopy entfernen. ... trotzdem nochmal mit Test-Daten und Test-Pfaden testen bitte!! Wenn dann mit den Test-Daten alles wie gewünscht funktioniert, brauchst Du nur noch die Variablenzuweisungen vom Anfang des Codes anpassen und es passt auch für die produktiven Daten. Doch, aber dann musst Du diesen auch angeben. Wie Martin schon erwähnte, ist $PotenzielleBackupOrdnerListe ein Array von Objekten mit Eigenschaften. Es gäbe zwar Möglichkeiten, das so zu bauen, dass sich Copy-Item die richtige Eigenschaft aus dem Object rauspickt, aber wir wollen ja sowieso robocopy benutzen. Und das kann damit eben nicht umgehen. Also müssen wir die entsprechende Eigenschaft der Objekte explizit angeben. Du hattest erwähnt, dass Du Dich näher mit dem Thema Scripting befassen möchtest. Das ist mit Sicherheit eine sehr gute Idee. Du solltest Dir ein bissl Zeit nehmen, um Dir die Grundlagen von Powershell draufzuschaffen. Ein guter Einstieg, wie ich finde, ist immernoch der Video-Kurs mit Jeffrey Snover: Getting Started with Powershell. Und wenn Du was zum Nachschlagen brauchst, kannst Du Dir das hier anschauen: Windows PowerShell™ 4: TFM. ... beides kostenlos.
  22. Martin, Martin Martin. CDs und DVDs hat hier grad niemand auch nur erwähnt ... außer Dir!! Und USB-Sticks oder USB-Platten sind im Hochtechnologie-Land-Deutschland (leider) noch lange nicht aus der Mode. Auf dem flachen Brandenburger Land bist Du froh, wenn Du DSL-Light oder 16Mbit-DSL bekommst. Mit Glück hast Du dann eine hoffentlich stabile Upload-Bandbreite von vielleicht 2MBit. Darüber möchtest auch Du kein Backup in die Cloud schieben. Und es gibt auch noch Leute, die "der Cloud" nicht oder nur sehr eingeschränkt vertrauen und lieber etwas in der Hand haben, was sie wegtragen und einschließen können. ... wie gesagt ... kein Business - private Privat-Patienten. Wir leben halt nicht in der besten aller Welten, sondern in dieser ....
  23. ... klingt gut ... nicht für mich ... eher für meine "Privatpatienten".
  24. Um dieses unglaublich unsägliche Gefrickel mit Laufwerksbuchstaben völlig zu umgehen, kann man - auch in Windows - einen angeschlossenen USB-Datenträger in einem leeren Verzeichnis "mounten". Dieser Pfad bleibt für ein gegebenes USB-Speichermedium immer der Gleiche - auch bei z.B. baugleichen Medien desselben Herstellers. Ich hab z.B. im Root von C: einen leeren Ordner USB in dem ich dann die jeweiligen gerätespezifischen Unterordner erstelle. Bei USB-Sticks verwende ich dann gern "beschreibende" Namen wie ItensoGreen8GB oder SndskCrzrEdge16GB oder so ... Edit: ... noch vergessen ... das Ganze funktioniert natürlich mit Bordmitteln!!
  25. Da ist schon Deine Einstellung falsch. Das ist kein Problem, sondern eine Herausforderung. Fast. Get-ChildItem liefert mit den angegebenen Parametern ALLE Ordner, aus denen dann mittels Where-Obejct die Ordner herausgefiltert werden, in deren Pfad das Suchmuster auftaucht. Bis hierhin noch keine Schleife ... nur Pipeline. Jetzt kommt die Schleife mit Foreach-Object. Darin wird erstmal das Datei-Suchmuster aus dem kompletten Pfad des aktuellen Ordners und des Datei-Musters zusammengebaut. Das wird dann mit Test-Path benutzt, um zu prüfen, ob der aktuelle Ordner PDF-Dateien enthält. Wenn ja, wird das aktuell in der Pipeline befindliche Objekt ausgegeben und damit in der Variablen $PotentielleBackupOrdner gesammelt. Der nächste Teil ist ein bissl knifflig. Ich gehe mal davon aus, dass Du nicht wirklich den ganzen Pfad im Ziel wiederhergestellt haben willst, sondern nur den Teil der nach Deinem $QuellPfad kommt. Wir müssen also den kompletten Pfad um den "Anfangs-Pfad" kürzen. $PotenzielleBackupOrdner = Get-ChildItem -Path $QuellPfad -Directory -Recurse | Where-Object {$_.FullName -match $SuchMuster} | ForEach-Object { $DateiSuchMuster = Join-Path -Path $_.FullName -ChildPath '*.pdf' if (Test-Path -Path $DateiSuchMuster) { [PSCustomObject]@{ FullName = $_.FullName ShortName = $_.FullName -replace [REGEX]::Escape($QuellPfad) } } } $PotenzielleBackupOrdner Wir benutzen den -replace Operator um den Teil des Pfades zu entfernen, der dem $QuellPfad entspricht. -replace arbeitet mit regulären Ausdrücken. Deshalb müssen wir alle Zeichen, die in regex als "spezielle" Zeichen gelten "escapen". So ... kannst ja schon mal probieren, den Ziel-Pfad zusammen zu bauen ... ich komm nachher wieder ...
×
×
  • Neu erstellen...