PowerShell VBAでPowerShellを実行して結果を取得する(Run編)【初実験編08】

2018/10/05PowerShellEXCEL,PowerShellの基本,VBA,Wscript.shell,Scripting.FileSystemObject,CreateObject

記事内に広告が含まれています。

Excel(VBA)からPowerShellを実行して、結果をセルに出力してみる

今回は、前回目障りだったPowerShellの実行画面は非表示にして、実行結果も取得できるように工夫した実装を、Runメソッドを使った方法で試してみます。

Runメソッドを使うと、PowerShellの実行結果をテンポラリーファイルに保存する必要があるため、少し実装が膨らみますが、
処理の完了を待つことができるため、sleepを入れて処理が完了するのを監視する必要はありません。

前回同様に実行結果は、名前参照を設定した結果出力用のセルを準備し、そこに表示させるように実装します。

過去の投稿「Excel お手軽名前参照」を見て、結果出力用のセルに名前を付けます
("testCell"という名前にしました)

Runメソッドを用いた実装

コマンドボタンを配置して、クリックイベントのSubプロシージャを実装します

今回、下の宣言は、標準モジュールのコード内でグローバルで持ちました。

' テンポラリーファイルを扱うオブジェクト宣言
Private objFSO As Object

' WshShellを扱うオブジェクト宣言
Private objWshShell As Object</pre>
クリックイベントではこんな感じ。
<pre class="lang:default decode:true">Sub ボタン1_Click()
    
    Dim cmdStr As String
    Dim strResult As String

    ' 簡単なコマンドレットの構文を作成(DOSの「dir C:\実験」と同じ)
    cmdStr = "Get-ChildItem 'C:\実験'"
   
    ' PowerShellの実行(Execコマンド使用バージョン)
    strResult = RunPowerShell(cmdStr)

    ' 名前参照セルに、結果を設定する
    Range("testCell").Value = strResult

End Sub

 RunPowerShell()の中身

コマンドを受けて、実行(結果はテンポラリー出力)し、出力結果を自ら読み込んで結果として返します

' **************************************************
' PowerShellの実行(Runコマンド使用バージョン)
' **************************************************
Private Function RunPowerShell(cmdStr As String) As String

    ' テンポラリーファイルを扱うオブジェクトを取得する
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    ' WshShellを扱うオブジェクト(PowerShellの実行用)を取得する
    Set objWshShell = CreateObject("WScript.Shell")

    ' PowerShellの実行コマンドレット構文を実行して結果を得る
    RunPowerShell = GetPowerShellResult(cmdStr)

    ' 後処理(オブジェクトの解放)
    If Not (objFSO Is Nothing) Then
        Set objFSO = Nothing
    End If
    If Not (objWshShell Is Nothing) Then
        Set objWshShell = Nothing
    End If

End Function

' **************************************************
' PowerShellを実行し結果を取得する
' **************************************************
Function GetPowerShellResult(cmdStr) As String
    
    Dim result As String
    Dim objTemporary As Object
    Dim tempPath As String
    
    ' テンポラリーファイル名を取得する
    tempPath = GetTempFilePath()
    
    ' Rnuコマンド、非表示(0)で実行して完了を待つ(結果はテンポラリーファイル出力する)
    '  -NoLogo                          見出しを出さない
    '  -ExecutionPolicy RemoteSigned    実行権限を設定
    '  -Command                         コマンド引数(これ以降にPowerShellのコマンドレット構文を記載)
    Call objWshShell.Run("powershell -NoLogo -ExecutionPolicy RemoteSigned -Command " _
                         &amp; """" &amp; cmdStr &amp; " | Out-File -filePath " &amp; tempPath &amp; " -encoding Default""", 0, True)

    ' 読み込み専用(1)でテンポラリーファイルを読み込む
    Set objTemporary = objFSO.OpenTextFile(tempPath, 1)

    ' ファイルポインターを判断して結果を読む
    If objTemporary.AtEndOfStream Then
        result = ""
    Else
        result = objTemporary.ReadAll
    End If
    
    objTemporary.Close
    
    ' テンポラリーファイルを削除
    Call objFSO.DeleteFile(tempPath, True)

    ' 出力結果を返す
    GetPowerShellResult = result

End Function

' **************************************************
' フルパスのテンポラリーファイル名を生成する
' **************************************************
Function GetTempFilePath() As String

    Dim strTemporaryName As String
    
    ' フルパスのテンポラリーファイル名を作る
    strTemporaryName = Environ$("temp") &amp; "\" &amp; objFSO.GetTempName
        
    ' テンポラリーファイルを新規作成する
    Call objFSO.CreateTextFile(strTemporaryName)
    
    ' フルパスのテンポラリーファイル名を返す
    GetTempFilePath = strTemporaryName

End Function

Rnuメソッド(Call objWshShell.Run()部分)は、非表示(0)かつ完了を待つ(True)引数で実行している。

PowerShell Treeをファイルにリダイレクトしてみた【初実験編01】
PowerShell 同一階層のファイル名一覧をテキストファイルにリダイレクトしてみる【初実験編02】
PowerShell 起動方法(Windows10)【初実験編03】
PowerShell ファイル名の一括置換【初実験編04】
PowerShell ファイル検索【初実験編05】
PowerShell 文字列検索【初実験編06】
PowerShell VBAでPowerShellを実行して結果を取得する(Exec編)【初実験編07】
PowerShell VBAでPowerShellを実行して結果を取得する(Run編)【初実験編08】
PowerShell UNIXのシェルやDOSコマンド【初実験編09】

システムトラストでは一緒に働いていただける仲間を募集中です。
株式会社システムトラスト

システムトラストでは、システムエンジニア、プログラマーなどを随時募集中です。気軽にご相談ください。

お問合せ