添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如何在python中运行一个Powershell脚本

1 人关注

所以我的问题是,如何在python中运行PowerShell脚本,并从python中传递变量,然后让python运行PowerShell脚本,再从PowerShell脚本中传递特定变量给python脚本。

我所拥有的是每个代码单独工作。 正如你所看到的,我从一个 .ini 文件中传入隐藏变量,然后从那里我试图把 compList 传给Powershell。

我不确定我是否运行了正确的命令来调用PowerShell并在我的Python脚本中传递args

preferences = configparser.ConfigParser()
preferences.read('config.ini')
hostName = preferences.get('Directory', 'hostName')
port = preferences.get('Directory', 'port')
serviceName = preferences.get('Directory', 'serviceName')
usr = preferences.get('Credentials', 'userName')
pswrd = preferences.get('Credentials', 'password')
compList = preferences.get('ComputerList', 'compList')
compList = list(compList.split(","))
p = subprocess.Popen(["powershell.exe", r"C:\Users\pecorgx\TestPS1.ps1", 'arg1 @("compList")'], stdout=sys.stdout)
p.communicate()

My PowerShell Script:

$ArrComputers =  $arg1
Clear-Host
foreach ($Computer in $ArrComputers) 
    $computerSystem = get-wmiobject Win32_ComputerSystem -Computer $Computer
    $computerBIOS = get-wmiobject Win32_BIOS -Computer $Computer
    $computerOS = get-wmiobject Win32_OperatingSystem -Computer $Computer
    $computerCPU = get-wmiobject Win32_Processor -Computer $Computer
    $hdds = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter drivetype=3
        write-host "System Information for: " $computerSystem.Name -BackgroundColor DarkCyan
        "-------------------------------------------------------"
        "Manufacturer: " + $computerSystem.Manufacturer
        "Model: " + $computerSystem.Model
        "Serial Number: " + $computerBIOS.SerialNumber
        "CPU: " + $computerCPU.Name
        foreach ($computerhdd in $hdds) { "HDD Drive Letter: " + $computerhdd.DeviceID + "HDD Capacity:" + "{0:N2}" -f ($computerHDD.Size/1GB) + "GB" + " HDD Space: " + "{0:P2}" -f ($computerHDD.FreeSpace/$computerHDD.Size) }
        "RAM: " + "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB) + "GB"
        "Operating System: " + $computerOS.caption + ", Service Pack: " + $computerOS.ServicePackMajorVersion
        "User logged In: " + $computerSystem.UserName
        "Last Reboot: " + $computerOS.ConvertToDateTime($computerOS.LastBootUpTime)
        "-------------------------------------------------------"

我认为我的传递是正确的,但我想让Powershell传递回我的Python脚本

$computerSystem.TotalPhysicalMemory/1GB
$computerSystem.Manufacturer
$computerSystem.Model
$computerBIOS.SerialNumber
$computerCPU.Name

我想把这个var $computerHDD.Size/1GB传到一个列表中,然后再传给我的python脚本

编辑:我决定只使用.txt来传递命令。我做了$myOBJ = "" | Select "computer",然后做了$myOBJ.computer = [string](....),其中(...)是我想在脚本运行后传回的东西。 我很想知道在没有第三方帮助的情况下可以使用的解决方案。

