在 Azure 自动化 powershell 脚本中打印来自 SQL 的消息不起作用

Mik*_*kov 5 sql-server powershell azure azure-automation

我创建了一个示例 Azure 自动化 Powershell Runbook。我正在尝试执行 SQL 命令,然后将该命令中的消息打印到 Workbook 输出中。

我的代码取自使用 PowerShell 从 SQL Server 捕获 InfoMessage 输出,如果我在本地运行它,它就可以工作:

Write-Output "Starting"

$conn = New-Object System.Data.SqlClient.SqlConnection "Data Source=abc.database.windows.net,1433;Initial Catalog=def;Integrated Security=False;User ID=ghj;Password=qwe"

## Attach the InfoMessage Event Handler to the connection to write out the messages 
$handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] {param($sender, $event) Write-Output $event.Message }; 
$conn.add_InfoMessage($handler); 
$conn.FireInfoMessageEventOnUserErrors = $true;

$conn.Open();

$cmd = $conn.CreateCommand(); 
$cmd.CommandText = "PRINT 'This is the message from the PRINT statement'"; 
$cmd.ExecuteNonQuery(); 
$cmd.CommandText = "RAISERROR('This is the message from the RAISERROR statement', 10, 1)";  
$cmd.ExecuteNonQuery(); 
$conn.Close();

Write-Output "Done"
Run Code Online (Sandbox Code Playgroud)

运行工作簿后,我看到Starting, -1(来自ExecuteNotQuery结果)Done而不是来自 SQL 的消息。

Register-ObjectEvent这个答案也不起作用:

Register-ObjectEvent : Cannot register for the specified event. 
An event with the name 'InfoMessage' does not exist. Parameter name: eventName
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

And*_*unk 5

在 Azure 自动化中,调用Write-OutputWrite-Host处理程序内部似乎存在范围问题。消息设置在处理一个全局变量,然后调用Write-OutputExecuteNonQuery工作了我的目的。

Write-Output "Starting"

$conn = New-Object System.Data.SqlClient.SqlConnection "Data Source=abc.database.windows.net,1433;Initial Catalog=def;Integrated Security=False;User ID=ghj;Password=qwe"

## Attach the InfoMessage Event Handler to the connection to write out the messages 
$handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] {param($sender, $event) $global:message = $event.Message};
$conn.add_InfoMessage($handler); 
$conn.FireInfoMessageEventOnUserErrors = $true;

$conn.Open();

$cmd = $conn.CreateCommand(); 
$cmd.CommandText = "PRINT 'This is the message from the PRINT statement'"; 
$cmd.ExecuteNonQuery() | Out-Null; 
Write-Output $global:message
$cmd.CommandText = "RAISERROR('This is the message from the RAISERROR statement', 10, 1)";  
$cmd.ExecuteNonQuery() | Out-Null; 
Write-Output $global:message
$conn.Close();

Write-Output "Done"
Run Code Online (Sandbox Code Playgroud)

如果您期待多条消息,您可以将它们连接到变量。

$handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] {param($sender, $event) $global:message += $event.Message + "`n"};
Run Code Online (Sandbox Code Playgroud)

但是,无论哪种情况,它们都不会在抛出时引发,而是在查询完成后引发。

编辑:我找到了一个我更喜欢的解决方案,并想分享它。在处理程序中使用对象列表...

$events = new-object System.Collections.Generic.List[Object]
$handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] { param($sender, $event) $events.Add($event) }
Run Code Online (Sandbox Code Playgroud)

...然后ExecuteNonQuery循环写入所有消息

ForEach($event in $events)
{
    Write-Output $event.Message
}
Run Code Online (Sandbox Code Playgroud)