none
CSV-Datei auslesen, um net use Befehl aufzubauen RRS feed

  • Frage

  • Hallo zusammen,

    folgendes Problem:

    Es gibt eine per Semikolon getrennte TXT-Datei, in der Username1;Username2;Passwort;LW;Pfad stehen.

    Ich möchte nun ein Script bauen, welches mit einen Net Use Befehl aufbaut, indem die CSV nach dem Username1 (entspricht dem aktuell in Windows angemeldeten User) durchsucht wird. Für das Verbinden mit dem Laufwerk sollen dann LW, Pfad, Username2 und Passwort verwendet werden.

    Wie stelle ich das grundsätzlich an, dass mir die entsprechende Zeile gesucht wird und wie baue ich den Befehl dann auf?

    Vielen Dank schonmal!

    Philipp

    Montag, 19. September 2016 10:52

Antworten

  • > Usernamen würde ich aber gerne mitgeben. Geht das? Bzw wie?
     
    Schau Dir mal get-credential -username an :-) Und das dann in
    new-psdrive verwenden.
     
    Wenn Du es grafisch willst: $host.ui.PromptForCredential
     
    • Als Antwort markiert philbo20 Mittwoch, 28. September 2016 06:47
    Dienstag, 20. September 2016 14:12
  • Aber zu deiner Aussage "nur der User auf der Maschine". Hmm, der User wäre immer derselbe, aber die Maschine eben nicht (da Terminalserver). Dann könnte er die Datei nicht entschlüsseln bei der nächsten Anmeldung, wenn er auf nem anderen TS landet?

    Nein, das SecureString ist an den Account und an den Rechner gebunden.

    http://stackoverflow.com/questions/23699500/convertto-securestring-gives-different-experience-on-different-servers

    Doch das Mapping geht mit MapNetworkDrive, habe ich ja oben extra geschrieben wie dies zu machen ist!

    $net.MapNetworkDrive($_.LW,$Pfad,$false,$credential.UserName,$credential.GetNetworkCredential().Password)



    • Bearbeitet U333 Dienstag, 27. September 2016 12:23
    • Als Antwort markiert philbo20 Dienstag, 27. September 2016 13:02
    Dienstag, 27. September 2016 12:21

