在 PowerShell 中使用 ForEach-Object 遍历实例上的每个数据库不起作用

Iterate through each database on an instance using ForEach-Object in PowerShell does not work

我是 PowerShell 的新手。 试图了解如何使用 ForEach-Object 命令遍历服务器上的每个数据库。

但是它只多次引入 master 数据库并且似乎没有遍历其余数据库。

# generate list of databases to iterate through
$DB = Invoke-SqlCmd -ServerInstance databasecluster  -Database master -Query "SELECT [name] AS [Database] FROM sys.databases  ORDER BY 1 DESC;"
$Query = "select DB_name();"
$DB | ForEach-Object{
           $DB = "$_";
            Invoke-Sqlcmd -Query $Query -ServerInstance myinstance;
}

我在这里错过了什么?

更新

PS C:\> $DB = Invoke-SqlCmd -ServerInstance myinstance -Database master -Query "SELECT [name] AS [Database] FROM sys.databases  ORDER BY 1 DESC;"
>> $Query = "select DB_name();"
>> $DB | ForEach-Object{
>>              $DB = "$_";
>>              Invoke-Sqlcmd -ServerInstance myinstance -Database $DB -Query $Query
>>   }

错误

*Invoke-Sqlcmd : Cannot open database "System.Data.DataRow" requested by the login. The login failed.
Login failed for user 'domain\username'.
At line:5 char:14
+ ...             Invoke-Sqlcmd -ServerInstance myinstance -Database $ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlException
    + FullyQualifiedErrorId : SqlExceptionError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand*

问题

$DB 对象是 System.Data.DataRow 类型对象的数组。发生的情况是 $_ 包含来自您发出的查询的整个 DataRow

SELECT [name] AS [Database] FROM sys.databases  ORDER BY 1 DESC;

当在 ForEach-Object 循环中指定 $_ 时,它只是 returns 对象的类型,因为它没有默认操作,毕竟它是一个可以想象包含的行很多值。您可以通过 运行 这些行来查看会发生什么,以解决检查 $DB 数组中的第一个 'row':

# Just the DataRow
$DB[0]
# DB DataRow 1 column 1
$DB[0][0]
# DB First DataRow Database column
$DB[0].Database

解决方案

解决方案是在循环中使用 $_.Database 从查询中获取 'Database' 列值:

$DB = Invoke-SqlCmd -ServerInstance myinstance -Database master -Query "SELECT [name] AS [Database] FROM sys.databases  ORDER BY 1 DESC;"
$Query = "select DB_name();"
$DB | ForEach-Object{
             $DB = $_.Database;
             Invoke-Sqlcmd -ServerInstance myinstance -Database $DB -Query $Query
  }

提示

使用不同的变量名也是一个好主意 - 在从 $DB | 开始的循环中重复使用 $DB 可能有效,但在更复杂的脚本中可能会造成混淆。