Set the powershell encoding output when called with the popen of Python
<p>I have a python script who execute some powershell script (I execute python from cmd or powershell console)</p>

<pre><code>import subprocess, json

def readSensorList():
    with open('sensor.json') as json_data:
        data = json.load(json_data)
    json_data.close()
    return data
def executeSensor():
    sensorList = list()
    sensorListRaw = readSensorList()
    for sensor in sensorListRaw["sensors"]:
        x = subprocess.Popen(["powershell.exe",
    '-ExecutionPolicy',
    'Unrestricted', sensorListRaw["path"] + sensor["filename"]], stdout=subprocess.PIPE)
        sensorList.append(x)
    return sensorList
def sortSensorInformation(sensors):
    sortedJson = list()
    for sensor in sensors:
        sortedJson.append(json.loads(sensor.communicate()[0].decode('windows-1252')))
    print(json.dumps(sortedJson))

sortSensorInformation(executeSensor())
</code></pre>

<p>The PS script output is JSON, but the encoding is never the same in the different os I tried...</p>

<p>In my Windows 10 French, without the .decode('windows-1252') I get:</p>

<pre><code>[b'{\t"AVPath": "%ProgramFiles%\\\\Windows Defender\\\\MSASCui.exe", \t"AVDefStatus": "Up to date", \t"AVName": "Windows Defender", \t"AVRTP": "Enabled"}\r\n', b'{\t"Uptime": "2:0:56:33"}\r\n', b'{\t"updatePending": 2, \t"isARebootPending": false}\r\n', b'{\t"serverAge": ":::"}\r\n', b'{\t"freeSpace": 831.379005432129, \t"diskLetter": "C:", \t"totalSpace": 931.022457122803, \t"volumeName": ""}\r\n', b'{\t"firewallStatus": "OK"}\r\n']
</code></pre>

<p>with the .decode('windows-1252') the encoding is ok:</p>

<pre><code>[{"AVRTP": "Enabled", "AVPath": "%ProgramFiles%\\Windows Defender\\MSASCui.exe", "AVName": "Windows Defender", "AVDefStatus": "Up to date"}, {"Uptime": "2:0:54:53"}, {"isARebootPending": false, "updatePending": 2}, {"serverAge": ":::"}, {"diskLetter": "C:", "freeSpace": 831.373157501221, "volumeName": "", "totalSpace": 931.022457122803}, {"firewallStatus": "OK"}]
</code></pre>

<p>On server 2012 french, it's the same as windows 10, but on Server 2011 french,
with the 1252 decoding:</p>

<pre><code>['{\t"Uptime": "49:21:54:10"}\r\n', '{\t"isARebootPending": false,\t"updatePending": 1}\r\n', '[{\t"volumeName": "SYSTEME", \t"freeSpace": 95.5574760437012, \t"totalSpace": 279.266887664795, \t"diskLetter": "C{\t"v\r\nolumeName": "DONNEES", \t"freeSpace": 160.898635864258,\t"totalSpace": 558.877925872803, \t"diskLetter": "D:"},{\t"volume\r\nName": "Backup", \t"freeSpace": 65.9345016479492, \t"totalSpace": 558.877925872803, \t"diskLetter": "Z:"}]\r\n', '{\t"firewallStatus": "OK"}\r\n']
</code></pre>

<p>But sometimes I get:</p>

<pre><code>UnicodeEncodeError: 'charmap' codec can't encode character '\u0160' in position 226: character maps to &lt;undefined&gt;
</code></pre>

<p>Without .decode('windows-1252') (still 2011 french):</p>

<pre><code>[b'{\t"Uptime": "49:21:51:37"}\r\n', b'{\t"isARebootPending": false, \t"updatePending": 1}\r\n', b'[{\t"volumeName": "SYSTEME", \t"freeSpace": 95.5614395141602, \t"totalSpace": 279.266887664795, \t"diskLetter": "C:"}, {\t"v\r\nolumeName": "DONNEES", \t"freeSpace": 160.899082183838, \t"totalSpace": 558.877925872803, \t"diskLetter": "D:"}, {\t"volume\r\nName":"Backup", \t"freeSpace": 65.9345016479492, \t"totalSpace": 558.877925872803, \t"diskLetter": "Z:"}]\r\n', b'{\t"firewallStatus": "OK"}\r\n']
</code></pre>

<p>I just don't understand why...</p>

<p>Here is one powershell scripts:</p>

<pre><code>$scriptpath = Split-Path $MyInvocation.MyCommand.Path
Push-Location $scriptpath
#Importing the file where the JSON function are
. ".\util\json.ps1"

   #Get the WMIObject who contain the lastbootuptime and convert it into DateTime
   $os = Get-WmiObject win32_operatingsystem
   $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
   #Preparing the object uptimeClean with the object $Uptime to convert it into JSON
   $uptimeClean = @{
    Uptime = '' + $Uptime.Days + ':' + $Uptime.Hours + ':' + $Uptime.Minutes + ':' + $Uptime.Seconds
   }

   Write-Output $uptimeClean | ConvertTo-JSON
</code></pre>

<p>Is there a way to set the powershell output encoding, or to automatically find the encoding in python?</p>

<p>Or other idea?</p>