Alle Antworten

  • > Ich möchte nun ein Script bauen, welches mit einen Net Use Befehl
     
    Nein, das möchtest Du nicht. Du möchtest keine Kennwörter im Klartext
    verwenden. Du möchtest viel lieber genauer beschreiben, was Du erreichen
    willst - und dafür gibt es sicher bessere Lösungen als Klartextkennwörter.
     
    (Mit "was Du erreichen willst" meine ich nicht, daß Du ein Skript bauen
    möchtest. Was genau soll im Endeffekt erreicht werden?)
     
    Montag, 19. September 2016 10:56
  • :-)

    Diese txt-Datei ist noch eine "Altlast", in dieser stehen (für diesen Zweck) die Kennwörter und Usernamen, die in einer anderen Domäne gelten.

    Usernamen sind aber teilweise anders, als in unserer Domäne.

    Ich muss also mit unserem Usernamen den Namen der anderen Domäne suchen und dann per Net use dorthin eine LW-Verbindung aufbauen.

    Montag, 19. September 2016 11:03
  • > Ich muss also mit unserem Usernamen den Namen der anderen Domäne suchen
    > und dann per Net use dorthin eine LW-Verbindung aufbauen.
     
    Besser: Trust einrichten (notfalls mit SID-Filtering und selektiver
    Authentifizierung) und die betreffenden User "Deiner" Domäne direkt
    berechtigen.
     
    Montag, 19. September 2016 13:17
  •  Besser: Trust einrichten (notfalls mit SID-Filtering und selektiver
    Authentifizierung) und die betreffenden User "Deiner" Domäne direkt
    berechtigen.
     

    Die andere Domäne ist nicht von uns verwaltet.

    Alternativ würde ich die Verbindung ohne Kennwort herstellen, so dass der User beim ersten Öffnen gefragt wird. Also so, wie Windows es handhabt, wenn man per Hand mappt.

    Usernamen würde ich aber gerne mitgeben. Geht das? Bzw wie?

    Dienstag, 20. September 2016 05:46
  • > Usernamen würde ich aber gerne mitgeben. Geht das? Bzw wie?
     
    Schau Dir mal get-credential -username an :-) Und das dann in
    new-psdrive verwenden.
     
    Wenn Du es grafisch willst: $host.ui.PromptForCredential
     
    • Als Antwort markiert philbo20 Mittwoch, 28. September 2016 06:47
    Dienstag, 20. September 2016 14:12
  • Schau Dir mal get-credential -username an :-) Und das dann in
    new-psdrive verwenden.
     
    Wenn Du es grafisch willst: $host.ui.PromptForCredential

    Danke für den Tipp! Mit get-crediental wird das gehen.

    Allerdings kriege ich mit new-psdrive kein Laufwerk verbunden, oder besser gesagt es wird mir im Explorer nicht angezeigt, mit get-psdrive jedoch schon!

    New-PSDrive -name $LW -PSProvider FileSystem -Root $Pfad -Persist -Credential $credential

    wobei es hier egal ist, ob ich mit dem Parameter -Credential arbeite oder nicht

    Hast du einen Tipp?

    Gruß

    Philipp

    Donnerstag, 22. September 2016 06:46
  • > besser gesagt es wird mir im Explorer nicht angezeigt, mit get-psdrive
     
    Google ist nicht so Dein Ding, gell? :-))
     
    -Persist
     

    Nachtrag: Wenn Du das Credential nur einmal brauchst, kannst Du auf Get-Credential auch verzichten - New-PSDrive -Credential öffnet automatisch eine Passwortabfrage.

    Gruß, Martin

    • Bearbeitet Martin Binder Donnerstag, 22. September 2016 09:20 ....
    Donnerstag, 22. September 2016 09:05
  • Servus,

    auch wenn sich mir beim Hinterlegen von Passwörtern in einem Plaintextfile die Nackenhaare aufstellen X-), bidde:

    (Pfad zur Textdatei anpassen)

    $file = 'D:\data.txt' $data = Import-CSV $file -Delimiter ";" -Header 'Username','MapUsername','Password','Drive','Path' $net = New-Object -Com Wscript.Network $data | ?{$_.Username -eq $env:USERNAME} | %{ $net.MapNetworkDrive($_.Drive,$_.Path,$false,$_.MapUsername,$_.Password)
    # alternativ mit New-PSDrive
    #New-PSDrive -Name $_.Drive.SubString(0,1) -PSProvider FileSystem -Root $_.Path -Scope Global -Credential (new-Object PSCredential($_.MapUsername,(ConvertTo-SecureString $_.Password -AsPlainText -Force))) }

    Grüße Uwe





    • Bearbeitet U333 Donnerstag, 22. September 2016 16:58
    Donnerstag, 22. September 2016 16:51
  • Hi zusammen,

    ich bin leider nochmal auf eure Hilfe angewiesen.

    Ich habe mit get-credentials rumprobiert. Das Anlegen einer TXT-Datei, damit der User nicht jedes Mal das PW eingeben muss, klappt auch.

    Allerdings kriege ich es nicht hin, dass mir zum verbinden beim nächsten Mal das PW aus der Datei korrekt ausgelesen wird.

    Das habe ich gebastelt (muss dazu sagen, dass ich absolut keine Erfahrung in PS habe, daher sage ich bewusst gebastelt).

    $file = 'c:\temp\user.csv'
    $data = Import-CSV $file -Delimiter ";" -Header 'Userintern','Userextern','LW','Amt'
    $net = New-Object -Com Wscript.Network
    $data | ?{$_.UserLKG -eq $env:USERNAME} | %{  
    $Pfad= "\\IP-zumSERVER\" + $_.Amt
    $User = "DOMAIN\"+$_.Userextern
    $LW = $_.LW
    if (Test-Path $LW) { 
    net use $LW /D }
    if (!(Test-Path C:\temp\pw_hh.txt)) {
    $credential = Get-Credential -Message "Kennwort für die Laufwerksverbindung eingeben" -UserName $User
    $credential.Password | ConvertFrom-SecureString | Set-Content 'C:\temp\pw_hh.txt'
    $credential = New-Object System.Management.Automation.PsCredential($credential.UserName, $credential.Password)
    $net.MapNetworkDrive($_.LW,$Pfad,$false,$credential.UserName, $credential.Password)
        } else {   
    $encrypted = Get-Content c:\temp\pw_hh.txt | ConvertTo-SecureString -AsPlainText
    $credential = New-Object System.Management.Automation.PSCredential($User,$encrypted)     
    (New-Object -ComObject wscript.shell).popup("Laufwerk "+$_.LW+" wird verbunden...")     
    $net.MapNetworkDrive($_.LW,$Pfad,$false,$credential.UserName,$credential.Password)     
    }

    Ich bekomme immer ein Ausnahme beim Aufrufen von "MapNetworkDrive" mit 5 Argument(en):  "Typenkonflikt.

    Woran hapert es?

    Dienstag, 27. September 2016 10:49
  • Hallo philbo20,

    das liegt daran das

    $credential.Password

    vom Typ SecureString ist du musst stattdessen

    $credential.GetNetworkCredential().Password

    nehmen, dort steht das Passwort im Klartext vom Typ String.

    Und noch zur Info, das verschlüsselte Passwort kann nur der User auf der Maschine entschlüsseln der es auch verschlüsselt hat! D.h. das Skript muss mit diesem Account gestartet werden.

    Grüße Uwe





    • Bearbeitet U333 Dienstag, 27. September 2016 10:57
    Dienstag, 27. September 2016 10:53
  • > $encrypted = Get-Content c:\temp\pw_hh.txt | ConvertTo-SecureString -AsPlainText
     
    Das -AsPlainText muß hier weg - das brauchst Du nur, wenn Du aus
    "P@ssw0rd" einen Secure String machen willst. Aber Du hast das ja schon
    aus einem Secure String konvertiert :-)
     
    Dienstag, 27. September 2016 11:41
  • > $net.MapNetworkDrive($_.LW,$Pfad,$false,$credential.UserName,$credential.Password)
     
    Nachtrag: Mit dem WSH-Objekt geht das so auch nicht - das braucht wenn
    überhaupt das Kennwort im Klartext.
     
    Was Du aber machen kannst: New-PSDrive -Persist (wie oben schon geschrieben)
     
    Dienstag, 27. September 2016 11:44
  • > $net.MapNetworkDrive($_.LW,$Pfad,$false,$credential.UserName,$credential.Password)
     
    Nachtrag: Mit dem WSH-Objekt geht das so auch nicht - das braucht wenn
    überhaupt das Kennwort im Klartext.
     
    hatte ich oben schon die Lösung dafür gepostet :-)
    Dienstag, 27. September 2016 11:47
  • Und noch zur Info, das verschlüsselte Passwort kann nur der User auf der Maschine entschlüsseln der es auch verschlüsselt hat! D.h. das Skript muss mit diesem Account gestartet werden.



    Okay, dann probiere ich damit nochmal.

    Aber zu deiner Aussage "nur der User auf der Maschine". Hmm, der User wäre immer derselbe, aber die Maschine eben nicht (da Terminalserver). Dann könnte er die Datei nicht entschlüsseln bei der nächsten Anmeldung, wenn er auf nem anderen TS landet?

    Und geht es jetzt via $net.MapNetworkdrive oder nicht? Das hab ich jetzt nicht so ganz verstanden.

    Danke euch!

    Dienstag, 27. September 2016 12:18
  • Aber zu deiner Aussage "nur der User auf der Maschine". Hmm, der User wäre immer derselbe, aber die Maschine eben nicht (da Terminalserver). Dann könnte er die Datei nicht entschlüsseln bei der nächsten Anmeldung, wenn er auf nem anderen TS landet?

    Nein, das SecureString ist an den Account und an den Rechner gebunden.

    http://stackoverflow.com/questions/23699500/convertto-securestring-gives-different-experience-on-different-servers

    Doch das Mapping geht mit MapNetworkDrive, habe ich ja oben extra geschrieben wie dies zu machen ist!

    $net.MapNetworkDrive($_.LW,$Pfad,$false,$credential.UserName,$credential.GetNetworkCredential().Password)



    • Bearbeitet U333 Dienstag, 27. September 2016 12:23
    • Als Antwort markiert philbo20 Dienstag, 27. September 2016 13:02
    Dienstag, 27. September 2016 12:21
  • okay, danke!

    Hab es aber gerade mal ausprobiert...auch wenn ich von einem anderen TS das Script ausführe, wird mein Laufwerk verbunden!

    Dienstag, 27. September 2016 13:03
  • Dann habt ihr die Dinger geklont oder der User hat die Credentials schon in seinem Store.
    Es ist definitiv so das Securestring pro Rechner individuelle Machine-Keys zu Verschlüsselung benutzt, glaub's mir.
    • Bearbeitet U333 Dienstag, 27. September 2016 13:17
    Dienstag, 27. September 2016 13:15
  • > Es ist definitiv so das Securestring pro Rechner individuelle
    > Machine-Keys zu Verschlüsselung benutzt, glaub's mir.
     
    Er hat roaming profiles -
     
    Und das mit dem WSHNetwork hab ich übersehen :-)
     
    Dienstag, 27. September 2016 13:56
  • Er hat roaming profiles -
     

    Stimmt, in dem Fall ist es klar. Danke für die Ergänzung.
    • Bearbeitet U333 Dienstag, 27. September 2016 14:23
    Dienstag, 27. September 2016 14:23
  • japp, wir haben Roaming Profiles :-)

    Super, dann hab ich es jetzt soweit gelöst.

    Aus der zentral abgelegten .csv habe ich die Passwörter in Klartext rausgeworfen, da steht also nur noch der Pfad, LW-Buchstabe sowie der "lokale" und "entfernte" Username drin.

    Wenn dann die Text-Datei mit dem PW noch nicht im Home-LW des Users existiert, lasse ich sein Kennwort abfragen und in der TXT ablegen. Ist die Datei da, wird damit sein LW verbunden.

    Danke euch!

    Mittwoch, 28. September 2016 06:46
  • So 100% gelöst ist es doch noch nicht.

    Könnt ihr mir nen Tipp geben, wie ich den Fehlerfall abfange, wenn der User sein Kennwort falsch eingibt?

    Eigentlich müsste dann das get-credential-Fenster wieder kommen, so dass er nen neuen Versuch hat.

    Mittwoch, 28. September 2016 08:50
  • Du kannst entweder ein Try-Catch um den MapNetworkDrive-Befehl packen und das ganze in eine while-Schleife setzen. Oder du machst es mit einer Funktion die das Kennwort gegen das AD prüft:

    Beispiel

    function Check-Credential{
        param(
            [parameter(mandatory=$true)][ValidateNotNullOrEmpty()][pscredential]$cred
        )
        [System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices.Accountmanagement') | out-null
        $ds = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain)
        if ($cred.UserName -ne "" -and $cred.GetNetworkCredential().Password -ne ""){
            return $ds.ValidateCredentials($cred.UserName, $cred.GetNetworkCredential().password)
        }
        return $false
    }

    $maxtries = 5
    $tries = 0
    do {
        $cred = Get-Credential
        $result = Check-Credential $cred
        $tries++
    }until($result -or $tries -eq $maxtries)

    if($result){
        
        # hier dein Laufwerk mappen

    }else{
        write-host "Maximale Anzahl an Fehlversuchen erreicht" -ForegroundColor Red
    }


    Grüße Uwe








    • Bearbeitet U333 Mittwoch, 28. September 2016 10:16
    Mittwoch, 28. September 2016 09:18
  • und die Funktion rufe ich dann auf, nachdem ich den User sein Kennwort eingeben lasse?
    Mittwoch, 28. September 2016 09:59
  • Logisch :-) Sonst hast du ja noch kein Passwort :D OMG ...
    • Bearbeitet U333 Mittwoch, 28. September 2016 10:03
    Mittwoch, 28. September 2016 10:03
  • okay, aber da kann ich nur das PW in meiner aktuellen Domäne checken, richtig?

    Kann ich eine andere Domäne anfragen und dort die credentials prüfen lassen?

    • Bearbeitet philbo20 Mittwoch, 28. September 2016 11:05 .
    Mittwoch, 28. September 2016 11:04
  • okay, aber da kann ich nur das PW in meiner aktuellen Domäne checken, richtig?

    In der Form wie oben, ja. Kann man aber auch auf lokale Machine-Credentials ausbauen (indem man den ContextType auf "Machine" festlegt, oder man fragt per LDAP andere DCs ab. Je nachdem was man halt braucht.


    Per LDAP kann man z.B. so für eine andere Domain checken ob ein Passw0rd richtig oder falsch ist:

    $result = new-object adsi ("LDAP://dc=domainXYZ,dc=com","MaxMuster","Passw0rd")
    if($result.name){
      write-host "Credentials OK"
    }else{
      write-host "Credentials ERROR"
    }






    • Bearbeitet U333 Mittwoch, 28. September 2016 11:18
    Mittwoch, 28. September 2016 11:06
  • ziemlich langer Thread und nur kurz überflogen, aber als Anregung: mit Gruppenrichtlinen könntest du auch drives Mappen. Das geht dort ganz einfach 

    Chris

    Freitag, 18. November 2016 19:36