5 个评论
如果你让powerhell脚本打印出json,你应该可以很容易地在python中反序列化它。
我说的 "打印出来 "是指打印到std out,而不是一个文件。
为什么你在这个命令里有这个随机的 r --- subprocess.Popen(["powershell.exe", r"C:\Users\pecorgx\TestPS1.ps1" ?在你的ps1中,你没有在任何地方显示 $arg1 中的内容,所以, $ArrComputers = $arg1 ,将是空的。更谨慎的做法是将你要的信息设置为hashtable到pscustomobject并返回。另外,为什么不直接使用内置的 Get-ComputerInfo cmdlet来获取这些信息,而非所有这些调用?
r代表原始字符串
python
powershell
Glenville Pecor
Glenville Pecor
发布于 2021-04-14
1 个回答
postanote
postanote
发布于 2021-04-14
已采纳
0 人赞同

这里是你的用例的简化例子。

import subprocess;
process=subprocess.Popen(["powershell","Get-Childitem C:\\Windows\\*.log"],stdout=subprocess.PIPE);
result=process.communicate()[0]
print (result)

当然,上面只是打印出一个目录列表,但你只要用你的.ps1脚本路径替换该命令即可。

此外,正如我在评论中指出的,为什么不直接使用......。

# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-ComputerInfo).Parameters
(Get-Command -Name Get-ComputerInfo).Parameters.Keys
Get-help -Name Get-ComputerInfo -Examples
Get-Help -Name Get-ComputerInfo -Detailed
Get-help -Name Get-ComputerInfo -Full
Get-help -Name Get-ComputerInfo -Online
Get-ComputerInfo -Property '*'

... cmdlet,来收集这些信息并选择你想要的属性? 只有运行其他收集器才能获得Get-ComputerInfo不提供的信息。

还有内置的...

Get-PhysicalDisk
Get-Volume

... cmdlets来获取存储信息。

这样来构建你的输出细节如何...

Clear-Host
$env:COMPUTERNAME | 
ForEach-Object{
    $computerSystem = Get-wmiobject Win32_ComputerSystem -ComputerName $PSItem
    $computerBIOS   = Get-wmiobject Win32_BIOS -ComputerName $PSItem
    $computerOS     = Get-wmiobject Win32_OperatingSystem -ComputerName $PSItem
    $computerCPU    = Get-wmiobject Win32_Processor -ComputerName $PSItem
        $ComputerInfo = [PSCustomObject]@{
                            Manufacturer    = $computerSystem.Manufacturer
                            Model           = $computerSystem.Model
                            SerialNumber    = $computerBIOS.SerialNumber
                            CPU             = $computerCPU.Name 
                            RAM             = [math]::Round($($computerSystem.TotalPhysicalMemory/1GB), 3)
                            OperatingSystem = "$($computerOS.caption), Service Pack: $($computerOS.ServicePackMajorVersion)"
                            LoggedOnUser    = $env:USERNAME  
                            LastReboot      = $computerOS.ConvertToDateTime($computerOS.LastBootUpTime) 
        $StorageInfo = [PSCustomObject]@{
                            DeviceID      = (Get-Volume).DriveLetter
                            Size          = Get-Volume | ForEach {[math]::Round($($PSitem.Size/1GB), 3)}
                            SizeRemaining = Get-Volume | ForEach {[math]::Round($($PSitem.SizeRemaining/1GB), 3)}

......或结合起来,以这种方式输出

Clear-Host
$env:COMPUTERNAME | 
ForEach-Object{
    $ComputerSystem  = Get-wmiobject Win32_ComputerSystem -ComputerName $PSItem | 
                       Select-Object -Property Manufacturer, Model, UserName
    $ComputerBIOS    = Get-wmiobject Win32_BIOS -ComputerName $PSItem| 
                       Select-Object -Property SerialNumber
    $ComputerOS      = Get-wmiobject Win32_OperatingSystem -ComputerName $PSItem  | 
                       Select-Object -Property Caption, ServicePackMajorVersion, 
                            Name       = 'LastReboot'
                            Expression = {$PSItem.ConvertToDateTime($PSItem.LastBootUpTime)}
    $ComputerCPU     = Get-wmiobject Win32_Processor -ComputerName $PSItem | 
                       Select-Object -Property Name
    $ComputerStorage = Get-WmiObject Win32_LogicalDisk -ComputerName $PSItem -Filter drivetype=3 | 
                       Select-Object -Property DeviceID, 
                           Name        = 'Size'
                           Expression = {[math]::Round($($PSitem.Size/1GB), 3)}
                           Name        = 'FreeSpace'
                           Expression = {[math]::Round($($PSitem.FreeSpace/1GB), 3)}
    $ComputerDetails = New-Object -Type PSObject
    $ComputerSystem, $ComputerBIOS, $ComputerOS, $ComputerCPU, $ComputerStorage | 
    ForEach-Object {
        $CurObj = $PSItem 
        $PSItem | 
        Get-Member | 
        Where-Object {$PSItem.MemberType -match 'NoteProperty'} | 
        ForEach-Object {
            $NewMember = $PSItem.Name
            $ComputerDetails | 
            Add-Member -MemberType NoteProperty -Name $NewMember -Value $CurObj.$NewMember