Run powershell Scripts INSIDE python script
I believe the easiest way to achieve what you are trying to do is by using subprocess.Popen
. This function can call command-line/terminal commands from within a python script. It can be used like this:
import subprocess
subprocess.Popen()
Where your command is placed between the two brackets.
A Powershell command can be executed from the command line using the command line (see this):
powershell -command ""
Where your command is between the two quotation marks.
Since subprocess.Popen can call a command line command, you can call a powershell command through it. Here's an example using your first ps command:
import subprocess
command='Write-Host("Installing module PSWindowsUpdate if not already installed...")'
subprocess.Popen('powershell -command '+"'"+command+"'")
Alternatively, you can use subprocess.run to execute the command. The only difference it that subprocess.run executes the command and then your script continues, while subprocess.Popen runs the command while your script continues.
If you want the command to do it's thing silently (eg. without opening powershell), pass stdout=subprocess.PIPE, shell=True
to subprocess.Popen
with your command.
You can print the output directly with something like:
stdout_value = process.communicate()[0]
print (stdout_value)
Where process is your subprocess.Popen() object.
Now onto completing all your commands:
If you want to print the output of your commands, you can use:
import subprocess
def call_command(command):
process=subprocess.Popen('powershell -command '+"'"+command+"'", stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
stdout_value = process.communicate()[0]
return stdout_value
print(call_command('Write-Host("Installing module PSWindowsUpdate if not already installed... ")'))
Simply use call_command for each command and you're done. You will see some extra characters in the output (eg. \n
or \r
), these are included by default for powershell to actually create a newline, etc. Basically, if you don't want them, you can remove them yourself (eg. string.replace('\n', '')
)
If you want to actually open powershell, calling subprocess.Popen
for each line will open one powershell terminal per line, which I don't think you'd want. I would take some more trickery to call all the commands in one powershell terminal:
One thing you could do is put your powershell commands in a file with the .ps1 file extension.you can then call it with subprocess.Popen and run it altogether in a powershell terminal.
For example:
import subprocess
subprocess.Popen("C://path/to/your/file/myfile.ps1")
But you'd have to have another file, not just your python script.
Or:
your could combine all your commands into one:
commands = """ Write-Host("Installing module PSWindowsUpdate if not already installed... ")
Install-Module PSWindowsUpdate
Write-Host("PSWindowsUpdate is now installed.")
Write-Host("")
Write-Host("Getting Windows Updates...")
Import-Module PSWindowsUpdate
$updates = Invoke-Command -ScriptBlock {Get-Wulist -verbose}
$updatenumber = ($updates.kb).count
if ($null -ne $updates){
Get-WindowsUpdate -AcceptAll -Install | Out-File C:\PSWindowsUpdate.log
do {$updatestatus = Get-Content c:\PSWindowsUpdate.log
"Currently processing the following update:"
Get-Content c:\PSWindowsUpdate.log | select-object -last 1
Start-Sleep -Seconds 10
$ErrorActionPreference = 'SilentlyContinue'
$installednumber = ([regex]::Matches($updatestatus, "Installed" )).count
$ErrorActionPreference = ‘Continue’
}until ( $installednumber -eq $updatenumber)
}
Remove-Item -path C:\PSWindowsUpdate.log"""
Then run it with subprocess:
import subprocess;
subprocess.Popen(["powershell","& {" + command+ "}"])
# or subprocess.Popen('powershell -command' + command)
To print it in the terminal instead of opening powershell, use:
import subprocess;
subprocess.Popen(["powershell","& {" + command+ "}"], stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
stdout_value = process.communicate()[0]
return stdout_value
That should be it!
How to run a Powershell script in python
Here is simplified example of your use case:
import subprocess;
process=subprocess.Popen(["powershell","Get-Childitem C:\\Windows\\*.log"],stdout=subprocess.PIPE);
result=process.communicate()[0]
print (result)
Of course the above is just printing out a directory list, but you just replace that command with your .ps1 script path.
Also, as noted in my comment, why not just use the ...
# 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, to collect this info and select the properties you want?
Only running the other collectors for info that Get-ComputerInfo
does not provide.
There is also the built-in ...
Get-PhysicalDisk
Get-Volume
... cmdlets to get storage information.
How about constructing your output details this way...
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)}
}
)
}
... or combine and ouput this way
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
}
}
}
$ComputerDetails
Running powershell script within python script, how to make python print the powershell output while it is running
Make sure you can run powershell scripts (it is disabled by default). Likely you have already done this. http://technet.microsoft.com/en-us/library/ee176949.aspx
Set-ExecutionPolicy RemoteSigned
Run this python script on your powershell script
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()
This code is based on python3.4 (or any 3.x series interpreter), though it should work on python2.x series as well.
C:\Users\MacEwin\Desktop>python helloworld.py
Hello World
How to run a PowerShell cmdlet in Python to get a list of connected USB devices?
There is a module called pyUSB that works really well.
Alternatively, to run Powershell commands, you can use the subprocess package.
import subprocess
result = subprocess.run(["powershell", "-Command", MyCommand], capture_output=True)
Running a python script via Powershell script
Assuming that python is already in your path variables you can just call a python script like this:
python C:\User\PythonScripts\TestFile.py
Related Topics
Pythone :How to Use Dataframe Output in Email Body as Text
Converting Two Lists into a Matrix
How to Read a File Without Newlines
Tensorflow: Convert Tensor to Numpy Array Without .Eval() or Sess.Run()
How to Make a Dataframe Show in Pycharm
How to Redeem Nitro Gifts Automatically With Discord.Py (Self-Bot)
How to Determine Whether a Column/Variable Is Numeric or Not in Pandas/Numpy
Visual Studio Code Pylint: Unable to Import 'Protorpc'
Plotly: Plot Multiple Figures as Subplots
Text Pre-Processing + Python + Csv:Removing Special Characters from a Column of a Csv
Convert SQL Result to List Python
Python Regex - How to Get Positions and Values of Matches
Pandas Convert Columns to Percentages of the Totals
How to Cleanly Uninstall Ansible
How to Change the Title Bar in Tkinter
Python Json Add Key-Value Pair
Turn String into a List and Remove Carriage Returns (Python)