【ExcelVBA】マクロが呼び出したPowershellで実行したコマンドの結果を直接取得するには

この記事では、マクロが呼び出したPowershellで実行したコマンドの結果を直接取得する方法についてご説明します。

【動画】マクロが呼び出したPowershellで実行したコマンドの結果を直接取得する実際の動き

本題に入る前に、まずは次の動画をご覧ください。


execメソッドでPowershellのコマンドを実行させるとPowershellで実行したコマンドの結果を直接取得することができます。

なお、Powershellの実行は同期起動させています。

マクロ作成の流れ

STEP.1
Powershellに実行させるコマンドを用意する
Powershellに実行させるコマンドを用意します。
STEP.2
Powershellを呼び出してSTEP.1のコマンドを実行する
Powershellを呼び出してSTEP.1のコマンドを実行します。

コードの例

Option Explicit

Sub test()

    Dim strcmd  As String   'Powershell実行コマンド用変数
    Dim wsh     As Object   'WshShellインスタンス用変数
    Dim exec    As Object   'Powershell実行結果用変数
    
    'Powershellで実行させたいコマンドを用意する
    strcmd = "powershell.exe -Command Get-ChildItem -Path '" & ThisWorkbook.Path & _
                                      "' -Recurse -File | Measure-Object | %{$_.Count}"

    'WshShellオブジェクトからインスタンスを生成する
    Set wsh = CreateObject("WScript.Shell")
    
    'Powershellコマンドを実行し、結果を取得する
    Set exec = wsh.exec(strcmd)
    
    'Powershellが実行されている間はループするDo
    Do While exec.Status = 0
    
        'Powershellが実行中の場合(exec.Statusの値が0の場合)
    
        'ループ中にユーザー操作を可能にする
        DoEvents
        
    Loop
    
    '結果を出力する
    MsgBox exec.StdOut.ReadAll

End Sub

注目すべきコード①

最初に見て頂きたいのは10行目から11行目です。

    'Powershellで実行させたいコマンドを用意する
    strcmd = "powershell.exe -Command Get-ChildItem -Path '" & ThisWorkbook.Path & _
                                      "' -Recurse -File | Measure-Object | %{$_.Count}"

コードの説明

以上のコードは、Powershellで実行させたいコマンドを用意しているコードです。

本記事では「Powershellで実行したコマンドの結果を直接取得する」ことが目的であり、コマンドの中身は記事の主題から外れるので、今回は適当なコマンドを用意しました。

ちなみにこのコマンドは、「フォルダ内にある全フォルダ配下のすべてのファイル数をカウントする」コマンドです。

注目すべきコード②

次に見て頂きたいのは14行目から17行目です。

    'WshShellオブジェクトからインスタンスを生成する
    Set wsh = CreateObject("WScript.Shell")
    
    'Powershellコマンドを実行し、結果を取得する
    Set exec = wsh.exec(strcmd)

コードの説明

以上のコードは、WshShellオブジェクトからインスタンスを生成し、Powershellコマンドを実行してその結果を取得したら結果をメッセージボックスに出力させる処理のコードです。

Powershellの実行はexecメソッドで実行され、結果は変数execに格納されます。

注目すべきコード③

次に見て頂きたいのは20行目から30行目です。

    'Powershellが実行されている間はループするDo
    Do While exec.Status = 0
    
        'Powershellが実行中の場合(exec.Statusの値が0の場合)
    
        'ループ中にユーザー操作を可能にする
        DoEvents
        
    Loop
    
    '結果を出力する
    MsgBox exec.StdOut.ReadAll

コードの説明

以上のコードは、Powershellが実行されている間はサブルーチン内で空ループ(処理は特に何もせず無限ループに近い状態にする)させてPowershellの処理を待機させる処理のコードです。

なぜこの空ループを行うのかというと、Powershellの処理が完了するより先にマクロが終了してしまわないようにするためです。(同期処理)

exec.Statusの値が0ならPowershell実行中、0以外ならPowershell実行完了です。

コードの詳細

20行目のコードは、Powershellが実行されている間は処理を繰り返すDoループです。

Powershellが実行されている場合は25行目でDoEvents関数を実行します。

DoEvents関数はループ中にユーザー操作を可能にします。

Doループに入るとExcelファイルの操作ができなくなる(Excelファイルが固まってしまう)ので、ループ中はDoEvents関数を実行し操作ができるようにしています。

30行目のコードでは、Powershellで実行したコマンドの結果をメッセージボックスに表示させています。

動作確認

今回呼び出すPowershellが実行する処理は、以下のフォルダ内のファイルの数をカウントする処理です。

マクロ実行後

マクロを実行すると、Powershellで実行したコマンドの結果がメッセージボックスに出力されました。

最後に

この記事では、マクロが呼び出したPowershellで実行したコマンドの結果を直接取得する方法についてご説明しました。

マクロが呼び出したPowershellで実行したコマンドの結果を取得したい場合は本記事を参考にしてみてくださいね。

プログラミングのスキルを習得するなら

プログラミングのスキルを習得したい、今のスキルをもっと高めたい、そう考えているなら「プログラミングスクール」がおすすめです。

プログラミングのスキルの基礎を身につけるなら「TechAcademy」で1週間の無料体験があるので、これで「プログラミングの基礎」を学ぶのにおすすめですよ。

→ TechAcademyの「1週間 無料体験」はこちら