【问题标题】:How do I log errors from a powershell script called by a SQL stored procedure into a SQL table?如何将 SQL 存储过程调用的 powershell 脚本中的错误记录到 SQL 表中?
【发布时间】:2018-03-09 10:14:57
【问题描述】:

我有一个执行 powershell 文件的 SQL 存储过程,我想将执行 powershell 文件时发生的任何错误记录到 SQL 表中。

我的 SQL 存储过程:

CREATE PROCEDURE [dbo].[sp_RemoveEmptyFiles]
    @filePath varchar(260)

AS 

DECLARE @sql as varchar(4000)
DECLARE @powershellFileLocation varchar(260)

SET @powershellFileLocation = '\\MyComputerName\Files\Powershell\cleandirectory.ps1'


SET @sql = 'powershell -c "& { . ' + @powershellFileLocation + '; clean-directory ' + @filePath + ' }"'

EXEC master..xp_cmdshell @sql

我的 powershell 脚本:

function clean-directory {
    param ([string]$path)
    try 
    {
        if ($path.Length -le 0 -or -not (test-path -literalPath $path)) {
            throw [System.IO.FileNotFoundException] """$path"" not a valid file path."
        }

        #
        #
        # Clean directories here
        #
        #
    }
    catch 
    {
        write-host $error
    }
}

现在,如果脚本成功,它会返回 NULL 的输出和 0 的返回值。目标是用可以将这些错误保存到 SQL 表中的东西替换那个 catch 块。

我的第一个(低效)想法是在那个 catch 块中调用 SQL 命令,类似于:

$commandText = "INSERT INTO ErrorLogTable (TimeStamp, ErrorMessage) VALUES ($(Get-Date), $error)"
$command = $conn.CreateCommand()
$command.CommandText = $commandText
$command.ExecuteNonQuery()

但这似乎不是最好的方法——连接回调用存储过程的 SQL 服务器并创建一个新命令等。应该注意的是 powershell 脚本,文件路径参数存储过程和 SQL 服务器位于不同的位置,因此我确实需要牢记权限问题(这也是为什么我试图避免从我的 powershell 脚本调用 Invoke-Sqlcmd)。

有没有办法在存储过程中获取powershell文件的输出,然后从那里将错误消息保存到表中?

【问题讨论】:

标签: sql-server powershell stored-procedures


【解决方案1】:

由于我使用的是xp_cmdshell,因此我可以通过如下更改 SQL 脚本来捕获该输出:

SET @sql = 'powershell -c "& { . ' + @powershellFileLocation + '; clean-directory ' + @filePath + ' }"'

-- table to hold the output from the cmdshell
CREATE TABLE #PowershellOutput ([Output] varchar(1000))

-- execute actual powershell script
INSERT INTO #PowershellOutput ([Output]) EXEC master..xp_cmdshell @sql

这会将发送到控制台的每一行捕获为单独的行。这不是从 powershell 捕获错误消息的最佳解决方案,因此我仍在寻找更好的方法来捕获它们。我要么将这些行加入到单个输出中,要么找到一种更好的方法来仅捕获 powershell 错误(而不是整个堆栈跟踪)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多