【PowerShell】PowerShellからINIファイルの設定値を取得するには①

この記事では、PowerShellからINIファイルの設定値を取得する方法についてご説明します。

【動画】PowerShellからINIファイルの設定値を取得する実際の動き

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


今回はINIファイルを1行ずつ確認してセクション名とキー名に該当する値を取得しています。

セクション名とキー名に該当する値が見つかったらコンソールにその値を出力しています。

マクロ作成の流れ

STEP.1
INIファイルにアクセスして行を参照する
INIファイルにアクセスして行を参照します。
STEP.2
INIファイルの行にセクション名が存在する場合は、そのセクション名を取得する
INIファイルの行にセクション名が存在する場合は、そのセクション名を取得します。
行にセクション名が存在するかは、正規表現を使って特定します。
STEP.3
セクション名に該当するキー名と値を取得する
セクション名に該当するキー名と値を取得します。
行にセクション名が存在するかは、正規表現を使って特定します。
取得したセクション名はハッシュテーブルに格納しておきます。
STEP.4
行にキーと値が含まれる場合、かつ現在のセクションが存在する場合、そのキー名と値を取得する
行にキーと値が含まれる場合、かつ現在のセクションが存在する場合、そのキー名と値を取得します。
取得したキー名と値はハッシュテーブルに格納しておきます。
STEP.5
指定されたセクション名がハッシュテーブルに存在するか確認し、さらに指定されたキーがそのセクション内に存在するか確認し、キーが存在する場合はコンソールに表示します
指定されたセクション名がハッシュテーブルに存在するか確認し、さらに指定されたキーがそのセクション内に存在するか確認し、キーが存在する場合はコンソールに表示します。

INIファイルの例

今回は下のINIファイルを用意しました。

セクション名に「connVal」を、キー名に「comVal」を指定して実行するとコンソール上に「vb1」の値が出力されています。

コードの例

# セクション名を指定する
$sectionName = "connVal"

# キー名を指定する
$keyName = "comVal"

# INIファイルのフルパスを指定する
$iniFilePath = "C:¥work¥10_勉強¥18_PowerShell¥0027¥info.ini"

if (-Not (Test-Path $iniFilePath)) {

    # INIファイルが存在しない場合

    # INIファイルが存在しない旨のメッセージを表示する
    Write-Host "指定されたINIファイルが存在しないので処理を終了します" 

    # 処理を終了する
    exit
}

# INIファイルの内容を格納するための空のハッシュテーブルを用意する
$iniContent = @{}

# 現在のセクション名を格納する変数を(nullで)初期化します。
$currentSection = $null 

# INIファイルの行数文処理を繰り返すループ
Get-Content $iniFilePath | ForEach-Object {

    if ($_ -match '^¥[(.+)¥]$') {
    
        # 行の最初の文字が [ で、最後文字が ] の場合
        # ⇒(.+)は文字列を指す

        # 「^」は行の始めを表し、「$」は行の終わりを表す
        # 正規表現において、[ と ] は特殊な意味を持つメタ文字なので、[ と ] の前に ¥ の文字を置いてはエスケープさせている
        
        # キャプチャグループ(今回はセクション名)を取得する
        $currentSection = $matches[1]

        # セクション名をiniContentに追加する
        $iniContent[$currentSection] = @{}
        
    }
    elseif ($_ -match '^(.+)=(.+)$' -and $null -ne $currentSection) {

        # 行がキー名と値を含む場合(key=val の場合)、かつ現在のセクションが存在する場合

        # キー名を取得する(1つ目の(.+))
        $key = $matches[1].Trim()

        # 値を取得する(2つ目の(.+))
        $value = $matches[2].Trim()

        # iniContentにキーと値を現在のセクションに追加する
        $iniContent[$currentSection][$key] = $value
    }
}

if ($iniContent.ContainsKey($sectionName)) {

    # iniContentに指定されたセクション名が存在する場合

    if ($iniContent[$sectionName].ContainsKey($keyName)) {

        # 指定されたキーが存在する場合
        
        # キーに対応する値を取得する
        $value = $iniContent[$sectionName][$keyName]

        # 取得した値を出力する
        Write-Host $value

    } else {

        # 指定されたキーが存在しない場合

        # エラーメッセージを出力する
        Write-Host "指定したキーがセクション内に存在しません: $keyName"
    }

} else {

    # iniContentに指定されたセクション名が存在しない場合
    
    # エラーメッセージを出力する
    Write-Host "指定したセクションがINIファイル内に存在しません: $sectionName"
}

