Jef*_*ias 6 sql-server powershell sqlcmd sp-askbrent
我正在尝试sp_AskBrent
使用 PowerShell运行Invoke-SQLCmd
并在变量中捕获其输出:
$query = "EXEC SAIDBA.monitoring.sp_AskBrent @Seconds=10;"
$check = Invoke-Sqlcmd -ServerInstance $ServerInstance -Query $query
-ErrorAction Stop -ConnectionTimeout 3
Run Code Online (Sandbox Code Playgroud)
使用ExpertMode = 0运行时,没问题。
但是当使用ExpertMode = 1运行时,我们注意到三件事:
$check
一片空白 它以以下错误结束:
Invoke-Sqlcmd:SQL PowerShell 中不允许出现重复的列名。要重复列,请使用 Column_Name AS New_Name 格式的重复列的列别名。
在行:1 字符:18
- $check = Invoke-Sqlcmd -ServerInstance $ServerInstance -Query $query -Er ...
- CategoryInfo: SyntaxError: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
- FullQualifiedErrorId : DuplicateColumnNameErrorMessage, Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
我认为有一种解决方法可以提供sp_AskBrent
将ExpertMode数据存储到表中并随后从这些表中选择的参数,但我想确保无法在 PowerShell 中立即恢复所有内容。
Bre*_*zar 10
布伦特来了 正确,@ExpertMode = 1 打开多个结果集 - 诊断、等待统计、文件统计和性能计数器。
如果您只想要一个结果集,请不要打开@ExpertMode。
如果您需要多个结果集,但您的应用程序(在本例中为 PoSH)无法使用它们,您需要将它们记录到表中。这就是这些参数的用武之地:
如果你想让它以不同的方式工作,请描述你需要什么,我会看看我是否能想出办法来得到它。希望有帮助!
来自评论:
我实际上正在考虑编写一个运行状况检查脚本,我将在发生事故或监控时运行该脚本,并解析
sp_AskBrent
.
嗯不错。只需要记住几件事 - 表格不会自行清理,@SkipChecksQueries = 0
例如,如果您使用参数,它们会变大。该sp_AskBrent®
授权还禁止发行,所以只要确保你没有捆绑的脚本,或者在服务器上安装它,你没有自己。否则,去吧!如果有什么我能做的事情可以帮助使它更容易,大喊大叫。
所有输出表中都有一个日期字段来帮助您维护历史表。
小智 7
不要低估布伦特的回答(尽管他有时确实在训练中给出了一些不错的答案)......
在 PowerShell 中,您可以执行返回多个数据集的查询,Invoke-Sqlcmd
但不能使用它来执行此操作,因为它当前不是为它构建的。
您将有两种选择:使用 .NET 本机代码(例如System.Data.SqlClient
)或使用可信赖的SMO
. SMO
如果我想包含服务器属性或其他可以SMO
访问的内容,我倾向于简单地选择。
在sp_AskBrent
我继续的上下文中,花了几分钟将输出构建到 HTML 报告中。此脚本的主要兴趣点是要处理多个数据集,您将ExecuteWithResults
使用以下命名空间下可用的方法执行查询:
Microsoft.SqlServer.Management.Smo.Server
Microsoft.SqlServer.Management.Smo.Database
您可以database
在此处查看 MSDN上使用命名空间的示例。在我的脚本中,我使用了Server
命名空间。无论哪种方式它都可以工作,但是如果您查看 MSDN 文章,ExecuteWithResults
它将返回一个DataSet
对象,并且该对象将包含一个DataTable
. 的数量DataTables
基于您的代码返回的数据集数量。在布伦特程序的情况下,您将返回 5 DataTables
。您可以在下面的代码中通过在循环$results.Count
之前添加 in 来验证这一点foreach
。
现在这个脚本中的另一个注意事项是我选择输出到 HTML。如果需要,您可以选择另一种格式,但将所有内容输出到控制台是不可读的。我还会注意到我添加了帮助信息,因此Get-Help
如果您需要查看有关参数的详细信息或提醒自己如何调用它,则可以针对脚本使用。
对于这个例子,我使用了Pinal Dave的一小段代码来在我的本地实例上生成一些 CPU 使用率。(否则程序不会返回太多信息)。
脚本
<#
.SYNOPSIS
Executes sp_AskBrent and outputs to HTML
.DESCRIPTION
Execute sp_AskBrent in normal or expert mode and outputs to an HTML.
.PARAMETER server
String. [REQUIRED] The SQL Server instance you wish to get results on.
.PARAMETER timelimit
Integer. Time used for @seconds parameter of sp_AskBrent
.PARAMETER expertMode
Switch. Just opts to have @ExpertMode = 1 for the query
.PARAMETER sqlversion
Integer. If on machine with multiple SQL Server tool versions installed, specify version.
.PARAMETER outfile
String. Set output file to generate HTML
.EXAMPLE
Run command in normal mode, which returns one dataset
.\Script.ps1 -server MANATARMS\SQL12 -timelimit 5 -sqlversion 11 -outfile 'C:\temp\MyServer.html'
.EXAMPLE
Run command in expert mode, which returns multiple datasets
.\Script.ps1 -server MANATARMS\SQL12 -timelimit 5 -expertMode -sqlversion 11 -outfile 'C:\temp\MyServer.html'
.NOTES
Does not check if sp_AskBrent is on the server before executing the query.
#>
[cmdletbinding()]
param(
[Parameter(Mandatory=$true,Position=0)]
[Alias("instance")]
[string]
$server,
[Parameter(Mandatory=$false,Position=1)]
[int]
$timelimit = 10,
[Parameter(Mandatory=$false,Position=2)]
[switch]
$expertMode,
[Parameter(Mandatory=$false,Position=3)]
[int]
$sqlversion = 11,
[Parameter(Mandatory=$false,Position=4)]
[string]
$outfile= 'C:\temp\Testing.html'
)
$HtmlTop = @"
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-color:white;
font-family:Tahoma,Arial;
font-size:10pt;
}
table {
border-collapse: collapse;
}
th {
border:2px solid black;
color:white;
background-color: #0066FF;
padding: 4px;
}
th.subhead {
color:black;
background-color: #8dbafc
}
td {
border: 1px solid black;
padding: 2px;
}
</style>
</head>
<body>
<h2>Server Name: $($server)</h2>
<h3>Run Date: $(Get-Date)</h3>
"@
$HtmlTop | Out-File -FilePath $outfile -Force
if ($expertMode) {
$askBrent = "EXEC sp_AskBrent @Seconds=$($timelimit), @ExpertMode=1"
}
else {
$askBrent = "EXEC sp_AskBrent @Seconds=$($timelimit), @ExpertMode=0"
}
try {
Add-Type -AssemblyName "Microsoft.SqlServer.Smo,Version=$($sqlversion).0.0.0,Culture=neutral,PublicKeyToken=89845dcd8080cc91"
}
catch {
Add-Type -AssemblyName "Microsoft.SqlServer.Smo"
}
$srv = New-Object 'Microsoft.SqlServer.Management.Smo.Server' $server
$results = $srv.ConnectionContext.ExecuteWithResults($askBrent);
foreach ($t in $results.Tables) {
$t | Select-Object * -ExcludeProperty RowError, RowState, HasErrors, Table, ItemArray | ConvertTo-Html -As Table -Fragment | Out-String | Out-File -FilePath $outfile -Append
## This is just to get a break between tables ##
"<hr>" | Out-File -FilePath $outfile -Append
}
Run Code Online (Sandbox Code Playgroud)