PowerShell有两种不同的语法,在文档中描述为
"parsing modes"
:
-
参数模式:
-
应用于命令名后面的所有内容,包括
*$database[0]*
论点
-
表达式模式:
-
适用于大多数其他方面,并完全按照您的预期工作:
$databases[0]
将被解释为数组索引操作
当PowerShell在参数模式下遇到所谓的“裸词令牌”时,它会自动将其解释为可扩展字符串文字表达式的内容。
换句话说,论点
*$databases[0]*
被解释为与你写的一样
"*$databases[0]*"
.
在可扩展字符串文字中,仅
简单变量表达式
被识别并展开-因此PowerShell尝试评估
$databases
不考虑
[0]
.
可以通过使用子表达式运算符包装表达式来转义字符串插值规则
$()
:
"*$($databases[0])*"
很高兴知道,
但你在这里并不真的需要它
-你需要一个循环!
我不知道如何制作ForEach循环
这个
foreach
loop statement
在PowerShell中相当简单:
foreach ($item in $collection) {
# work with each $item here
}
让我们试试你的
$数据库
大堆
foreach ($databaseName in $databases) {
# find the latest backup file containing the db name in its file name
$latestBackupFile = Get-ChildItem $BackupPath -File -Filter "*$databaseName*.bak" | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 1
if ($latestBackupFile) {
Restore-SqlDatabase -ServerInstance "my-vm" -Database $databaseName -BackupFile $latestBackupFile.FullName -ReplaceDatabase
}
else {
Write-Warning "Unable to locate backup file for database $databaseName"
}
}
由于我们不再依赖数组索引器,
$databaseName
现在可以按预期在过滤器字符串中展开-在第一次迭代中
$databaseName
变量将具有值
"Orders"
,所以参数表达式
-Filter "*$databaseName*.bak"
将产生筛选器字符串
*Orders*.bak
最后,如果您需要用字符填充数据库名称,否则这些字符可能会被解释为变量路径的一部分,则可以使用限定变量路径
{}
:
# underscore _ below would have been interpreted as part of the variable path expression `$databaseName_` if not for the curly brackets
... -Filter "*${databaseName}_*.bak"