126

次のコードがあります。

$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、これは無効です。
私の回避策は、それを新しい変数にコピーすることです。

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

4

5 に答える 5

206

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

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

于 2009-07-17T21:41:57.493 に答える
18

@Joeyは正しい答えを持っていますが、なぜ評価を強制する必要があるのか​​ についてもう少し追加します$()

サンプル コードには、PowerShell の作成者が拡張を単なる変数参照に制限し、プロパティへのアクセスもサポートしないことを選択した理由を示すあいまいさが含まれています (余談ですが、文字列の拡張はToString()、オブジェクトのメソッドを呼び出すことによって行われます。いくつかの「奇妙な」結果を説明できます)。

コマンドラインの最後に含まれる例:

...\$LogFileName.ldf

オブジェクトのプロパティがデフォルトで展開されている場合、上記は次のように解決されます

...\

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

于 2009-07-17T22:19:07.167 に答える
11

@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
于 2016-07-29T18:28:55.537 に答える