web-dev-qa-db-ja.com

二重引用符で囲まれた文字列でオブジェクトのプロパティを使用するにはどうすればよいですか?

私は次のコードを持っています:

$DatabaseSettings = @();
$NewDatabaseSetting = "" | select DatabaseName, DataFile, LogFile, LiveBackupPath;
$NewDatabaseSetting.DatabaseName = "LiveEmployees_PD";
$NewDatabaseSetting.DataFile = "LiveEmployees_PD_Data";
$NewDatabaseSetting.LogFile = "LiveEmployees_PD_Log";
$NewDatabaseSetting.LiveBackupPath = '\\LiveServer\LiveEmployeesBackups';
$DatabaseSettings += $NewDatabaseSetting;

文字列実行コマンドでプロパティの1つを使用しようとすると:

& "$SQlBackupExePath\SQLBackupC.exe" -I $InstanceName -SQL `
  "RESTORE DATABASE $DatabaseSettings[0].DatabaseName FROM DISK = '$tempPath\$LatestFullBackupFile' WITH NORECOVERY, REPLACE, MOVE '$DataFileName' TO '$DataFilegroupFolder\$DataFileName.mdf', MOVE '$LogFileName' TO '$LogFilegroupFolder\$LogFileName.ldf'"

$DatabaseSettingsの値ではなく、$DatabaseSettings[0].DatabaseNameの値を使用しようとしますが、これは無効です。
私の回避策は、それを新しい変数にコピーすることです。

二重引用符で囲まれた文字列でオブジェクトのプロパティに直接アクセスするにはどうすればよいですか?

80
caveman_dick

変数名を二重引用符で囲まれた文字列で囲むと、変数の値に置き換えられます。

_$foo = 2
"$foo"
_

になる

_"2"
_

そうしたくない場合は、一重引用符を使用する必要があります。

_$foo = 2
'$foo'
_

ただし、プロパティにアクセスする場合、または二重引用符で囲まれた変数のインデックスを使用する場合は、その副次式を$()で囲む必要があります。

_$foo = 1,2,3
"$foo[1]"     # yields "1 2 3[1]"
"$($foo[1])"  # yields "2"

$bar = "abc"
"$bar.Length"    # yields "abc.Length"
"$($bar.Length)" # yields "3"
_

PowerShellは、そのような場合にのみ変数を展開し、それ以上は展開しません。インデックス、プロパティ、または完全な計算を含むより複雑な式の評価を強制するには、それらをサブ式演算子$( )で囲む必要があります。これにより、式が評価され、文字列に埋め込まれます。

139
Joey

@Joeyには正しい答えがありますが、$()で評価を強制する必要がある理由をもう少し付け加えます。

サンプルコードには、PowerShellのメーカーが展開を単なる変数参照に制限し、プロパティへのアクセスもサポートしないことを選択した理由を示す曖昧さが含まれています(余談ですが、ToString()オブジェクトのメソッド。これにより、「奇妙な」結果を説明できます)。

あなたの例はコマンドラインの最後に含まれています:

...\$LogFileName.ldf

オブジェクトのプロパティがデフォルトで展開された場合、上記は

...\

$LogFileNameによって参照されるオブジェクトにはldfと呼ばれるプロパティがないため、$null(または空の文字列)が変数に置き換えられます。

14
Steven Murawski

@Joeyには良い答えがあります。 String.Formatに相当するより多くの.NETルックを使用する別の方法があります。オブジェクトのプロパティにアクセスする場合はこの方法をお勧めします。

車に関すること:

$properties = @{ 'color'='red'; 'type'='sedan'; 'package'='fully loaded'; }

オブジェクトを作成します。

$car = New-Object -typename psobject -Property $properties

文字列を補間する:

"The {0} car is a Nice {1} that is {2}" -f $car.color, $car.type, $car.package

出力:

# The red car is a Nice sedan that is fully loaded
9
loonison101