Saya memiliki kode berikut:
$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;
Ketika saya mencoba menggunakan salah satu properti dalam perintah eksekusi string:
& "$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'"
Ia mencoba untuk hanya menggunakan nilai $DatabaseSettings
daripada nilai $DatabaseSettings[0].DatabaseName
, yang tidak valid.
Solusi saya adalah menyalinnya ke variabel baru.
Bagaimana cara mengakses properti objek secara langsung dalam string kutip ganda?
sumber
@Joey memiliki jawaban yang benar, tetapi hanya untuk menambahkan sedikit lagi mengapa Anda perlu memaksakan evaluasi dengan
$()
:Kode contoh Anda berisi ambiguitas yang menunjukkan mengapa pembuat PowerShell mungkin telah memilih untuk membatasi perluasan hanya untuk referensi variabel dan tidak mendukung akses ke properti juga (sebagai tambahan: ekspansi string dilakukan dengan memanggil
ToString()
metode pada objek, yang mana dapat menjelaskan beberapa hasil yang "aneh").Contoh Anda terdapat di bagian paling akhir dari baris perintah:
Jika properti objek diperluas secara default, di atas akan diselesaikan menjadi
karena objek yang direferensikan
$LogFileName
tidak akan memiliki properti yang dipanggilldf
,$null
(atau string kosong) akan menggantikan variabel.sumber
@ Joey punya jawaban yang bagus. Ada cara lain dengan tampilan .NET lebih dengan setara String.Format, saya lebih suka saat mengakses properti pada objek:
Hal-hal tentang mobil:
Buat sebuah objek:
Interpolasi string:
Keluaran:
sumber
write-host "foo = {0}" -f $foo
karena PowerShell akan memperlakukannya-f
sebagaiForegroundColor
parameter untukwrite-host
. Dalam contoh ini, Anda perluwrite-host ( "foo = {0}" -f $foo )
. Ini adalah perilaku PowerShell standar, tetapi perlu diperhatikan.String.Format
.Expression
sebaliknyaArgument
(hingga terminator perintah).Catatan dokumentasi:
Get-Help about_Quoting_Rules
mencakup interpolasi string, tetapi, pada PSv5, tidak mendalam.Untuk melengkapi jawaban Joey yang membantu dengan ringkasan pragmatis dari ekspansi string PowerShell (interpolasi string dalam string yang dikutip ganda (
"...")
, termasuk dalam string yang dikutip ganda di sini ):Hanya referensi seperti
$foo
,$global:foo
(atau$script:foo
, ...) dan$env:PATH
(variabel lingkungan) yang dikenali saat disematkan secara langsung dalam"..."
string - artinya, hanya referensi variabel itu sendiri yang diperluas, terlepas dari apa yang mengikutinya.Untuk membedakan nama variabel dari karakter berikutnya dalam string, apit dengan
{
dan}
; mis${foo}
. , .Hal ini terutama penting jika nama variabel diikuti dengan
:
, seperti PowerShell jika tidak akan mempertimbangkan segala sesuatu antara$
dan:
sebuah ruang lingkup specifier, biasanya menyebabkan interpolasi untuk gagal ; misalnya,"$HOME: where the heart is."
istirahat, tetapi"${HOME}: where the heart is."
berfungsi sebagaimana mestinya.(Atau,
`
-escape yang:
:"$HOME`: where the heart is."
).Untuk memperlakukan a
$
atau a"
sebagai literal , awali dengan escape char.`
(a backtick ); misalnya:"`$HOME's value: `"$HOME`""
Untuk hal lain, termasuk menggunakan subskrip array dan mengakses properti variabel objek , Anda harus menyertakan ekspresi dalam
$(...)
, operator subekspresi (mis.,"PS version: $($PSVersionTable.PSVersion)"
Atau"1st el.: $($someArray[0])"
)$(...)
even memungkinkan Anda untuk menyematkan keluaran dari seluruh baris perintah dalam string kutip ganda (misalnya,"Today is $((Get-Date).ToString('d'))."
).Hasil interpolasi tidak selalu terlihat sama dengan format keluaran default (yang akan Anda lihat jika Anda mencetak variabel / subekspresi langsung ke konsol, misalnya, yang melibatkan pemformat default; lihat
Get-Help about_format.ps1xml
):Koleksi , termasuk larik, diubah menjadi string dengan menempatkan satu spasi di antara representasi string dari elemen (secara default; pemisah yang berbeda dapat ditentukan dengan pengaturan
$OFS
) Misalnya,"array: $(@(1, 2, 3))"
hasilarray: 1 2 3
Contoh jenis lainnya (termasuk unsur koleksi yang tidak sendiri koleksi) yang stringified oleh salah memanggil
IFormattable.ToString()
metode dengan budaya invarian , jika jenis contoh ini mendukungIFormattable
antarmuka [1] , atau dengan menelepon.psobject.ToString()
, yang dalam banyak kasus hanya memanggil.ToString()
metode tipe NET yang mendasari [2] , yang mungkin atau mungkin tidak memberikan representasi yang berarti: kecuali tipe (non-primitif) telah secara khusus menimpa.ToString()
metode tersebut, yang akan Anda dapatkan hanyalah nama tipe lengkap (misalnya,"hashtable: $(@{ key = 'value' })"
hasilhashtable: System.Collections.Hashtable
).Untuk mendapatkan hasil yang sama seperti di konsol , gunakan subekspresi dan pipa ke
Out-String
dan terapkan.Trim()
untuk menghapus garis kosong di depan dan di belakang, jika diinginkan; misalnya,"hashtable:`n$((@{ key = 'value' } | Out-String).Trim())"
hasil:[1] Perilaku yang mungkin mengejutkan ini berarti bahwa, untuk tipe yang mendukung representasi yang peka budaya,
$obj.ToString()
menghasilkan representasi yang sesuai dengan budaya saat ini , sedangkan"$obj"
(interpolasi string) selalu menghasilkan representasi budaya-invarian - lihat jawaban saya ini.[2] Penimpaan penting:
* Stringifikasi koleksi yang telah dibahas sebelumnya (daftar elemen yang dipisahkan spasi daripada sesuatu seperti itu
System.Object[]
).* Representasi instance seperti hashtable
[pscustomobject]
(dijelaskan di sini ) daripada string kosong .sumber