web-dev-qa-db-fra.com

Exécution du script powershell dans python, comment faire python imprimer la sortie powershell pendant son exécution)

J'écris un script python qui vérifie diverses conditions et exécute un script powershell en conséquence pour m'aider à automatiser la migration de windows XP vers windows 7. Le script powershell donne sa propre sortie donnant à l'utilisateur des mises à jour sur ce qui se passe. Je voudrais prendre la sortie du script powershell et l'imprimer comme sortie du script python. J'ai regardé autour de quelques questions qui semblent vouloir faire la même chose mais ils ne semblent pas fonctionner pour moi. Au début, j'ai essayé d'utiliser

import subprocess
subprocess.call(["C:\Users\gu2124\Desktop\helloworld.ps1"])

Comme cela a été suggéré ici Exécuter la fonction PowerShell à partir de Python mais j'ai découvert que cela attend que le programme s'exécute en premier et ne donne pas de sortie, j'ai donc découvert que j'avais besoin d'utiliser subprocess.Popen() comme cela a été suggéré ici tilisez Popen pour exécuter un script Powershell en Python, comment puis-je obtenir la sortie du script Powershell et le mettre à jour sur la page Web? alors j'ai essayé ceci

import subprocess
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=sys.stdout)

et je reçois cette erreur

Traceback (most recent call last):
  File "C:\Users\gu2124\Desktop\pstest.py", line 5, in <module>
    subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.py1"], stdout=sys.stdout)
  File "C:\Python27\lib\subprocess.py", line 701, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:\Python27\lib\subprocess.py", line 848, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
  File "<string>", line 523, in __getattr__
  File "C:\Program Files\PyScripter\Lib\rpyc.Zip\rpyc\core\netref.py", line 150, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "C:\Program Files\PyScripter\Lib\rpyc.Zip\rpyc\core\netref.py", line 71, in syncreq
    return conn.sync_request(handler, oid, *args)
  File "C:\Program Files\PyScripter\Lib\rpyc.Zip\rpyc\core\protocol.py", line 434, in sync_request
    raise obj

AttributeError: DebugOutput instance has no attribute 'fileno'

Je ne suis pas complètement sûr de ce que cela signifie, mais d'après ce que je pense avoir compris après avoir lu ceci AttributeError: l'instance de StringIO n'a pas d'attribut 'fileno' c'est que c'est parce que je joue avec la stdout de manière incorrecte. J'ai regardé un peu plus et j'ai trouvé cela Pourquoi mon code de sous-processus python ne fonctionne-t-il pas? où les réponses ont dit d'utiliser stdout=subprocess.PIPE Alors j'ai essayé ce

import subprocess
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)

qui ne me donne pas non plus de sortie Enfin, j'ai vu cela http://www.pythonforbeginners.com/os/subprocess-for-system-administrators et j'ai changé mon code en celui-ci

import subprocess
p = subprocess.Popen(["powershell","C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)
print p.communicate

Je pensais que cela le pouvait parce que j'essaie initialement d'exécuter un script PowerShell à partir de la ligne de commande, je dois donc d'abord ouvrir PowerShell. Lorsque je tape ces commandes directement dans la ligne de commande, cela fonctionne comme il se doit, mais lorsque je l'exécute via le script python, il donne ceci

<bound method Popen.communicate of <subprocess.Popen object at 0x00000000026E4A90>>

ce qui est une amélioration je suppose mais pas le "Hello world" que j'attendais. Je n'ai aucune idée de ce que je devrais essayer de faire ensuite pour que cela fonctionne. Toute aide serait grandement appréciée

De plus, si le script PowerShell que j'utilise est nécessaire ici, il est

$strString = "Hello World"
write-Host $strString

function ftest{
$test = "Test"
write-Host $test
}

EDIT: J'ai essayé de mettre à niveau vers python 3.3 comme cela a été suggéré dans la première réponse mais je ne peux toujours pas le faire fonctionner. J'ai utilisé la commande p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout) et je suis sûr que le le fichier est là mais j'obtiens cette erreur:

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout)
  File "C:\Python27\lib\subprocess.py", line 701, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:\Python27\lib\subprocess.py", line 848, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
UnsupportedOperation: fileno 
15
user3282276
  1. Assurez-vous que vous pouvez exécuter des scripts PowerShell (il est désactivé par défaut). Vous l'avez probablement déjà fait. http://technet.Microsoft.com/en-us/library/ee176949.aspx

    Set-ExecutionPolicy RemoteSigned
    
  2. Exécutez ce script python sur votre script powershell helloworld.py:

    # -*- coding: iso-8859-1 -*-
    import subprocess, sys
    
    p = subprocess.Popen(["powershell.exe", 
                  "C:\\Users\\USER\\Desktop\\helloworld.ps1"], 
                  stdout=sys.stdout)
    p.communicate()
    

Ce code est basé sur python3.4 (ou n'importe quel interpréteur de série 3.x), bien qu'il devrait également fonctionner sur la série python2.x.

C:\Users\MacEwin\Desktop>python helloworld.py
Hello World
19
NuclearPeon

Je n'ai pas Python 2.7 installé, mais dans Python 3.3 appelant Popen avec stdout réglé sur sys.stdout a très bien fonctionné. Mais pas avant d'avoir échappé aux barres obliques inverses du chemin.

>>> import subprocess
>>> import sys
>>> p = subprocess.Popen(['powershell.exe', 'C:\\Temp\\test.ps1'], stdout=sys.stdout)
>>> Hello World
_
1
Ansgar Wiechers