3

I am trying to pull a variety of system metrics from a PowerShell Script into Python for further processing. I have picked the data that I need and used echo to place it into a txt file which I am attempting to read with Python, but when I look at the Python data, I just get gibberish. Does Powershell use some strange encoding when it outputs to txt files? If so, is there a way to either get PowerShell to output in a format Python can read or instruct Python to read the format PowerShell uses?

The PowerShell Code looks like this:

$Make = Get-CimInstance CIM_ComputerSystem | Select Manufacturer
echo $Make.manufacturer > c:\Mike\Output\SysConfig.txt
$Model = Get-CimInstance CIM_ComputerSystem | Select Model
echo $Model.model >> c:\Mike\Output\SysConfig.txt
$Os = Get-CimInstance Win32_OperatingSystem | Select-Object  Caption
echo $Os.caption >> c:\Mike\Output\SysConfig.txt
$CPU = Get-WmiObject Win32_Processor | Select * 
echo $CPU.Name >> c:\Mike\Output\SysConfig.txt
echo $CPU.NumberOfCores >> c:\Mike\Output\SysConfig.txt
echo $CPU.NumberOfLogicalProcessors >> c:\Mike\Output\SysConfig.txt
echo $CPU.ThreadCount >> c:\Mike\Output\SysConfig.txt
echo $CPU.MaxClockSpeed >> c:\Mike\Output\SysConfig.txt
echo $CPU.CurrentClockSpeed >> c:\Mike\Output\SysConfig.txt

The text output looks like this:

Hewlett-Packard
HP EliteBook 2570p
Microsoft Windows 10 Pro
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
2
4
4
2901
2901

And the Python Code looks like this:

with open('c:\mike\output\SysConfig.txt', mode='r') as f:
    Manufacturer = f.readlines(1)
    Make = f.readlines(2)
    OS = f.readlines(3)
    CPU_Name = f.readlines(4)
    CPU_Phys_Cores = f.readlines(5)
    CPU_Log_Cores = f.readlines(6)
    CPU_Threads = f.readlines(7)
    CPU_Max_Clock = f.readlines(8)
    CPU_Curr_Clock = f.readlines(9)

print(Manufacturer)
print(Make)
print(OS)
print(CPU_Name)
print(CPU_Phys_Cores)
print(CPU_Log_Cores)
print(CPU_Threads)
print(CPU_Max_Clock)
print(CPU_Curr_Clock)
3
  • Use | Out-File -FilePath C:\Mike\Output\SysConfig.txt -Encoding UTF8 -Append, not a redirect operator >>. Also, what's the point of using Python when you're already using PowerShell? Commented Dec 22, 2017 at 16:34
  • I'm creating a much larger program that cannot be run in powershell but have found that Python does not produce reliable system metrics on my machines. Commented Dec 22, 2017 at 16:43
  • You're using readlines() incorrectly. The argument tells it the maximum number of lines to read, it's not the index of a line in file. I suggest you use readline() instead and just put f.readline() everywhere. Commented Dec 22, 2017 at 16:46

2 Answers 2

4

Your problem is the encoding of the redirect operators is unicode (UTF16-LE).

$CS = Get-CimInstance -ClassName CIM_ComputerSystem
$OS = (Get-CimInstance -ClassName Win32_OperatingSystem).Caption
$CPU = Get-CimInstance -ClassName Win32_Processor

@"
$($CS.Manufacturer)
$($CS.Model)
$OS
$($CPU.Name)
$($CPU.NumberOfCores)
$($CPU.NumberOfLogicalProcessors)
$($CPU.ThreadCount)
$($CPU.MaxClockSpeed)
$($CPU.CurrentClockSpeed)
"@ | Out-File -FilePath C:\Mike\Output\SysConfig.txt -Encoding UTF8

Cleaned up:

$CS = Get-CimInstance -ClassName CIM_ComputerSystem
$OS = (Get-CimInstance -ClassName Win32_OperatingSystem).Caption
$CPU = Get-CimInstance -ClassName Win32_Processor

"{0}`n{1}`n{2}`n{3}`n{4}`n{5}`n{6}`n{7}`n{8}" -f @( $CS.Manufacturer
                                                    $CS.Model
                                                    $OS
                                                    $CPU.Name
                                                    $CPU.NumberOfCores
                                                    $CPU.NumberOfLogicalProcessors
                                                    $CPU.ThreadCount
                                                    $CPU.MaxClockSpeed
                                                    $CPU.CurrentClockSpeed
                                                  ) |
    Out-File -FilePath C:\Mike\Output\SysConfig.txt -Encoding UTF8
Sign up to request clarification or add additional context in comments.

Comments

2

No problem reading what you have in Python.

Define some labels, for use in presenting output. Read the entire input file a as a byte arrays, decode the bytes appropriately to form a string, and discard a line-end, if present. Split the string on line-ends and print each resulting string with the appropriate label.

vars = ["Manufacturer", "Make", "OS", "CPU_Name", "CPU_Phys_Cores", "CPU_Log_Cores", "CPU_Threads", "CPU_Max_Clock", "CPU_Curr_Clock"]

with open('SysConfig.txt', 'rb') as f:
    content = f.read().decode(encoding='UTF16').rstrip() 

for var, line in zip(vars, content.split('\n')):
    print (var, line.strip())

Output:

Manufacturer Hewlett-Packard
Make HP Compaq Elite 8300 SFF
OS Microsoft Windows 10 Pro
CPU_Name Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
CPU_Phys_Cores 4
CPU_Log_Cores 4
CPU_Threads 4
CPU_Max_Clock 3201
CPU_Curr_Clock 2700

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.