0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PowerShellスクリプトでのExcel操作

0
Last updated at Posted at 2025-04-22

概要

PowerShellスクリプトでのExcel操作方法について
備忘録として記載いたします。

実行環境

windows:Windows11Pro 23H2
Windows PowerShell:5.1.26100.4061

PowerShellのバージョン確認

確認コマンド:$PSVersionTable

PowerShellとWindows PowerShellの違い

下記のサイトが参考になります。

実行ポリシーの確認・変更

現在の実行ポリシーを確認する方法

Get-ExecutionPolicy

Restrictedである場合はスクリプトを実行できない。
管理者権限で実行ポリシーを変更する

Set-ExecutionPolicy RemoteSigned

再度、実行ポリシーを確認して、
RemoteSignedに変更されていることを確認する。

実行ポリシー変更スクリプト

RemoteSignedに変更してスクリプトの実行を可能にしたい場合

change_RemoteSigned.bat
@echo off
setlocal

:: PowerShellの現在の実行ポリシーを取得
for /f "tokens=* usebackq" %%i in (`powershell -Command "Get-ExecutionPolicy -Scope LocalMachine"`) do set policy=%%i

echo 現在の実行ポリシーは: %policy%

:: RestrictedならRemoteSignedに変更
if /i "%policy%"=="Restricted" (
    echo 実行ポリシーがRestrictedのため、RemoteSignedに変更します(管理者権限が必要)...

    :: 管理者権限でPowerShellを起動し、ポリシー変更を実行
    powershell -NoProfile -ExecutionPolicy Bypass -Command ^
        "Start-Process PowerShell -Verb RunAs -ArgumentList '-NoProfile -Command \"Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force\"'"

    echo 実行ポリシー変更コマンドを管理者権限で実行しました。
    echo PowerShellウィンドウが表示され、変更が完了するまで閉じないでください。
) else (
    echo 実行ポリシーの変更は不要です。
)

echo Enterキーを押下して画面を閉じてください。
endlocal
pause

Restrictedに変更してスクリプトの実行を禁止にしたい場合

change_Restricted.bat
@echo off
setlocal

:: PowerShellの現在の実行ポリシーを取得
for /f "tokens=* usebackq" %%i in (`powershell -Command "Get-ExecutionPolicy -Scope LocalMachine"`) do set policy=%%i

echo 現在の実行ポリシーは: %policy%

:: RemoteSignedならRestrictedならに変更
if /i "%policy%"=="RemoteSigned" (
    echo 実行ポリシーがRemoteSignedのため、Restrictedに変更します(管理者権限が必要)...

    :: 管理者権限でPowerShellを起動し、ポリシー変更を実行
    powershell -NoProfile -ExecutionPolicy Bypass -Command ^
        "Start-Process PowerShell -Verb RunAs -ArgumentList '-NoProfile -Command \"Set-ExecutionPolicy Restricted -Scope LocalMachine -Force\"'"

    echo 実行ポリシー変更コマンドを管理者権限で実行しました。
    echo PowerShellウィンドウが表示され、変更が完了するまで閉じないでください。
) else (
    echo 実行ポリシーの変更は不要です。
)

echo Enterキーを押下して画面を閉じてください。
endlocal
pause

注意点

・param はスクリプトの先頭に配置する必要がある。
 関数定義の後に param を記述すると、PowerShell がスクリプトの実行時に param を認識できず、
 エラーになる。
・スクリプト内に日本語の表記が存在しているとエラーとなる場合がある。
 解決策として、ファイルの拡張子を.txtにして
 メモ帳を開いて「名前を付けて保存」の選択時に「エンコード」の項目から「UTF-8(BOM 付き)」を選択する。
 そして再度拡張子を.ps1にしてスクリプトを実行する。

batファイルの使用

test.bat
@echo off
powershell -NoProfile -ExecutionPolicy Bypass -File "test.ps1"

iniファイルから取得

config.ini
[VEHICLE]
train = train
bike = bike
car = car

[BIRTHDAY]
may = may
june = june
july = july
get_ini.ps1
function Get-IniContent {
    param (
        [string]$filePath
    )
    
    # 結果を格納するOrderedハッシュテーブル
    $iniData = [ordered]@{}

    # ファイル内容を解析
    $section = $null # 初期化
    switch -regex -file $filePath {
        "^\[(.+)\]$" {
            $section = $matches[1]
            $iniData[$section] = @{}
        }
        "^(.+?)\s*=\s*(.+)$" {
            if ($section) {
                $key, $value = $matches[1], $matches[2]
                $iniData[$section][$key] = $value
            } else {
                Write-Error "セクションが未定義のままキーと値にアクセスしています: $($matches[1]) = $($matches[2])"
            }
        }
    }
    return $iniData
}
# INIファイルのパスを指定して読み込み
$filePath = "config.ini"
$iniData = Get-IniContent -filePath $filePath

# セクションごとにデータを出力
foreach ($section in $iniData.Keys) {
    Write-Host "[$section]"
    foreach ($key in $iniData[$section].Keys) {
        Write-Host "$key = $($iniData[$section][$key])"
    }
    Write-Host ""
}    

# 指定のセクションのみ出力
foreach ($key in $iniData["BIRTHDAY"].Keys) {
    Write-Host "$key = $($iniData["BIRTHDAY"][$key])"
}


チェックボックスの使用

