Python上でPowerShellを実行する

# はじめに
PowerShellのコマンドをPython上で実行する方法をまとめる。Pythonのライブラリ```subprocess```を使う。

# 目次
+ [subprocess](#subprocess)
+ [PowerShellを複数行実行したい場合](#powershellを複数行実行したい場合)
+ [PowerShellのファイルを実行したい場合](#powershellのファイルを実行したい場合)

## subprocess
subprocessは新しいプロセスを開始して、標準出力の結果を取得することができる。今回、PowerShellのコマンドをPython上で実行するために、```subprocess.run```を使う。PowerShellのコマンド列をリストで渡す。```capture_output=True, text=True```と指定することで標準出力をキャプチャしテキストとして出力する。出力結果は```stdout```で取得できる。

```python
import subprocess

cmd = "Get-Date"
ret = subprocess.run(['powershell','-Command', cmd], capture_output=True, text=True)
print(ret)

# CompletedProcess(args=['powershell', '-Command', 'Get-Date'], returncode=0, stdout='\n2024年10月5日 22:25:50\n\n\n', stderr='')

print(ret.stdout)

# 2024年10月5日 22:26:29
```

[戻る](#目次)

## PowerShellを複数行実行したい場合
複数行実行したい場合は、コマンドを```""" """```で括ってあげればよい。例として下記記事に記載したUSBデバイスから、USBメモリを無効化するPowerShellスクリプトを```subprocess.run```で実行する場合は。

https://qiita.com/tapitapi/items/b81cff80d7de14276a84

```python
import subprocess

cmd = """
$devlist = Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -match '^USB' }

#USB 大容量記憶装置を無効化---------------------------
foreach ($dev in $devlist) {
    if ($dev.FriendlyName -like "USB 大容量記憶装置") {
        Write-Output "Disable : $($dev.Class) : $($dev.FriendlyName) : $($dev.InstanceId)"
        # デバイスを無効にする
        Disable-PnpDevice -InstanceId $dev.InstanceId -Confirm:$false
    }
}
$current_devlist = Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -match '^USB' }
Write-Output $current_devlist
"""
ret = subprocess.run(['powershell','-Command', cmd], capture_output=True, text=True)

print(ret.stdout)
```
```:結果
Disable : USB : USB 大容量記憶装置 : USB\VID_090C&PID_1000\...

Status     Class           FriendlyName                                                                     InstanceId
------     -----           ------------                                                                     ----------
OK         USB             USB ルート ハブ (USB 3.0)                                                        USB\ROOT...
OK         USB             USB ルート ハブ (USB 3.0)                                                        USB\ROOT...
Error      USB             USB 大容量記憶装置                                                               USB\VID_...
OK         USB             汎用 USB ハブ                                                                    USB\VID_...
OK         HIDClass        USB 入力デバイス                                                                 USB\VID_...
OK         HIDClass        USB 入力デバイス                                                                 USB\VID_...
OK         USB             USB Composite Device                                                             USB\VID_...
OK         Bluetooth       インテル(R) ワイヤレス Bluetooth(R)                                              USB\VID_...
```

[戻る](#目次)

## PowerShellのファイルを実行したい場合
```powershell -File```で実行する。同階層にあるPowerShellスクリプトファイル```ps_sample.ps1```に引数を指定して実行する場合の例は下記の通り。

```python:pythonファイル
import subprocess

file_path = 'ps_sample.ps1'
args = ["引数1","引数2"]
ret = subprocess.run(['powershell','-File', file_path] + args , capture_output=True, text=True)

print(ret.stdout)

# 引数1
# 引数2
```

```powershell:ps_sample.ps1
Write-Output $Args[0]
Write-Output $Args[1]
```

[戻る](#目次)