如何捕获输出消息并将其保存到 powershell 和 SqlCmd 中的变量
How to capture output message and save it to variable in powershell and SqlCmd
我正在使用 powershell 代码 https://dba.stackexchange.com/a/254401/92058,它循环遍历实例上的每个数据库并使用 DBCC CheckDB
sql 命令检查损坏。
如果检测到损坏(例如在这种情况下,DB 50Ways 上的页面已损坏),DBCC CheckDB 命令将输出一条消息(不是错误!)。
如您所见,正在处理数据库50Ways
下面弹出消息,表明它发现了损坏的页面。
那么我如何才能只捕获这条消息(如果有的话)并将其保存到一个变量中,这样我就可以向自己发送电子邮件通知。
$ServerInstance = "myinstance" ## instance name
$Databases = Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Query "SELECT [name] AS [Database] FROM sys.databases ORDER BY 1 DESC;"
foreach ($DB in $Databases)
{
Write-Output "Processing $($DB.Database)..."
Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Query "DBCC CHECKDB ([$($DB.Database)]) WITH NO_INFOMSGS,PHYSICAL_ONLY;" -OutputSqlErrors:$true -Verbose
}
Write-Output "Complete."
输出如下所示:
Processing WideWorldImporters...
Processing tempdb...
Processing msdb...
Processing model...
Processing master...
Processing DBA...
Processing AdventureWorks2017...
Processing 50Ways...
Invoke-SqlCmd : Table error: Object ID 901578250, index ID 0, partition ID
72057594043105280, alloc unit ID 72057594049527808 (type In-row data), page (1:312).
Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -4.
Object ID 901578250, index ID 0, partition ID 72057594043105280, alloc unit ID
72057594049527808 (type In-row data): Page (1:312) could not be processed. See other
errors for details.
CHECKDB found 0 allocation errors and 2 consistency errors in table 'ToLeaveYourLover'
(object ID 901578250).
CHECKDB found 0 allocation errors and 2 consistency errors in database '50Ways'.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB
(50Ways).
At line:11 char:5
+ Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Q ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlEx
ecutionException
+ FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScr
iptCommand
Complete.
和图片一样,只需要在变量中捕获一条红色消息。
也尝试使用 TRY CATCH
块,但它根本没有捕捉到错误。
BEGIN TRY
DBCC CHECKDB ([50Ways]) WITH NO_INFOMSGS,PHYSICAL_ONLY
END TRY
BEGIN CATCH
SELECT
ERROR_MESSAGE() AS [Error Message]
,ERROR_LINE() AS ErrorLine
,ERROR_NUMBER() AS [Error Number]
,ERROR_SEVERITY() AS [Error Severity]
,ERROR_STATE() AS [Error State]
END CATCH
这些只是您可以使用 CommonParameter -ErrorVariable
或使用自动变量 $Error
捕获的标准异常错误。
下面是一个使用ErrorVariable的例子。我们告诉 Invoke-SqlCmd
将遇到的任何错误存储在名为 'dbCheckErrors' 的变量中。我们稍后检查此变量 $dbCheckErrors
是否包含任何 ErrorRecords,如果包含,我们将所有异常消息收集到我们的 $errorCollection
数组中以供以后访问。完成数据库检查后,我们可以查看消息,将消息保存到文件中,或者两者都可以。
# Create an empty array to later capture error message in our loop
$errorCollection = @()
foreach ($DB in $Databases)
{
Write-Output "Processing $($DB.Database)..."
Invoke-SqlCmd -ErrorVariable 'dbCheckErrors' -ServerInstance '(localdb)\MSSQLLocalDB' -Database master -Query "DBCC CHECKDB ([$($DB.Database)]) WITH NO_INFOMSGS,PHYSICAL_ONLY;" -OutputSqlErrors:$true -Verbose
if ($dbCheckErrors) {
# Do something with any errors here
# Or just add the exception message(s) to a collection to handle later
$errorCollection += $dbCheckErrors.Exception.Message
}
}
# view the exception messages
$errorCollection
# save the exception messages to file
$errorCollection | Set-Content -Path '.\dbCheckErrors.log'
我正在使用 powershell 代码 https://dba.stackexchange.com/a/254401/92058,它循环遍历实例上的每个数据库并使用 DBCC CheckDB
sql 命令检查损坏。
如果检测到损坏(例如在这种情况下,DB 50Ways 上的页面已损坏),DBCC CheckDB 命令将输出一条消息(不是错误!)。
如您所见,正在处理数据库50Ways
下面弹出消息,表明它发现了损坏的页面。
那么我如何才能只捕获这条消息(如果有的话)并将其保存到一个变量中,这样我就可以向自己发送电子邮件通知。
$ServerInstance = "myinstance" ## instance name
$Databases = Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Query "SELECT [name] AS [Database] FROM sys.databases ORDER BY 1 DESC;"
foreach ($DB in $Databases)
{
Write-Output "Processing $($DB.Database)..."
Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Query "DBCC CHECKDB ([$($DB.Database)]) WITH NO_INFOMSGS,PHYSICAL_ONLY;" -OutputSqlErrors:$true -Verbose
}
Write-Output "Complete."
输出如下所示:
Processing WideWorldImporters...
Processing tempdb...
Processing msdb...
Processing model...
Processing master...
Processing DBA...
Processing AdventureWorks2017...
Processing 50Ways...
Invoke-SqlCmd : Table error: Object ID 901578250, index ID 0, partition ID
72057594043105280, alloc unit ID 72057594049527808 (type In-row data), page (1:312).
Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -4.
Object ID 901578250, index ID 0, partition ID 72057594043105280, alloc unit ID
72057594049527808 (type In-row data): Page (1:312) could not be processed. See other
errors for details.
CHECKDB found 0 allocation errors and 2 consistency errors in table 'ToLeaveYourLover'
(object ID 901578250).
CHECKDB found 0 allocation errors and 2 consistency errors in database '50Ways'.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB
(50Ways).
At line:11 char:5
+ Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Q ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlEx
ecutionException
+ FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScr
iptCommand
Complete.
和图片一样,只需要在变量中捕获一条红色消息。
也尝试使用 TRY CATCH
块,但它根本没有捕捉到错误。
BEGIN TRY
DBCC CHECKDB ([50Ways]) WITH NO_INFOMSGS,PHYSICAL_ONLY
END TRY
BEGIN CATCH
SELECT
ERROR_MESSAGE() AS [Error Message]
,ERROR_LINE() AS ErrorLine
,ERROR_NUMBER() AS [Error Number]
,ERROR_SEVERITY() AS [Error Severity]
,ERROR_STATE() AS [Error State]
END CATCH
这些只是您可以使用 CommonParameter -ErrorVariable
或使用自动变量 $Error
捕获的标准异常错误。
下面是一个使用ErrorVariable的例子。我们告诉 Invoke-SqlCmd
将遇到的任何错误存储在名为 'dbCheckErrors' 的变量中。我们稍后检查此变量 $dbCheckErrors
是否包含任何 ErrorRecords,如果包含,我们将所有异常消息收集到我们的 $errorCollection
数组中以供以后访问。完成数据库检查后,我们可以查看消息,将消息保存到文件中,或者两者都可以。
# Create an empty array to later capture error message in our loop
$errorCollection = @()
foreach ($DB in $Databases)
{
Write-Output "Processing $($DB.Database)..."
Invoke-SqlCmd -ErrorVariable 'dbCheckErrors' -ServerInstance '(localdb)\MSSQLLocalDB' -Database master -Query "DBCC CHECKDB ([$($DB.Database)]) WITH NO_INFOMSGS,PHYSICAL_ONLY;" -OutputSqlErrors:$true -Verbose
if ($dbCheckErrors) {
# Do something with any errors here
# Or just add the exception message(s) to a collection to handle later
$errorCollection += $dbCheckErrors.Exception.Message
}
}
# view the exception messages
$errorCollection
# save the exception messages to file
$errorCollection | Set-Content -Path '.\dbCheckErrors.log'