test.ps1
# 必要なアセンブリをロード
Add-Type -AssemblyName System.Windows.Forms

# フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "項目と教科選択"
$form.Width = 600
$form.Height = 300

# ウィンドウの「×」ボタンが押された際の処理を追加
$form.Add_FormClosing({
    param([System.Object]$sender, [System.Windows.Forms.FormClosingEventArgs]$e)
    $result = [System.Windows.Forms.MessageBox]::Show(
        "スクリプトを終了しますか?",
        "確認",
        [System.Windows.Forms.MessageBoxButtons]::YesNo,
        [System.Windows.Forms.MessageBoxIcon]::Question
    )

    if ($result -eq [System.Windows.Forms.DialogResult]::Yes) {
        Write-Host "スクリプトを終了しました。"
        # イベントループを終了
        $form.Dispose()
    } else {
        $e.Cancel = $true # フォームの閉じ動作をキャンセル
    }
})

# ラベルの作成
$label = New-Object System.Windows.Forms.Label
$label.Text = "項目を選んでください"
$label.Font = New-Object System.Drawing.Font("Arial", 10)
$label.AutoSize = $true
$label.Location = New-Object System.Drawing.Point(20, 20)
$form.Controls.Add($label)

# チェックボックス1
$checkbox1 = New-Object System.Windows.Forms.CheckBox
$checkbox1.Text = "項目1"
$checkbox1.Location = New-Object System.Drawing.Point(20, 50)
$form.Controls.Add($checkbox1)

# チェックボックス2
$checkbox2 = New-Object System.Windows.Forms.CheckBox
$checkbox2.Text = "項目2"
$checkbox2.Location = New-Object System.Drawing.Point(120, 50)
$form.Controls.Add($checkbox2)

# チェックボックス3
$checkbox3 = New-Object System.Windows.Forms.CheckBox
$checkbox3.Text = "項目3"
$checkbox3.Location = New-Object System.Drawing.Point(220, 50)
$form.Controls.Add($checkbox3)

# ラベルの作成(教科を選んでください)
$subjectlabel = New-Object System.Windows.Forms.Label
$subjectlabel.Text = "教科を選んでください"
$subjectlabel.Font = New-Object System.Drawing.Font("Arial", 10)
$subjectlabel.AutoSize = $true
$subjectlabel.Location = New-Object System.Drawing.Point(20, 80)
$form.Controls.Add($subjectlabel)

# 教科チェックボックス
$SubjectEnglish = New-Object System.Windows.Forms.CheckBox
$SubjectEnglish.Text = "英語"
$SubjectEnglish.Location = New-Object System.Drawing.Point(20, 100)
$form.Controls.Add($SubjectEnglish)

$SubjectMath = New-Object System.Windows.Forms.CheckBox
$SubjectMath.Text = "数学"
$SubjectMath.Location = New-Object System.Drawing.Point(120, 100)
$form.Controls.Add($SubjectMath)

$SubjectPhysics = New-Object System.Windows.Forms.CheckBox
$SubjectPhysics.Text = "物理"
$SubjectPhysics.Location = New-Object System.Drawing.Point(220, 100)
$form.Controls.Add($SubjectPhysics)

# 選択された「項目」と「教科」を格納する変数
$selectedItems = [ref] "未登録"
$subjectItems = [ref] "未登録"

# OKボタン
$okButton = New-Object System.Windows.Forms.Button
$okButton.Text = "OK"
$okButton.Location = New-Object System.Drawing.Point(150, 200)
$okButton.Add_Click({
    $selectedItems.Value = ""
    $subjectItems.Value = ""

    if ($checkbox1.Checked) {$selectedItems.Value += "項目1 "}
    if ($checkbox2.Checked) {$selectedItems.Value += "項目2 "}
    if ($checkbox3.Checked) {$selectedItems.Value += "項目3 "}
    if ($SubjectEnglish.Checked) {$subjectItems.Value += "English"}
    if ($SubjectMath.Checked) {$subjectItems.Value += "Math"}
    if ($SubjectPhysics.Checked) {$subjectItems.Value += "physics"}

    if (-not ($selectedItems.Value -and $subjectItems.Value)) {
        [System.Windows.Forms.MessageBox]::Show("項目と教科を最低1つずつ選択してください。", "警告")
        return
    }

    $form.DialogResult = [System.Windows.Forms.DialogResult]::OK
})
$form.Controls.Add($okButton)

# フォームを表示
$result = $form.ShowDialog()

# フォームを閉じた後の選択を10秒間表示
Write-Host "選択された項目: $($selectedItems.Value)"
Write-Host "選択された教科: $($subjectItems.Value)"


if($subjectItems.Value -eq "Math"){
    Write-Host "数学を選択しました"
}else{
    # ポップアップの表示
    [System.Windows.Forms.MessageBox]::Show("すぐに終了します。OKボタンを押下してください。", "警告")
    # スクリプトの終了
    exit
}
# 10秒間ログを表示する
Start-Sleep -Seconds 10

実行結果
image.png

COMオブジェクトの解放

ComObjectfree.ps1
# COMオブジェクトの作成
$excel = New-Object -ComObject Excel.Application

# 何らかの操作を実行
$excel.Visible = $true

# アプリケーションを終了
$excel.Quit()

# COMオブジェクトの解放
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel) | Out-Null
$excel = $null
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?