【问题标题】:How to capture output message and save it to variable in powershell and SqlCmd如何捕获输出消息并将其保存到 powershell 和 SqlCmd 中的变量
【发布时间】:2021-11-10 02:08:31
【问题描述】:

我正在使用一个 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

【问题讨论】:

  • 所以你想静默并只捕获错误?
  • dba.stackexchange.com/questions/156287/…。但要好得多:尝试 WITH TABLERESULTS, NO_INFOMSGS 将其作为实际表格,比信息消息更容易使用。
  • @AbrahamZinala 是的。如果出现错误(损坏),我想捕获消息。如果没有 - 不要捕获任何东西
  • 而这个:Try { Invoke-SqlCmd -ServerInstance $ServerInstance -Database master -Query "DBCC CHECKDB ([$($DB.Database)]) WITH NO_INFOMSGS,PHYSICAL_ONLY;" -OutputSqlErrors:$true -Verbose } Catch { $myerror = $_ } 没用?
  • 你会尝试使用-AbortOnError-ErrorLevel 参数吗?

标签: sql-server powershell tsql database-administration


【解决方案1】:

这些只是标准异常错误,您可以使用 CommonParameter -ErrorVariable 或使用自动变量 $Error 捕获。

以下是使用 ErrorVariable 的示例。我们告诉Invoke-SqlCmd 将遇到的任何错误存储在一个名为“dbCheckErrors”的变量中。我们稍后检查这个变量$dbCheckErrors 是否包含任何错误记录,如果是,我们将所有异常消息收集到我们的$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'

【讨论】:

  • 谢谢@Daniel。这正是我想要的。学到了新东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
相关资源
最近更新 更多