在 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
可能有效,但在更复杂的脚本中可能会造成混淆。
我是 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
可能有效,但在更复杂的脚本中可能会造成混淆。