注目すべきコード①

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

# セクション名を指定する
$sectionName = "connVal"

# キー名を指定する
$keyName = "comVal"

# INIファイルのフルパスを指定する
$iniFilePath = "C:¥work¥10_勉強¥18_PowerShell¥0027¥info.ini"

コードの説明

以上のコードは、セクション名とキー名、INIファイルのフルパスを取得するコードです。

注目すべきコード②

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

if (-Not (Test-Path $iniFilePath)) {

    # INIファイルが存在しない場合

    # INIファイルが存在しない旨のメッセージを表示する
    Write-Host "指定されたINIファイルが存在しないので処理を終了します" 

    # 処理を終了する
    exit
}

コードの説明

以上のコードは、INIファイルの有無をチェックするコードです。

指定したINIファイルのフルパスにINIファイルが存在しない場合は処理を終了します。

コードの詳細

10行目のコードで使用しているTest-Pathは、指定したINIファイルのフルパスが存在するかを確認するコマンドレットです。

-Notは論理否定演算子で、「~でない場合」を意味します。

以上により、10行目のIF文は「INIファイルのフルパスがが存在しない場合」という条件になります。

フルパスが存在しない場合は15行目でエラーメッセージを出力して18行目のexitメソッドを実行し処理を終了させています。

注目すべきコード③

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

# INIファイルの内容を格納するための空のハッシュテーブルを用意する
$iniContent = @{}

# 現在のセクション名を格納する変数を(nullで)初期化します。
$currentSection = $null

コードの説明

以上のコードは、INIファイルの内容を格納するための空のハッシュテーブルを用意し、現在のセクション名を格納する変数を(nullで)初期化する処理のコードです。

iniContentはINIファイルにあるセクション名やキー名、値を格納するハッシュテーブルです。

currentSectionはINIファイルのセクション名を格納する変数です。

iniContentは@{}で、currentSectionはnullで初期化しておきます。

注目すべきコード④

次に見て頂きたいのは28行目です。

# INIファイルの行数文処理を繰り返すループ
Get-Content $iniFilePath | ForEach-Object {

コードの説明

以上のコードは、INIファイルの行数文処理を繰り返すループのコードです。

このループはINIファイルの先頭行から最終行まで1行ずつ確認するためのループです。

注目すべきコード⑤

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

    if ($_ -match '^¥[(.+)¥]$') {
    
        # 行の最初の文字が [ で、最後文字が ] の場合
        # ⇒(.+)は文字列を指す

        # 「^」は行の始めを表し、「$」は行の終わりを表す
        # 正規表現において、[ と ] は特殊な意味を持つメタ文字なので、[ と ] の前に ¥ の文字を置いてはエスケープさせている
        
        # キャプチャグループ(今回はセクション名)を取得する
        $currentSection = $matches[1]

        # セクション名をiniContentに追加する
        $iniContent[$currentSection] = @{}
        
    }

コードの説明

以上のコードは、参照している行にセクションが存在するかを確認し、存在している場合はそのセクション名を取得してiniContentに格納する処理のコードです。

コードの詳細

30行目のコードでは、参照している行にセクションが存在するかを判定するIFです。

[ と ] で囲まれた文字列で記述される文字列(今回のサンプルだと[connVal]や[tableInfo])がセクション名になるので、正規表現でこのセクション名を特定します。

このIFでは「^¥[(.+)¥]$」にマッチする文字列がセクション名になります。

以上の条件を1つずつ解説します。

①^

「^」は、行の始めを表します。

セクション名を特定する場合は先頭文字から見ていくため「^」を最初の条件に指定しています。

②¥[

「¥[」は、角括弧 [ を特定する条件です。

セクション名は角括弧 [ から始まるので角括弧 [ を条件に指定します。

③(.+)

(.+)は1文字以上の任意の文字列をグループ化します。

[connVal]の場合は [ と ] を除いたconnValの部分になります。

④¥]

「¥]」は、角括弧 ] を特定する条件です。

セクション名は角括弧 ] で終わるので角括弧 ] を条件に指定します。

⑤$

$は行の終わりを表します。

セクション名は ] で終わるので、 $を条件に指定します。

