在python脚本中传递Powershell命令之间的变量

时间:2014-11-18 16:19:40

标签: python powershell

我必须通过python脚本调用两个powershell命令。我目前正在使用subprocess.Popen。

第一个命令返回一个powershell对象。例如:

PS>$temp = <powershell_command_1>

$ temp对象中有多个属性。必须将整个对象传递给同一脚本中的第二个PowerShell对象。例如

PS><powershell_command_2> -object $temp

如果$ temp是一个字符串,我传递python字符串变量没有问题。但是,在这种情况下,$ temp是一个对象。如何将此值传递给第二个PS cmdlet?

这是追溯

Traceback (most recent call last):
  File "file.py", line 430, in <module>
    status = c1.configure_cluster()
  File "file.py", line 319, in configure_cluster
    configure_cluster = subprocess.Popen([self.powershell_binary,'-ExecutionPolicy','ByPass',r'Cmdlet2', temp], stdout=subprocess.PIPE)
  File "C:\Python34\lib\subprocess.py", line 858, in __init__
    restore_signals, start_new_session)
  File "C:\Python34\lib\subprocess.py", line 1085, in _execute_child
    args = list2cmdline(args)
  File "C:\Python34\lib\subprocess.py", line 663, in list2cmdline
    needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: Type str doesn't support the buffer API

1 个答案:

答案 0 :(得分:0)

如果两个命令可以一起运行,那么只需将它们一起运行,但正如您所说,您必须单独运行它们,您可以尝试使用Export-Clixml将对象保存到文件,然后Import-Clixml到重装它。这是一个有效的例子:

#!/usr/bin/env python3
import base64, subprocess, sys

def powershell(cmd, input=None):
    cmd64 = base64.encodebytes(cmd.encode('utf-16-le')).decode('ascii').strip()
    stdin = None if input is None else subprocess.PIPE
    process = subprocess.Popen(["powershell.exe", "-NonInteractive", "-EncodedCommand", cmd64], stdin=stdin, stdout=subprocess.PIPE)
    if input is not None:
        input = input.encode(sys.stdout.encoding)
    output, stderr = process.communicate(input)
    output = output.decode(sys.stdout.encoding).replace('\r\n', '\n')
    return output

command=r"""
$data = Get-ChildItem C:\Python34
$data | Export-Clixml -Path c:\temp\state.xml
$data
"""
output = powershell(command)
print(output)
print("Do some processing here...")
result = """NEWS.txt=1
README.txt=1
\u00a3.txt=1
"""
command = r"""
$in = $input|Out-String
$selected = $in | ConvertFrom-StringData
$data = Import-Clixml -Path c:\\temp\\state.xml
$data |? { $selected.ContainsKey($_.Name) } | Select Length,FullName
"""
output = powershell(command, result)
print(output)

其中给出了以下输出:

C:\Temp>py state.py


    Directory: C:\Python34


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        24/10/2014     11:52            DLLs
d----        24/10/2014     11:52            Doc
d----        24/10/2014     11:52            include
d----        24/10/2014     11:52            Lib
d----        24/10/2014     11:52            libs
d----        05/11/2014     16:53            Scripts
d----        24/10/2014     11:52            tcl
d----        24/10/2014     11:52            Tools
-a---        06/10/2014     22:19      31073 LICENSE.txt
-a---        21/09/2014     21:03     367504 NEWS.txt
-a---        06/10/2014     22:15      27136 python.exe
-a---        06/10/2014     22:15      27648 pythonw.exe
-a---        06/10/2014     22:10       6942 README.txt
-a---        19/11/2014     11:59          5 £.txt



Do some processing here...

                                 Length FullName
                                 ------ --------
                                 367504 C:\Python34\NEWS.txt
                                   6942 C:\Python34\README.txt
                                      5 C:\Python34\£.txt

您当然可以将XML加载到Python中并对其进行操作,在这种情况下使用ConvertTo-Xml -as string而不是Export-CliXml,但我不太确定如何将转换回Powershell对象而不是一个xml对象。 (编辑:Powershell's import-clixml from string涵盖了通过Clixml而不使用文件的往返对象)。

相关问题