2016-04-20 15 views
0

Ich versuche ein Powershell-Skript zu erstellen, das ein Passwort aus dem Credential Manager in die Passworteingabe eines Python-Skripts eingibt. In this older post fand ich einige Informationen darüber, wie man einen Prozess mit PowerShell startet und dann etwas Text in die STDIN eingibt, aber aus irgendeinem Grund funktioniert diese Methode nicht für mich. Ich führe das Python-Skript aus und es wartet nur auf eine Passworteingabe im Powershell-Kommandozeilenfenster.Senden von Text an das Passwort STDIN des Python-Prozesses mit Powershell

Dies ist der Code und es führt das Python-Skript korrekt aus, das nach einem Passwort fragt, aber nichts passiert danach. Ich kann das Passwort manuell eingeben und auf Enter klicken, aber das ist natürlich nicht der Zweck. Dann kann ich das Python-Skript einfach selbst ausführen.

$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 
. $executingScriptDirectory\CredMan.ps1 

$launcherScript = Join-Path $executingScriptDirectory "launcher.py" 
$credTarget = 'some-target-in-credential-manager' 

Write-Host "Loading password from Windows credmgr entry '$credTarget' ..." 

[object] $cred = Read-Creds $credTarget 
if ($cred -eq $null) 
{ 
    Write-Host ("No such credential found: {0}" -f $credTarget) 
    Exit 2 
} 

# Found the credential; grab the password and boot up the launcher 
[string] $password = $cred.CredentialBlob 

Write-Host "Launching $launcherScript ..." 
Write-Host "Password: '$password'" 

$psi = New-Object System.Diagnostics.ProcessStartInfo; 
$psi.Arguments = "$launcherScript " 
$psi.FileName = "python.exe"; 
$psi.UseShellExecute = $false; # start the process from its own executable file 
$psi.RedirectStandardInput = $true; # enable the process to read from stdin 

$p = [System.Diagnostics.Process]::Start($psi); 

Start-Sleep -s 2 # wait 2 seconds so that the process can be up and running 
$p.StandardInput.WriteLine($password); 
$p.WaitForExit() 

Was könnte das Problem sein? Das Passwort wird im Python-Skript mit dieser Zeile abgefragt und verwendet das getpass-Modul.

password = getpass.getpass("Enter your password: ")

Vielen Dank für Ihre Hilfe.

Wenn Sie weitere Informationen benötigen, einfach anfordern :).

+0

Wie lautet die Ausgabe des Write-Host-Aufrufs? Siehst du das Passwort, das du zu diesem Zeitpunkt erwartest? Ich bin überrascht, dass Sie CredentialBlob einfach als Zeichenfolge und das ist das Passwort. –

Antwort

1

Alfe, ich danke Ihnen, dass Sie mir die richtige Richtung gezeigt haben, um dieses Problem zu lösen.

ich das Python-Skript angepasst haben, so dass es Parameter in der Befehlszeile und der Parameter für das Passwort nach der Option -p angegeben akzeptiert werden kann, so wie folgt aus:

$ script.py -p "password" 

Um dies zu tun aus Das Powershell-Skript. Mit diesem Code habe ich zunächst die Anmeldeinformationen aus dem Windows-Anmeldeinformations-Manager abgerufen und sie dem Python-Skript als Parameter übergeben.

Ich habe ein vorhandenes Skript verwendet, um die Anmeldeinformationen aus dem Anmeldeinformationen-Manager abrufen zu können, nämlich CredMan.ps1 script.

# Get the path of where this script is being invocated to reference to the script files in the same directory as this script. 
$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 
# Include external script to speak with Credential Manager 
. $executingScriptDirectory\CredMan.ps1 

$launcherScript = Join-Path $executingScriptDirectory "script.py" 
$credentialTarget = "name-of-credential-in-manager" 

[object] $cred = Read-Creds $credentialTarget 
if ($cred -eq $null) { 
    Write-Host ("No such credential found: {0}" -f $credentialTarget) 
    Exit 2 
} 

# Found the credential; Grab the password and execute the script with the password 
[string] $password = $cred.CredentialBlob 

# Execute python script with password given as parameter 
$exe = "python.exe" 
&$exe $launcherScript -p $password 

Vielen Dank für Ihre Hilfe und ich hoffe, Sie verstehen die gegebene Antwort.

+0

nette Lösung, aber wie veröffentlichen Sie es zum Endkunden? Sie müssen CredMan.ps1 auf dem Client-Rechner jedes Mal ausführen, wenn sich das Passwort ändert. Gibt es eine Möglichkeit, es in sichere Zeichenfolge zu konvertieren und mit Software zu übergeben? – olekb

+0

Ich bin mir nicht sicher, ob ich Ihre Frage verstehe, aber CredMan.ps1 wird jedes Mal ausgeführt, wenn das Python-Skript ausgeführt wird. Dies liegt daran, dass der Benutzer sein Kennwort jederzeit im Windows Credential-Manager ändern kann. Daher speichern wir das Kennwort niemals und überlassen es dem Berechtigungsverwalter, der Passwörter sicher speichern soll. – Digihash

1

Ich nehme an, der Python-Prozess liest das Passwort nicht aus dem STDIN-Stream, sondern direkt aus dem Terminal, an den der Prozess angehängt ist. Dieser Terminal-Stream unterliegt keinen Weiterleitungen, die Sie vor dem Start des Subprozesses installieren. Daher beeinflusst das Schreiben in den STDIN des Prozesses dies nicht. Die Tatsache, dass Sie Ihr Passwort direkt über die Tastatur in den Python-Prozess eingeben können und es akzeptiert, gibt mir Recht, würde ich sagen.

In Ihrem Fall müssen Sie den Python-Prozess optimieren, um das PW von woanders zu lesen, e. G. indem Sie eine spezielle Option übergeben (natürlich ganz abhängig von Ihrem Python-Prozess) oder indem Sie die Python-Quelle selbst patchen.

Vielleicht gibt es auch Windows-spezifische Möglichkeiten, Tastatureingaben zu simulieren, aber das würde ich einen sehr hässlichen Hack nennen und kann daher nicht empfehlen.

+0

Hallo, ich habe das Python-Skript so geändert, dass Sie jetzt einen Parameter für das Passwort wie folgt angeben können: script.py -p 'password' Aber wie gebe ich diese Variable $ password als Parameter für -p zum Python-Skript? – Digihash

+0

Ich kenne nicht die Sprache, die Sie verwenden, um das Python-Skript aufzurufen, sondern die Stelle, an der Sie '$ psi.Arguments =" $ launcherScript "' und '$ psi.FileName =" python.exe ";' scheint verdächtig. Vielleicht funktioniert es mit '$ psi.Arguments =" $ launcherScript -p $ password "'? Oder können Sie irgendwie ein Array aller Argumente übergeben (z. B. $ psi.Arguments = ["$ launcherScript", "-p", "$ password"] ')? – Alfe