flashpixx Geschrieben 1. Januar 2014 Teilen Geschrieben 1. Januar 2014 Hallo, zunächst einmal ein gutes neues Jahr. Ich habe folgendes Problem, ich möchte ein Powershell Script erstellen, was einen User auf einem Rechner anlegt, dazu das Homeverzeichnis und in diesem dann ein Javaprogramm ablegt, welche als Dienst ausgeführt wird. Für mich ist die Powershell aktuell neu, da ich aus der Unixwelt komme. Mein aktueller Ansatz sieht so aus: # Script muss mit mehr Rechten ausgeführt werden "Set-ExecutionPolicy RemoteSigned" # Parameter sind Benutzername und Jenkins Secret Key Param([Parameter(Mandatory=$true)][string]$Username, [Parameter(Mandatory=$true)][string]$Secret) # Prüfung, ob der User aktuell Administratorrechte besitzt #If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) #{ # Write-Error("Administratorrechte sind notwendig") # Break #} # Prüfe ob Java installiert ist $javafound = $false $keys = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall $items = $keys | Foreach-Object { Get-ItemProperty $_.PsPath } foreach($item in $items) { if ($item.DisplayName -like "Java *") { $javafound = $true break } } if (!$javafound) { Write-Error("Java wurde nicht gefunden, bitte installieren!") Break } # Serverobjekt erzeugen, um Zugriff auf den lokalen Rechner zu erhalten [ADSI]$server = "WinNT://$(get-content env:computername)" # erzeuge User mit zufälligem Passwort, wobei der User das Passwort nicht ändern kann und es nicht abläuft, # prüfe ob User erst existiert und lege danach HomeDir an $localUsers = $server.Children | where {$_.SchemaClassName -eq 'user'} | foreach {$_.name[0].ToString()} foreach($item in $localUsers) { if ( !$Username.CompareTo($item) ) { Write-Error("Benutzername $Username existiert bereits!") } } $chars = [Char[]]"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@$%&/()=?" $pass = ($chars | Get-Random -Count 16) -join "" #$userhome = "\\$(get-content env:computername)\Home$\$Username" $user = $server.Create( "User", $Username) $user.Put( "Description", "Jenkins Slave User Account" ) $user.SetPassword( $pass ) $user.UserFlags = 64 + 65536 $user.SetInfo() Das Script soll sowohl auf einem Windows Desktop System laufen, ebenso wie auf einem Server OS. Ich scheitere aktuell daran, dass ich nicht weiss, wie ich das Userhomeverzeichnis erstellen kann. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 2. Januar 2014 Teilen Geschrieben 2. Januar 2014 Hi flashpixx, geht es dabei ausschließlich um lokale Benutzer oder auch um Domänen benutzer? Willst du den Ordner manuell anlegen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 2. Januar 2014 Teilen Geschrieben 2. Januar 2014 noch was: denk dran, dass du das $ im $userhome string escapen musst mit '`', sonst versucht er variablen zu finden, die es nicht gibt ;-) Anmerkung: Die ExecutionPolicy hat nichts mit rechten zu tun, es geht dabei um die Überprüfung, ob scripte signiert werden müssen (Code Signing)... und muss bei jedem System angepasst werden, wenn die Scripts nicht signiert sind. Kann aber ganz leicht umgangen werden, es handelt sich dabei also nicht um einen schutz. Desweiteren reicht deine Prüfung auf die Admin Rolle nicht aus, beispielsweise bei delegierten Rechtemodellen bzw. der UAC versagt das ganze schon, du musst also sicher gehen, dass die Shell elevated gestartet wurde oder eben aus der aufrufenden shell selber eine elevated shell erzeugen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 2. Januar 2014 Autor Teilen Geschrieben 2. Januar 2014 Vielen Dank für die Fragen. geht es dabei ausschließlich um lokale Benutzer oder auch um Domänen benutzer? Mir reicht ein lokaler User, da nicht jeder Rechner zwingend in einer / der Domäne sein muss, d.h. ich möchte, dass der User unter dem der Dienst läuft immer nur lokal existiert. Willst du den Ordner manuell anlegen? Ja, ich möchte ersten den lokalen User erzeugen, danach möchte ich das Homeverzeichnis unter C:\Users anlegen, dafür dann die passenden Owner & Rechte setzen (der User muss in dem Verzeichnis Schreibrechte haben), in das Homeverzeichnis lade ich dann mit $file = "c:\User\<Username>\slave.jar" $webclient = New-Object System.Net.WebClient $webclient.DownloadFile( "https://meinserver.de/jenkins/jnlpJars/slave.jar", $file ) meine Jar Datei, die aber nicht von dem User überschrieben werden darf und zum Schluss möchte ich dann folgendes CL-Kommando als Dienst hinterlegen: java -jar c:\Users\<Username>\slave.jar -jnlpUrl https://meinserver.de/jenkins/computer/<Name>/slave-agent.jnlp -secret <Secret Key> <Parameter fürs Logging> Dazu direkt die Frage: Ist mein gedachtes Vorgehen sinnvoll? noch was: denk dran, dass du das $ im $userhome string escapen musst mit '`', sonst versucht er variablen zu finden, die es nicht gibt ;-) Danke für den Hinweis, das hatte ich vergessen Anmerkung: Die ExecutionPolicy hat nichts mit rechten zu tun, es geht dabei um die Überprüfung, ob scripte signiert werden müssen (Code Signing)... und muss bei jedem System angepasst werden, wenn die Scripts nicht signiert sind. Kann aber ganz leicht umgangen werden, es handelt sich dabei also nicht um einen schutz. Mir geht es nur darum, dass ein User ohne Probleme das Script ausführen kann und nicht erst viel an Berechtigungen erstellen muss. Der User soll das Script ausführen und dort alle benötigten Infos eingeben, das Script meldet dann entweder, dass man als User nicht die notwendigen Rechte für die Konfig hat oder es legt die Daten wie oben beschrieben an. Desweiteren reicht deine Prüfung auf die Admin Rolle nicht aus, beispielsweise bei delegierten Rechtemodellen bzw. der UAC versagt das ganze schon, du musst also sicher gehen, dass die Shell elevated gestartet wurde oder eben aus der aufrufenden shell selber eine elevated shell erzeugen. Es soll kein Schutz sein, sondern ich möchte wenn das Script ausgeführt wird, zuerst prüfen, ob der User der das Script startet alle benötigten Rechte hat. Meines Wissens brauchte ich für das Erzeugen des Homeverzeichnisses und der Dienstekonfiguration lokale Adminrechte. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 2. Januar 2014 Teilen Geschrieben 2. Januar 2014 Das api für lokale Benutzer ist bei Windows traditionsgemäß eher mist. Trotzdem muss man ja irgendwie damit leben.... Was den Homefolder angeht würde ich dir folgenden Artikel empfehlen: Creating a Home Drive with Windows PowerShell: Part 3 - Hey, Scripting Guy! Blog - Site Home - TechNet Blogs Entsprechend wenn ein user das nicht überschreiben soll, die ACL wegnehmen. Was brauchst du denn noch, bzw. was fehlt dir? Was die Execution Policy angeht: Okay, dann sollten die Leute, die das script nur entsprechend wissen wie sie mit der Execution Policy umgehen müssen. Ist für viele immer noch ein Hindernis. Prüfung auf die Admin Rolle: Es ging mir mehr darum, dass auch der User "administrator" nicht in der Rolle "administrator" ist, wenn die UAC aktiviert ist und der Prozess nicht elevated ist. Das bedeutet du solltest direkt sicherstellen, dass du dich in einem elevated kontext befindest oder alternativ direkt innerhalb deines scripts eine neue shell elevated starten und dann durch den nutzer bestätigen lassen. Ist dein Vorgehen sinnvoll? Nun ja, es ist zumindest Lösungsorientiert. Wären es meine Server würde ich ein paar Sachen anders machen. Ich würde solche Dinge in einem separaten Ordner auf einer nicht Systempartition laufen lassen, so dass man bei einer Migration oder einer Serverinstallation dass ganze nicht vergisst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 2. Januar 2014 Autor Teilen Geschrieben 2. Januar 2014 [...] dass du dich in einem elevated kontext befindest oder alternativ direkt innerhalb deines scripts eine neue shell elevated starten und dann durch den nutzer bestätigen lassen. Kannst Du mir dafür ein Beispiel geben? Ist dein Vorgehen sinnvoll? Nun ja, es ist zumindest Lösungsorientiert. Wären es meine Server würde ich ein paar Sachen anders machen. Ich würde solche Dinge in einem separaten Ordner auf einer nicht Systempartition laufen lassen, so dass man bei einer Migration oder einer Serverinstallation dass ganze nicht vergisst. Nein, das ist hier anders, es geht hier nicht um einen Server. Ich möchte es einem Entwickler, der immer lokale Adminrechte auf seinem Rechner hat, ermöglichen diese Rechner unserem Jenkins Master hinzuzufügen. Nur möchte ich den Jenkins Slave als Dienst in einem eigenen Bereich des Rechners laufen lassen. Bei einer Migration entsteht kein Problem, denn es müssen keine Daten migriert werden. Somit würde der User einfach das PS-Script erneut ausführen. Es ist so angedacht, dass wir bei der Installation eines Rechners automatisch in unserem Jenkins Master (Linux System) eine neuen Eintrag für den Rechner einfügen, der per Default "ruhend" ist. Der User des Rechners entscheidet dann ob er den Rechner zur Verfügung stellt. Dafür braucht er eben einen Secret-Key und den Namen des Rechners. Damit es nun für den User einfach ist, möchte ich ein Script zur Verfügung stellen, bei dem man nur die Daten eingeben muss und der Rechner wird dann passend konfiguriert. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 2. Januar 2014 Teilen Geschrieben 2. Januar 2014 Das Beispiel ist simpel, den Code, den du zum testen brauchst, hast du schon... der Garantiert dir zwar nicht, dass das script mit admin rechten gestartet wurde, aber wenn es das nicht wurde, dann zeigt er es dir an :-) Ich würde das ganze also so angehen: ich würde zunächst den Check von oben auf Admin rechte machen, wenn der false ist, mittels folgendem snippet, die powershell.exe mit deinem script erneut aufrufen function sudo { $file, [string]$arguments = $args; $psi = New-Object System.Diagnostics.ProcessStartInfo $file; $psi.Arguments = $arguments; $psi.Verb = "runas"; $psi.WorkingDirectory = Get-Location; [system.Diagnostics.Process]::Start($psi) >> $null } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Pixelfuchs Geschrieben 4. Januar 2014 Teilen Geschrieben 4. Januar 2014 Hallo, für die Execution Policy hast du die nachfolgenden Lösungsmöglichkeiten: 1. Die Execution Policy für alle Benutzer manuell anpassen (Set-ExecutionPolicy) oder per Gruppenrichtlinie 2. In der Poershell kann man die Ausführungsrichtlinien auch nur für den aktuelle Sitzung festlegen. Hierfür muss die powershell.exe mit zusätzlichen Parametern aufgerufen werden: powershell.exe -ExecutionPolicy Unrestricted - File <Skriptdatei> Ich mache es in der Praxis so, dass ich eine CMD-Datei mit dem obigen Aufrufl anlege. Mit runas könntest du es vielleicht sogar hinbekommen, dass ganze unter Adminberechtigungen laufen zu lassen. mfg Hendrik232 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.