Ich habe folgenden Code:
$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;
Wenn ich versuche, eine der Eigenschaften in einem String-Ausführungsbefehl zu verwenden:
& "$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'"
Es wird versucht, nur den Wert von $DatabaseSettings
anstelle des Werts von zu verwenden $DatabaseSettings[0].DatabaseName
, was nicht gültig ist.
Meine Problemumgehung besteht darin, es in eine neue Variable kopieren zu lassen.
Wie kann ich direkt in einer Zeichenfolge in doppelten Anführungszeichen auf die Objekteigenschaft zugreifen?
quelle
@Joey hat die richtige Antwort, aber nur um ein bisschen mehr hinzuzufügen, warum Sie die Bewertung erzwingen müssen mit
$()
:Ihr Beispielcode enthält eine Mehrdeutigkeit, die darauf hinweist, warum die Hersteller von PowerShell möglicherweise die Erweiterung auf bloße Variablenreferenzen beschränkt haben und den Zugriff auf Eigenschaften nicht unterstützen (abgesehen davon: Die Zeichenfolgenerweiterung erfolgt durch Aufrufen der
ToString()
Methode für das Objekt kann einige "ungerade" Ergebnisse erklären).Ihr Beispiel ganz am Ende der Befehlszeile:
Wenn die Eigenschaften von Objekten standardmäßig erweitert würden, würde das oben Gesagte in aufgelöst
da das durch referenzierte Objekt
$LogFileName
nicht eine Eigenschaft namens hatldf
,$null
(oder eine leere Zeichenkette) würde für die Variable ersetzt werden.quelle
@ Joey hat eine gute Antwort. Es gibt eine andere Möglichkeit mit einem .NET-Look mit einem String.Format-Äquivalent. Ich bevorzuge es beim Zugriff auf Eigenschaften von Objekten:
Dinge über ein Auto:
Erstellen Sie ein Objekt:
Interpoliere einen String:
Ausgänge:
quelle
write-host "foo = {0}" -f $foo
da PowerShell-f
alsForegroundColor
Parameter für behandelt wirdwrite-host
. In diesem Beispiel müssten Siewrite-host ( "foo = {0}" -f $foo )
. Dies ist das Standardverhalten von PowerShell, aber erwähnenswert.String.Format
.Expression
andersArgument
(bis zu einem Befehlsabschluss).Hinweis zur Dokumentation:
Get-Help about_Quoting_Rules
Deckt die String-Interpolation ab, ab PSv5 jedoch nicht mehr ausführlich.Um Joeys hilfreiche Antwort mit einer pragmatischen Zusammenfassung von PowerShell zu ergänzen - String Erweiterung (string Interpolation in doppelten Anführungszeichen Strings (
"...")
einschließlich in doppelten Anführungszeichen hier-Strings ):Nur Referenzen wie
$foo
,$global:foo
(oder$script:foo
, ...) und$env:PATH
(Umgebungsvariablen) werden erkannt, wenn sie direkt in eine"..."
Zeichenfolge eingebettet sind - das heißt, nur die Variablenreferenz selbst wird erweitert, unabhängig davon, was folgt.Um einen Variablennamen von nachfolgenden Zeichen in der Zeichenfolge zu unterscheiden, schließen Sie ihn in
{
und ein}
. zB ,${foo}
.Dies ist besonders wichtig , wenn der Variablenname gefolgt von einem wird
:
, wie Powershell sonst alles zwischen dem in Betracht ziehen würde$
und:
ein Umfang Spezifizierer, in der Regel die Interpolation verursacht zu scheitern ; zB"$HOME: where the heart is."
bricht,"${HOME}: where the heart is."
funktioniert aber wie vorgesehen.(Alternativ
`
-escape der:
:"$HOME`: where the heart is."
).Um a
$
oder a"
als Literal zu behandeln , stellen Sie ihm ein Escapezeichen voran.`
(ein Backtick ); z.B:"`$HOME's value: `"$HOME`""
Für alles andere, einschließlich der Verwendung von Array-Indizes und des Zugriffs auf die Eigenschaften einer Objektvariablen , müssen Sie den Ausdruck in
$(...)
den Unterausdrucksoperator (z. B."PS version: $($PSVersionTable.PSVersion)"
oder"1st el.: $($someArray[0])"
) einschließen.$(...)
sogar verwenden, können Sie die Ausgabe ganzer Befehlszeilen in Zeichenfolgen in doppelten Anführungszeichen (z"Today is $((Get-Date).ToString('d'))."
. B. ) einbetten .Interpolationsergebnisse sehen nicht unbedingt genauso aus wie das Standardausgabeformat (was Sie sehen würden, wenn Sie die Variable / den Unterausdruck beispielsweise direkt auf die Konsole drucken würden, was den Standardformatierer betrifft; siehe
Get-Help about_format.ps1xml
):Sammlungen , einschließlich Arrays, werden durch Platzieren eines einzelnen Leerzeichens in Zeichenfolgen konvertiert zwischen den Stringdarstellungen der Elemente (Standard, ein anderes Trenn kann durch Einstellung festgelegt werden
$OFS
) Eg,"array: $(@(1, 2, 3))"
Ausbeutenarray: 1 2 3
Instanzen von jedem anderen Typ (einschließlich der Elemente der Sammlung, die selbst nicht Sammlungen sind) werden Zeichenfolge von entweder der anrufenden
IFormattable.ToString()
Methode mit der invarianten Kultur , wenn der Typ der Instanz die AbstützungenIFormattable
Schnittstelle [1] , oder durch den Aufruf.psobject.ToString()
, die in den meisten Fällen einfach Invokes die.ToString()
Methode des zugrunde liegenden .NET-Typs [2] , die möglicherweise eine aussagekräftige Darstellung liefert oder nicht: Sofern ein (nicht primitiver) Typ die.ToString()
Methode nicht speziell überschrieben hat , erhalten Sie lediglich den vollständigen Typnamen (z . B."hashtable: $(@{ key = 'value' })"
Ausbeutenhashtable: System.Collections.Hashtable
).Um die gleiche Ausgabe wie in der Konsole zu erhalten , verwenden Sie einen Unterausdruck und eine Pipe für
Out-String
und wenden Sie diese.Trim()
an, um gegebenenfalls führende und nachfolgende leere Zeilen zu entfernen. z.B,"hashtable:`n$((@{ key = 'value' } | Out-String).Trim())"
ergibt:[1] Dieses vielleicht überraschende Verhalten bedeutet, dass für Typen, die kultursensitive Darstellungen unterstützen,
$obj.ToString()
ein Strom entsteht kultursensitive kulturgerechte Darstellung erhalten wird, während"$obj"
(String-Interpolation) immer zu a führt kulturinvarianten Darstellung führt - siehe meine Antwort .[2] Bemerkenswerte Überschreibungen:
* Die zuvor diskutierte Stringifizierung von Sammlungen (durch Leerzeichen getrennte Liste von Elementen anstelle von so etwas
System.Object[]
).* Die hashtable- wie Darstellung von
[pscustomobject]
Instanzen (erklärt hier ) , anstatt der leeren String .quelle