レジストリ更新コマンドの概要
前々回、前回と、レジストリを操作する基本的なコマンドレットを紹介しました。今回より、レジストリを更新するプログラム(PowerShellスクリプト)を作成します。
無条件でレジストリキーを新規作成あるいは更新してしまうコマンドも作成できますが、レジストリに関しては、間違って操作するとWindowsが動作不良になる危険をはらんでいます。
そこで、以下のような流れのプログラム Set-RegistryKey.ps1 を作成します。
- 指定したレジストリキーとレジストリキーの値があるかどうかを確認する。
- すでにレジストリキーがあれば、現在の値を表示し、更新していいかどうかユーザーに確認する。
- ユーザーの確認がとれれば、指定した値に更新する。
もちろん、指定したレジストリキーやその値が存在しないのであれば、新規作成します。
3つのコマンドラインパラメータを指定して、以下のように使用することにします。
Set-RegistryKey キーのパス エントリ名 エントリ型 エントリ値
たとえば、HKCU:\Testというレジストリキーに MyName というエントリを作成し、文字列型としてMyComという値を設定するのであれば、以下のように実行します。
Set-RegistryKey HKCU:\Test MyName String MyCom
また、パラメータが1つだけの時はキーを作成するのみ、パラメータが2つのときは、キーとエントリを作成、パラメータが3つまたは4つの時はキーとエントリを作成した上で、エントリに値を設定するものとします。パラメータの順番は固定ですが、エントリ型は省略してもかまわないことにします。
プログラム全体を全部一度に作成するのは大変なので、まずは、レジストリキーやエントリを作成するだけのプログラムを作ってみましょう。
※ 一気に大きなプログラムを作成すると、思い通りに動かなかったときに何が原因かを突き止めるのが大変になります。まずは小さなプログラムから、動作を確認しながら拡張した方が確実です。
コマンドラインパラメータの分析
まずは、コマンドラインパラメータを取得する前処理のプログラムを作成します。
コマンドラインパラメータの最初の4つだけを取得し、5つ以上パラメータを指定されても、5つめ以降は無視するようにします。コマンドライン引数の数は変数argsのlengthプロパティで取得できます。
最大4つのパラメータを、以下の変数に代入して処理することにします。
<ここから表組み> 変数名 代入する内容 keypath レジストリキーのパス entry エントリ名 type エントリの型 value エントリの値 <ここまで表組み>
最初のプログラムは次の通りです。
if ($args.length -eq 0) #パラメータがないとき
{
#ヘルプを表示
"help"
} elseif ($args.length -eq 1) #パラメータが1つの時
{
"レジストリキーを作成します。"
$keypath = $args[0]
} elseif ($args.length -eq 2) #パラメータが2つの時
{
"レジストリキーとエントリを作成します。"
$keypath = $args[0]
$entry = $args[1]
} elseif ($args.length -eq 3) #パラメータが3つの時
{
"レジストリキーと文字列型エントリを作成し、値を保存します。"
$keypath = $args[0] #最初のパラメータはレジストリキーのパス
$entry = $args[1] #2番目のパラメータはエントリ名
$type = "String"
$value = $args[2]
} else { #パラメータが4つ以上の時
"レジストリキーとエントリを作成し、値を保存します。"
$keypath = $args[0] #最初のパラメータはレジストリキーのパス
$entry = $args[1] #2番目のパラメータはエントリ名
$type = $args[2]
$value = $args[3]
}
#テスト表示
"keypath = " + $keypath
"entry = " + $entry
"type = " + $type
"value = " + $value
ここで注意が必要なのは、パラメータが3つしか指定されていない場合です。本来、パラメータは4つ必要なのですが、3つのみの場合は、3番目のパラメータをエントリ値として処理し、指定のないtype変数には既定値としてStringを代入します。つまり、エントリ型を指定しない場合は、エントリ型を文字列型とします。
試しに実行してみます。パラメータが3個未満のとき、3個のとき、4個以上の時、それぞれを実行してみます。
うまく機能していることがわかります。
※ コマンドラインパラメータを利用する際、args配列オブジェクトをそのまま使うこともできます。多くのパラメータを一つ一つ順に処理するときなどは、むしろ、配列オブジェクトとforループを使うとプログラムがすっきりして、スマートになります。しかし、今回のプログラムの場合、キーのパス、エントリ名...といった異なる意味を持つ値をすべて同じ配列名で処理すると、どれが何を意味するのかわかりにくくなって、プログラミングミスを招きやすいと考えられます。そこで、今回はそれぞれの値の意味がわかりやすい、keypath、entryなどの通常の変数を使うことにしました。
キーの作成の操作
コマンドラインパラメータの取得がうまくいったことを確認したら、実際にレジストリキーやエントリを作成するようにしましょう。
レジストリキーを作成するのはNew-Itemコマンドレットです。パラメータが1つの時の処理に、以下のようなレジストリキーを作成する行を追加します。
New-Item $keypath
パラメータが2つの場合は、エントリも作成しますので、以下のように2行を追加します。
New-Item $keypath
New-ItemProperty $keypath $entry
パラメータが3つの場合は、エントリに値も保存しますので、以下のように追加します。
New-Item $keypath
New-ItemProperty $keypath $entry -PropertyType $type -Value $value
以上の行を追加したら、実際に実行して正しくレジストリを作成できるかどうか、試してみましょう。
※ 今回のプログラムの全文は、本ページ末尾に掲載しています。
まず、既存のレジストリキーを壊さないように、レジストリエディタを開いて、レジストリ内容を確認してください。筆者の環境では、HKCU:\Testというレジストリキーは存在しないので、テストとして、HKCU:\Testを作成してみることにします。レジストリキーの中にエントリMyNameを作成し、そこに値として文字列のMyComを保存します。
PowerShellスクリプト、Set-RegistryKey.ps1を以下のように実行します。
Set-RegistryKey HKCU:\Test MyName String MyCom
エントリ型を省略したときは文字列型としますので、Stringを省略して次のように実行してもかまいません。
Set-RegistryKey HKCU:\Test MyName MyCom
実行したら、正しく作成されているかどうか、レジストリエディタで確認してください。既にレジストリエディタを起動しているときは、F5キーを押して表示を更新します。
テストで作成したレジストリキーを削除して、いろいろなパターンを実験してみてください。
今回のプログラム
if ($args.length -eq 0) #パラメータがないとき
{
#ヘルプを表示
"help"
} elseif ($args.length -eq 1) #パラメータが1つの時
{
"レジストリキーを作成します。"
$keypath = $args[0]
New-Item $keypath
} elseif ($args.length -eq 2) #パラメータが2つの時
{
"レジストリキーとエントリを作成します。"
$keypath = $args[0]
$entry = $args[1]
New-Item $keypath
New-ItemProperty $keypath $entry
} elseif ($args.length -eq 3) #パラメータが3つの時
{
"レジストリキーと文字列型エントリを作成し、値を保存します。"
$keypath = $args[0] #最初のパラメータはレジストリキーのパス
$entry = $args[1] #2番目のパラメータはエントリ名
$type = "String"
$value = $args[2]
New-Item $keypath
New-ItemProperty $keypath $entry -PropertyType $type -Value $value
} else { #パラメータが4つ以上の時
"レジストリキーとエントリを作成し、値を保存します。"
$keypath = $args[0] #最初のパラメータはレジストリキーのパス
$entry = $args[1] #2番目のパラメータはエントリ名
$type = $args[2]
$value = $args[3]
New-Item $keypath
New-ItemProperty $keypath $entry -PropertyType $type -Value $value
}
#テスト表示
"keypath = " + $keypath
"entry = " + $entry
"type = " + $type
"value = " + $value