39行目のコードでは、[ と ] を除いたセクション名( (.+) )を取得してcurrentSectionを格納しています。

[ と ] を除いたセクション名( (.+) )は、$matches[1]から取得することができます。

42行目のコードでは、セクション名をiniContentに追加します。

注目すべきコード⑥

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

    elseif ($_ -match '^(.+)=(.+)$' -and $null -ne $currentSection) {

        # 行がキー名と値を含む場合(key=val の場合)、かつ現在のセクションが存在する場合

        # キー名を取得する(1つ目の(.+))
        $key = $matches[1].Trim()

        # 値を取得する(2つ目の(.+))
        $value = $matches[2].Trim()

        # iniContentにキーと値を現在のセクションに追加する
        $iniContent[$currentSection][$key] = $value
    }

コードの説明

以上のコードは、行がキー名と値を含む場合(key=val の場合)、かつ現在のセクションが存在する場合に、キー名と値を取得する処理のコードです。

コードの詳細

45行目のコードでは、行がキー名と値を含む場合(key=val の場合)、かつ現在のセクションが存在するかを判定するIF文のコードです。

「^(.+)=(.+)$」は、行にキー名と値が含まれているかを判定する条件ですが、この条件の中身を1つずつ解説します。

①^

「^」は、行の始めを表します。

行がキー名と値を含むかどうかを特定する場合に、行の先頭文字から見ていくため「^」を最初の条件に指定しています。

②(.+)=(.+)

INIファイルのキー名と値の記述は「comVal=vb1」(例)なので、条件に「(.+)=(.+)」を指定します。

左の(.+)に該当する値(comVal)は50行目の$matches[1]に格納されて、右の(.+)に該当する値(vb1)は53行目の$matches[2]に格納されます。

$matches[1](comVal)と$matches[2](vb1)の値はそれぞれ変数keyと変数valueに格納されます。

56行目のコードでは、iniContentにキーと値を現在のセクションに追加します。

注目すべきコード⑦

次に見て頂きたいのは60行目です。

if ($iniContent.ContainsKey($sectionName)) {

コードの説明

以上のコードは、iniContentに指定されたセクション名が存在するかどうか判定するIFです。

ContainsKeyメソッドは、ハッシュテーブル内にContainsKeyメソッドの引数に指定した値が存在するかを特定することができます。

今回はContainsKeyメソッドにセクション名を指定しているので、iniContent内に指定されたセクション名が存在するかを確認することができます。

注目すべきコード⑧

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

    if ($iniContent[$sectionName].ContainsKey($keyName)) {

        # 指定されたキーが存在する場合
        
        # キーに対応する値を取得する
        $value = $iniContent[$sectionName][$keyName]

        # 取得した値を出力する
        Write-Host $value

コードの説明

以上のコードは、指定されたキーが存在する場合にキーに対応する値をコンソールに出力する処理です。

コードの詳細

60行目のコードでは、指定されたキーが存在するかどうか判定し、存在する場合は69行目でキーに対応する値を取得します。

取得した72行目では、取得したキーに対応する値をコンソールに出力します。

注目すべきコード⑨

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

    } else {

        # 指定されたキーが存在しない場合

        # エラーメッセージを出力する
        Write-Host "指定したキーがセクション内に存在しません: $keyName"

コードの説明

以上のコードは、指定されたキーが存在しない場合に、指定したキーがセクション内に存在しないことを知らせるエラーメッセージを出力する処理のコードです。

注目すべきコード⑩

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

} else {

    # iniContentに指定されたセクション名が存在しない場合
    
    # エラーメッセージを出力する
    Write-Host "指定したセクションがINIファイル内に存在しません: $sectionName"
}

コードの説明

以上のコードは、iniContentに指定されたセクション名が存在しない場合に、指定したセクションがINIファイル内に存在しないことを知らせるエラーメッセージを出力する処理のコードです。

動作確認

INIファイルの例」をご覧ください。

最後に

この記事では、PowerShellからINIファイルの設定値を取得する方法についてご説明しました。

PowerShellからINIファイルの設定値を取得したい場合は、本記事を参考にして頂けたら幸いです。

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

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

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

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