Eu tenho o seguinte código:
$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;
Quando tento usar uma das propriedades em uma string execute o comando:
& "$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'"
Ele tenta usar apenas o valor de $DatabaseSettings
em vez do valor de $DatabaseSettings[0].DatabaseName
, que não é válido.
Minha solução alternativa é copiá-lo em uma nova variável.
Como posso acessar a propriedade do objeto diretamente em uma string entre aspas?
fonte
@Joey tem a resposta correta, mas apenas para acrescentar um pouco mais por que você precisa forçar a avaliação com
$()
:Seu código de exemplo contém uma ambigüidade que aponta para o motivo pelo qual os criadores do PowerShell podem ter optado por limitar a expansão a meras referências de variáveis e não oferecer suporte ao acesso às propriedades também (como um aparte: a expansão da string é feita chamando o
ToString()
método no objeto, que pode explicar alguns resultados "estranhos").Seu exemplo contido no final da linha de comando:
Se as propriedades dos objetos foram expandidas por padrão, o acima seria resolvido para
uma vez que o objeto referenciado por
$LogFileName
não teria uma propriedade chamadaldf
,$null
(ou uma string vazia) seria substituída pela variável.fonte
@Joey tem uma boa resposta. Há outra maneira com uma aparência mais .NET com um equivalente String.Format, eu prefiro ao acessar propriedades em objetos:
Coisas sobre um carro:
Crie um objeto:
Interpolar uma string:
Saídas:
fonte
write-host "foo = {0}" -f $foo
pois o PowerShell tratará-f
como oForegroundColor
parâmetro parawrite-host
. Neste exemplo, você precisawrite-host ( "foo = {0}" -f $foo )
. Esse é o comportamento padrão do PowerShell, mas vale a pena observar.String.Format
.Expression
diferenteArgument
(até um terminador de comando).Nota de documentação:
Get-Help about_Quoting_Rules
cobre a interpolação de strings, mas, a partir do PSv5, não em profundidade.Para complementar a resposta útil de Joey com um resumo pragmático da expansão de string do PowerShell (interpolação de string em strings entre aspas duplas (
"...")
, incluindo strings here entre aspas duplas ):Apenas referências como
$foo
,$global:foo
(ou$script:foo
, ...) e$env:PATH
(variáveis de ambiente) são reconhecidas quando diretamente embutidas em uma"..."
string - isto é, apenas a própria referência de variável é expandida, independentemente do que segue.Para eliminar a ambigüidade de um nome de variável de caracteres subsequentes na string, coloque-o entre
{
e}
; por exemplo,${foo}
.Isto é especialmente importante se o nome da variável é seguido por um
:
, como PowerShell de outra forma, considerar tudo entre a$
ea:
um âmbito especificador, normalmente fazendo com que a interpolação para falhar ; por exemplo,"$HOME: where the heart is."
quebra, mas"${HOME}: where the heart is."
funciona como pretendido.(Alternativamente,
`
escapam a o:
:"$HOME`: where the heart is."
).Para tratar a
$
ou a"
como literal , prefixe-o com escape char.`
(um backtick ); por exemplo:"`$HOME's value: `"$HOME`""
Para qualquer outra coisa, incluindo o uso de subscritos de array e acesso às propriedades de uma variável de objeto , você deve colocar a expressão em
$(...)
, o operador de subexpressão (por exemplo,"PS version: $($PSVersionTable.PSVersion)"
ou"1st el.: $($someArray[0])"
)$(...)
even permite que você insira a saída de linhas de comando inteiras em strings entre aspas (por exemplo,"Today is $((Get-Date).ToString('d'))."
).Os resultados da interpolação não são necessariamente iguais ao formato de saída padrão (o que você veria se imprimisse a variável / subexpressão diretamente no console, por exemplo, que envolve o formatador padrão; consulte
Get-Help about_format.ps1xml
):Coleções , incluindo matrizes, são convertidas em strings colocando um único espaço entre as representações de string dos elementos (por padrão; um separador diferente pode ser especificado configurando
$OFS
). Por exemplo,"array: $(@(1, 2, 3))"
rendimentosarray: 1 2 3
Instâncias de qualquer outro tipo (incluindo os elementos de colecções que não são eles próprios colecções) são Stringified por qualquer ligando para o
IFormattable.ToString()
método com a cultura invariante , se o tipo do exemplo suporta aIFormattable
interface de [1] , ou ligando.psobject.ToString()
, que na maioria dos casos, simplesmente invoca o.ToString()
método do tipo .NET subjacente [2] , que pode ou não fornecer uma representação significativa: a menos que um tipo (não primitivo) tenha sobrescrito especificamente o.ToString()
método, tudo o que você obterá é o nome completo do tipo (por exemplo,"hashtable: $(@{ key = 'value' })"
rendimentoshashtable: System.Collections.Hashtable
).Para obter a mesma saída do console , use uma subexpressão e um pipe para
Out-String
e aplique.Trim()
para remover quaisquer linhas vazias iniciais e finais, se desejado; por exemplo,"hashtable:`n$((@{ key = 'value' } | Out-String).Trim())"
rendimentos:[1] Este comportamento talvez surpreendente significa que, para tipos que suportam representações sensíveis à cultura,
$obj.ToString()
produz uma representação apropriada à cultura atual , enquanto"$obj"
(interpolação de strings) sempre resulta em uma representação invariante à cultura - veja esta minha resposta .[2] Substituições notáveis:
* A stringificação de coleções discutida anteriormente (lista de elementos separados por espaço em vez de algo semelhante
System.Object[]
).* O hashtable- como representação de
[pscustomobject]
casos (explicado aqui ), em vez do que a cadeia vazia .fonte