はじめに
前回のバッチ処理の投稿の続きです。
初めてPowerShellのスクリプトを作成した時のことをまとめます。
PowerShellとは
特徴
-
.NET Framework
をベースに開発されており、オブジェクト指向の概念を取り入れています - コマンドレットと呼ばれる、より直感的で強力なコマンドを使用します
- パイプライン処理により、複数のコマンドを組み合わせて複雑な処理を実行できます
コマンドレット
PowerShellで使用される軽量で強力なコマンドです。
動詞-名詞形式: 「Get-Item
」「Set-Location
」のように、動詞と名詞を組み合わせた直感的な名前が付けられています。
役割
- システム管理: ファイルやディレクトリの操作、サービスの管理、レジストリの操作など、様々なシステム管理タスクを実行できます
- データの操作: CSVファイルやXMLファイルの解析、テキストデータの抽出など、データの操作を自動化できます
- スクリプト作成: PowerShellスクリプトを作成し、繰り返し実行する処理を自動化できます
例
-
Get-Command
: 利用可能なすべてのコマンドレットの一覧を取得します -
Get-ChildItem
: 指定されたディレクトリ内のファイルやサブディレクトリの一覧を取得します -
Set-Location
: カレントディレクトリを変更します -
Remove-Item
: ファイルやディレクトリを削除します
コマンドプロンプトとの違い
どちらもWindowsで利用できるシェル(コマンド入力画面)ですが、PowerShellは、コマンドプロンプトをより高度に、そして柔軟に使えるように進化したツールです。
特徴 | コマンドプロンプト | PowerShell |
---|---|---|
歴史 | 古くからある | 比較的新しい |
ベース | DOSコマンド | .NET フレームワーク |
コマンド | テキストベース | コマンドレット (動詞-名詞) |
機能 | 基本的な操作 | 高度な操作、スクリプト作成 |
オブジェクト指向 | × | ○ |
パイプライン処理 | シンプル | 強力 |
使い分け
- 簡単な作業: コマンドプロンプト
- 高度な作業、自動化: PowerShell
実現したこと
- バッチ処理でWindowsエクスプローラーからクラウド上のファイル名一覧をコピー ◀︎ 前回の投稿内容
- マクロ付きExcelファイル(.xlsm)のパスをPowerShellに引数として渡す ◀︎ 前回の投稿内容
- PowerShellでマクロを実行する ◀︎ 今回の投稿内容
- 取得したファイル名一覧をマクロでExcelのシートにペーストする ◀︎ 別記事の投稿内容
コードをすぐ見たい方はこちら
PowerShellスクリプトの作成手順
- テキストエディタで新しいファイルを作成する(メモ帳、Visual Studio Codeなど)
- PowerShellのコマンドレット(スクリプト)を記述する
- 拡張子を
.ps1
に変更して保存する - スクリプトの実行(今回はバッチファイルから実行)
実行ポリシーの設定
PowerShellスクリプトを実行する場合、セキュリティ上の理由から実行ポリシーが制限されていることがあります。
実行ポリシーの設定を変更して、ローカルで作成したスクリプトを実行できるようにします。
(例)
# 実行ポリシーの設定確認
PS C:¥Users¥username¥Downloads> Get-ExecutionPolicy
Restricted
# 実行ポリシーの設定変更
PS C:¥Users¥username¥Downloads> Set-ExecutionPolicy RemoteSigned
実行ポリシーを変更する際は、セキュリティリスクを考慮の上で実施してください
実行ポリシー名 | 説明 |
---|---|
Restricted | すべてのスクリプトの実行が禁止されます。最も制限の強い設定です。 |
AllSigned | デジタル署名されたスクリプトのみ実行できます。 |
RemoteSigned | ローカルで作成されたスクリプトと、デジタル署名されたリモートスクリプトのみ実行できます。一般的に最もよく使用される設定です。 |
Unrestricted | すべてのスクリプトの実行が許可されます。セキュリティリスクが高いため、注意が必要です。 |
Bypass | 実行ポリシーを完全に無視します。 |
Default | 既定の実行ポリシーを設定します。 |
Undefined | 実行ポリシーが未定義の状態です。 |
作成したコード
Param([String]$filePath) #バッチファイルから受け取る引数(ファイルパス)
$target = "Module1.PasteClipboard" #実行するマクロを指定
$excel = $null
if(-not $filePath){
$errormsg = "マクロブックのファイルパスが見つかりません"
Write-Output $errormsg
$wsobj = New-Object -ComObject wscript.shell
$result = $wsobj.popup($errormsg) #ポップアップを表示
}
try {
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$workbook = $excel.WorkBooks.Open($filePath)
$sheet = $workbook.Sheets.Item("マクロ実行") #マクロを実行するシート名
$excel.Run($target)
} catch {
Write-Output "例外エラーです"
Write-Output ('Error message: ' + $_.Exception.Message)
}
コードの説明・補足
Param([String]$filePath)
スクリプト実行時にファイルパスを引数として受け取るパラメーターを定義しています。
[]
にはパラメーターのデータ型を指定します(例: [string]
, [int]
, [bool]
など。)
Param(
[型] $ParameterName,
)
カンマでつなげて複数のパラメーターを指定することもできます。
Param(
[型] $ParameterName,
[型] $ParameterName
)
New-Object -ComObject
.NET Framework オブジェクトまたは COM オブジェクトのインスタンスを作成します。
wscript.shell
Windows Script Host (WSH) の一部で、Windows環境を操作するためのオブジェクトです。このオブジェクトを使うことで、スクリプトから様々なWindowsシステムの機能を呼び出すことができます。
主な用途
- ファイル操作: ファイルの作成、削除、コピー、移動など
- アプリケーションの実行: 外部プログラムの実行
- レジストリの操作: レジストリキーの読み書き
- 環境変数の操作: 環境変数の設定や取得
- フォルダの操作: フォルダの作成、削除
- ショートカットの作成: ショートカットの作成
$excel.WorkBooks.Open($filePath)
指定されたファイルを開きます。
$sheet = $workbook.Sheets.Item("マクロ実行")
マクロを実行するシートを取得します。
今回はマクロを定義している"マクロ実行"
というシート名を設定しています。
$excel.Run($target)
指定されたマクロを実行します。
以下の行で実行したいマクロの場所を指定しています
$target = "Module1.PasteClipboard"
- Module1: マクロが記述されているモジュールの名前
- PasteClipboard: モジュール内のマクロの名称(=プロシージャ名)
モジュールとプロシージャの関係
そもそもModule1.PasteClipboard
のような例のように、
モジュール名とプロシージャ名を指定するのは、特定のマクロ(プロシージャ)を正確に呼び出すためです。
- モジュール: プロジェクトを構成しているより小さなプログラムの構成単位
- プロシージャ: プログラムを構成する最小単位
プロシージャが命令を書いた手順書だとするとモジュールはその手順書を記述する**場所(エリア)**に相当します。
ひとつのモジュールに複数のプロシージャを記述することができます。
引用:【ゼロからわかるVBA入門】モジュールとプロシージャ
try~catch
プログラムが実行中に発生するエラーや例外を処理するための構文です。
他の言語(FW)でもよく使われる構文ですが、PowerShellでも使用することができます。
$_.Exception.Message
catchブロック内で、発生した例外に関する情報を格納しているオブジェクトのメッセージプロパティにアクセスすることで、エラーメッセージを取得します。
$_
は、パイプラインを通して渡されてきた現在のオブジェクトを表す自動変数です。
上記のcatchブロック内では、発生した例外オブジェクトを指します。
この自動変数は、システムによって自動的に生成されて特定の情報を保持します。
Write-Output
- 値の表示: 変数の中身、コマンドの実行結果などをコンソールに表示します
- パイプラインへの渡す: Write-Outputで出力された値を、次のコマンドの入力として使用します。これにより、複数のコマンドを繋げて複雑な処理を行うことができます
# 変数の値を表示
$message = "Hello, World!"
Write-Output $message
# Get-Processコマンドの結果を表示
Get-Process | Write-Output
# Get-Processの結果をWhere-Objectで絞り込み
Get-Process | Where-Object {$_.Name -eq "notepad"} | Write-Output
Get-Process
PowerShellで実行中のプロセスに関する情報を取得します。
例えば、以下のようなプロセスが表示されます
PS C:¥Users¥username¥Downloads> Get-Process
Handles NPM(K) PM(K) WS(K) CPU(s) Id ProcessName
------- ------- ------- ------- ------- -- -----------
1061 2176 11372 42860 0.03 1484 System
1227 2724 14424 54540 0.02 1844 svchost
1262 2796 14904 56088 0.01 1924 svchost
1385 3072 16432 61644 0.03 1364 svchost
1448 3180 17008 63724 0.01 2348 svchost
1483 3252 17460 65484 0.01 2088 svchost
1554 3396 18160 68204 0.01 2264 svchost
1619 3540 18860 70924 0.01 2428 svchost
1690 3684 19560 73644 0.01 2592 svchost
1761 3828 20260 76364 0.01 2756 svchost
おわりに
バッチなどの異なるスクリプト言語同士を連携させることで、より複雑な自動化タスクを実現することができそうです。
PowerShellを使えるようになることで、システム管理や業務効率化の幅が広がりそうですね!