Skip to content

Commit 17e5f47

Browse files
committed
Changes for #310, #309
1 parent a59fcfc commit 17e5f47

File tree

1 file changed

+68
-190
lines changed

1 file changed

+68
-190
lines changed

PSBlitz.ps1

+68-190
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ param(
278278
###Internal params
279279
#Version
280280
$Vers = "5.1.0"
281-
$VersDate = "2025-02-02"
281+
$VersDate = "2025-02-03"
282282
$TwoMonthsFromRelease = [datetime]::ParseExact("$VersDate", 'yyyy-MM-dd', $null).AddMonths(2)
283283
$NowDate = Get-Date
284284
#Get script path
@@ -812,7 +812,9 @@ function Export-PlansAndDeadlocks {
812812
[Parameter(Position = 5, Mandatory = $false)]
813813
[string] $FPrefix = '',
814814
[Parameter(Position = 6, Mandatory = $false)]
815-
[switch] $DebugInfo
815+
[switch] $DebugInfo,
816+
[Parameter(Position = 7, Mandatory = $false)]
817+
[switch] $FileNameFromColumn
816818
)
817819
try {
818820
#if ($DebugInfo) {
@@ -824,11 +826,20 @@ function Export-PlansAndDeadlocks {
824826
foreach ($row in $DataTable) {
825827
$i += 1
826828
$FileName = "-- N/A --"
827-
if($DataTable.Rows[$RowNum][$XMLColName] -ne [System.DBNull]::Value){
828-
$FileName = $FPrefix +'_'+ $i + '.' + $OutputType
829+
if (($DataTable.Rows[$RowNum][$XMLColName] -ne [System.DBNull]::Value) -and
830+
(($DataTable.Rows[$RowNum][$FNameColName] -like "Deadlock*") -or
831+
($XMLColName -ne "deadlock_graph")) ) {
832+
if ($FileNameFromColumn) {
833+
$FileName = $DataTable.Rows[$RowNum][$FNameColName]
834+
}
835+
else {
836+
$FileName = $FPrefix + '_' + $i + '.' + $OutputType
837+
}
829838
$DataTable.Rows[$RowNum][$XMLColName] | Format-XML | Set-Content -Path "$FileDir\$FileName" -Force
830839
}
831-
$DataTable.Rows[$RowNum][$FNameColName] = $FileName
840+
if ($FileNameFromColumn -eq $false) {
841+
$DataTable.Rows[$RowNum][$FNameColName] = $FileName
842+
}
832843
$RowNum += 1
833844
}
834845

@@ -841,6 +852,35 @@ function Export-PlansAndDeadlocks {
841852
}
842853
}
843854

855+
function Add-QueryName {
856+
param (
857+
[Parameter(Position = 0, Mandatory = $true)]
858+
[System.Data.DataTable] $DataTable,
859+
[Parameter(Position = 1, Mandatory = $true)]
860+
[string] $QueryNameColName,
861+
[Parameter(Position = 2, Mandatory = $true)]
862+
[string] $QueryTextColName,
863+
[Parameter(Position = 3, Mandatory = $true)]
864+
[string] $QPrefix
865+
)
866+
try {
867+
$RowNum = 0
868+
$i = 0
869+
foreach ($row in $DataTable) {
870+
if ($DataTable.Rows[$RowNum][$QueryTextColName] -ne [System.DBNull]::Value) {
871+
$i += 1
872+
$QueryName = $QPrefix + "_" + $i + ".query"
873+
}
874+
else { $QueryName = "-- N/A --" }
875+
$DataTable.Rows[$RowNum][$QueryNameColName] = $QueryName
876+
$RowNum += 1
877+
}
878+
}
879+
catch {
880+
Write-Host " Error adding query names: $_" -ForegroundColor Red
881+
}
882+
}
883+
844884
function Convert-TableToExcel {
845885
param (
846886
[Parameter(Position = 0, Mandatory = $true)]
@@ -1298,7 +1338,7 @@ if ([string]::IsNullOrEmpty($ServerName)) {
12981338
if (!([string]$AdvOptions = Read-Host -Prompt "Show advanced options?(empty defaults to N)[Y/N]")) {
12991339
$AdvOptions = "N"
13001340
}
1301-
if($AdvOptions -eq "Y"){
1341+
if ($AdvOptions -eq "Y") {
13021342
##Get top N queries from cache
13031343
[int]$CacheTop = Read-Host -Prompt "Number of top resource intensive queries to return?(empty defaults to 10)"
13041344

@@ -1837,10 +1877,10 @@ $Query = "SELECT CAST(DATEDIFF(HH, [sqlserver_start_time], GETDATE()) / 24.00 AS
18371877
$Query = $Query + "`nFROM [sys].[dm_os_sys_info];"
18381878
Invoke-PSBlitzQuery -QueryIn $Query -StepNameIn "Uptime check" -ConnStringIn $ConnString -CmdTimeoutIn 100
18391879
if ($global:StepOutcome -eq "Success") {
1840-
if($global:PSBlitzSet.Tables[0].Rows[0]["uptime_days"] -lt 7.00){
1880+
if ($global:PSBlitzSet.Tables[0].Rows[0]["uptime_days"] -lt 7.00) {
18411881
[string]$DaysUp = $global:PSBlitzSet.Tables[0].Rows[0]["uptime_days"]
1842-
Write-Host "Warning: Instance uptime is less than 7 days - $DaysUp" -Fore Red
1843-
Write-Host "->Diagnostics data might not be reliable with less than 7 days of uptime." -Fore Red
1882+
Write-Host "Warning: Instance uptime is less than 7 days - $DaysUp" -Fore Red
1883+
Write-Host "->Diagnostics data might not be reliable with less than 7 days of uptime." -Fore Red
18441884
}
18451885
Invoke-ClearVariables PSBlitzSet
18461886
}
@@ -2034,20 +2074,8 @@ $htmlTable4
20342074

20352075
$htmlTable2 = Convert-TableToHtml $TempTabTbl -DebugInfo:$DebugInfo
20362076

2037-
#Add query name
2038-
$RowNum = 0
2039-
$i = 0
2040-
foreach ($row in $TempDBSessTbl) {
2041-
if ($TempDBSessTbl.Rows[$RowNum]["query_text"] -ne [System.DBNull]::Value) {
2042-
$i += 1
2043-
$QueryName = "TempDB_" + $i + ".query"
2044-
2045-
}
2046-
else { $QueryName = "" }
2047-
$TempDBSessTbl.Rows[$RowNum]["query"] = $QueryName
2048-
$RowNum += 1
2049-
}
2050-
2077+
Add-QueryName $TempDBSessTbl "query" "query_text" "TempDB"
2078+
20512079
$htmlTable3 = Convert-TableToHtml $TempDBSessTbl -ExclCols "query_text" -DebugInfo:$DebugInfo -AnchorFromHere -AnchorIDs "TempDB"
20522080

20532081
$htmlTable4 = Convert-QueryTableToHtml $TempDBSessTbl -DebugInfo:$DebugInfo -Cols "query", "query_text" -AnchorToHere -AnchorID "TempDB"
@@ -2160,26 +2188,9 @@ $htmlTable2
21602188
Write-Host " ->No open transactions found."
21612189
}
21622190
else {
2163-
##Exporting execution plans to file
2164-
#Set counter used for row retrieval
2165-
[int]$RowNum = 0
2166-
$i = 0
2167-
#loop through each row
2168-
if ($DebugInfo) {
2169-
Write-Host " ->Exporting execution plans" -fore yellow
2170-
}
2171-
foreach ($row in $AcTranTbl) {
2172-
$i += 1
2173-
if ($AcTranTbl.Rows[$RowNum]["current_plan"] -ne [System.DBNull]::Value) {
2174-
[string]$SQLPlanFile = $AcTranTbl.Rows[$RowNum]["current_plan_file"]
2175-
$AcTranTbl.Rows[$RowNum]["current_plan"] | Format-XML | Set-Content -Path $PlanOutDir\$($SQLPlanFile) -Force
2176-
}
2177-
if ($AcTranTbl.Rows[$RowNum]["most_recent_plan"] -ne [System.DBNull]::Value) {
2178-
[string]$SQLPlanFile = $AcTranTbl.Rows[$RowNum]["most_recent_plan_file"]
2179-
$AcTranTbl.Rows[$RowNum]["most_recent_plan"] | Format-XML | Set-Content -Path $PlanOutDir\$($SQLPlanFile) -Force
2180-
}
2181-
$RowNum += 1
2182-
}
2191+
2192+
Export-PlansAndDeadlocks $AcTranTbl $PlanOutDir "current_plan" "current_plan_file" -DebugInfo:$DebugInfo -FileNameFromColumn
2193+
Export-PlansAndDeadlocks $AcTranTbl $PlanOutDir "most_recent_plan" "most_recent_plan_file" -DebugInfo:$DebugInfo -FileNameFromColumn
21832194
if ($ToHTML -eq "Y") {
21842195

21852196
$tableName = "Open transaction info"
@@ -2825,25 +2836,8 @@ $JumpToTop
28252836
if ($DebugInfo) {
28262837
Write-Host " ->Exporting execution plans for $SortOrder" -fore yellow
28272838
}
2828-
<#Set counter used for row retrieval
2829-
$RowNum = 0
2830-
#Setting $i to 0
2831-
$i = 0
2832-
foreach ($row in $BlitzCacheTbl) {
2833-
#Increment file name counter
2834-
$i += 1
2835-
$SQLPlanFile = "-- N/A --"
2836-
#Get only the column storing the execution plan data that's not NULL and write it to a file
2837-
if ($BlitzCacheTbl.Rows[$RowNum]["Query Plan"] -ne [System.DBNull]::Value) {
2838-
$SQLPlanFile = $FileSOrder + "_" + $i + ".sqlplan"
2839-
$BlitzCacheTbl.Rows[$RowNum]["Query Plan"] | Format-XML | Set-Content -Path "$PlanOutDir\$SQLPlanFile" -Force
2840-
}
2841-
$BlitzCacheTbl.Rows[$RowNum]["SQLPlan File"] = $SQLPlanFile
2842-
#Increment row retrieval counter
2843-
$RowNum += 1
2844-
}
2845-
#>
2846-
Export-PlansAndDeadlocks $BlitzCacheTbl $PlanOutDir "Query Plan" "SQLPlan File" -FPrefix $FileSOrder -DebugInfo:$DebugInfo
2839+
2840+
Export-PlansAndDeadlocks $BlitzCacheTbl $PlanOutDir "Query Plan" "SQLPlan File" -FPrefix $FileSOrder -DebugInfo:$DebugInfo
28472841

28482842
##Add database names to array
28492843
if (([string]::IsNullOrEmpty($CheckDB)) -and ($IsAzureSQLDB -eq $false)) {
@@ -2899,19 +2893,8 @@ $JumpToTop
28992893

29002894
if ($ToHTML -eq "Y") {
29012895
$SheetName = $SheetName -replace "Top Queries - ", ""
2902-
2903-
$RowNum = 0
2904-
$i = 0
2905-
foreach ($row in $BlitzCacheTbl) {
2906-
if ($BlitzCacheTbl.Rows[$RowNum]["Query Text"] -ne [System.DBNull]::Value) {
2907-
$i += 1
2908-
$QueryName = $FileSOrder + "_" + $i + ".query"
2909-
}
2910-
else { $QueryName = "" }
2911-
$BlitzCacheTbl.Rows[$RowNum]["Query"] = $QueryName
2912-
$RowNum += 1
2913-
}
2914-
2896+
2897+
Add-QueryName $BlitzCacheTbl "Query" "Query Text" $FileSOrder
29152898

29162899
$htmlTable1 = Convert-TableToHtml $BlitzCacheTbl -NoCaseChange -ExclCols "Query Text", "Query Plan" -DebugInfo:$DebugInfo -AnchorFromHere -AnchorIDs $FileSOrder
29172900

@@ -3286,39 +3269,11 @@ ELSE IF ( (SELECT PARSENAME(CONVERT(NVARCHAR(128), SERVERPROPERTY ('PRODUCTVERSI
32863269
Write-Host " ->Exporting execution plans" -fore yellow
32873270
}
32883271

3289-
#Set counter used for row retrieval
3290-
<#$RowNum = 0
3291-
#Setting $i to 0
3292-
$i = 0
3293-
foreach ($row in $BlitzQSTbl) {
3294-
#Increment file name counter
3295-
$i += 1
3296-
$SQLPlanFile = "-- N/A --"
3297-
#Get only the column storing the execution plan data that's not NULL and write it to a file
3298-
if ($BlitzQSTbl.Rows[$RowNum]["query_plan_xml"] -ne [System.DBNull]::Value) {
3299-
$SQLPlanFile = "QueryStore_" + $i + ".sqlplan"
3300-
$BlitzQSTbl.Rows[$RowNum]["query_plan_xml"] | Format-XML | Set-Content -Path "$PlanOutDir\$SQLPlanFile" -Force
3301-
}
3302-
$BlitzQSTbl.Rows[$RowNum]["SQLPlan File"] = $SQLPlanFile
3303-
#Increment row retrieval counter
3304-
$RowNum += 1
3305-
}
3306-
#>
33073272
Export-PlansAndDeadlocks $BlitzQSTbl $PlanOutDir "query_plan_xml" "SQLPlan File" -FPrefix "QueryStore" -DebugInfo:$DebugInfo
33083273

33093274
if ($ToHTML -eq "Y") {
33103275

3311-
$RowNum = 0
3312-
$i = 0
3313-
foreach ($row in $BlitzQSTbl) {
3314-
if ($BlitzQSTbl.Rows[$RowNum]["query_sql_text"] -ne [System.DBNull]::Value) {
3315-
$i += 1
3316-
$QueryName = "QueryStore_" + $i + ".query"
3317-
}
3318-
else { $QueryName = "" }
3319-
$BlitzQSTbl.Rows[$RowNum]["Query"] = $QueryName
3320-
$RowNum += 1
3321-
}
3276+
Add-QueryName $BlitzQSTbl "Query" "query_sql_text" "QueryStore"
33223277

33233278
$htmlTable1 = Convert-TableToHtml $BlitzQSTbl -ExclCols "query_sql_text", "query_plan_xml" -CSSClass "QueryStoreTab sortable" -AnchorFromHere -AnchorIDs "QueryStore" -DebugInfo:$DebugInfo
33243279

@@ -3452,28 +3407,11 @@ ELSE IF ( (SELECT PARSENAME(CONVERT(NVARCHAR(128), SERVERPROPERTY ('PRODUCTVERSI
34523407
$BlitzIxTbl = $global:PSBlitzSet.Tables[0]
34533408
if ("0", "4" -Contains $Mode) {
34543409
#Export sample execution plans for missing indexes (SQL Server 2019 only)
3455-
#Since we're already looping through the result set here, might as well add and
3456-
#populate the plan file name column as well
34573410
if ($DebugInfo) {
34583411
Write-Host " ->Exporting missing index sample execution plans (if any)" -fore yellow
34593412
}
34603413

3461-
<#$RowNum = 0
3462-
$i = 0
3463-
foreach ($row in $BlitzIxTbl) {
3464-
if ($BlitzIxTbl.Rows[$RowNum]["Finding"] -like "*Missing Index") {
3465-
$SQLPlanFile = "--N/A--"
3466-
$i += 1
3467-
if ($BlitzIxTbl.Rows[$RowNum]["Sample Query Plan"] -ne [System.DBNull]::Value) {
3468-
$SQLPlanFile = "MissingIndex_$i.sqlplan"
3469-
$BlitzIxTbl.Rows[$RowNum]["Sample Query Plan"] | Format-XML | Set-Content -Path "$PlanOutDir\$SQLPlanFile" -Force
3470-
}
3471-
$BlitzIxTbl.Rows[$RowNum]["Sample Plan File"] = $SQLPlanFile
3472-
}
3473-
$RowNum += 1
3474-
}
3475-
#>
3476-
Export-PlansAndDeadlocks $BlitzIxTbl $PlanOutDir "Sample Query Plan" "Sample Plan File" -FPrefix "MissingIndex" -DebugInfo:$DebugInfo
3414+
Export-PlansAndDeadlocks $BlitzIxTbl $PlanOutDir "Sample Query Plan" "Sample Plan File" -FPrefix "MissingIndex" -DebugInfo:$DebugInfo
34773415
}
34783416
if ($ToHTML -eq "Y") {
34793417

@@ -3615,55 +3553,18 @@ ELSE IF ( (SELECT PARSENAME(CONVERT(NVARCHAR(128), SERVERPROPERTY ('PRODUCTVERSI
36153553
}
36163554
else {
36173555
##Exporting deadlock graphs to file
3618-
#Set counter used for row retrieval
3619-
[int]$RowNum = 0
3620-
#Setting $i to 0
3621-
#$i = 1
36223556
if ($DebugInfo) {
36233557
Write-Host " ->Exporting deadlock graphs (if any)" -fore yellow
36243558
}
3625-
foreach ($row in $TblLockDtl) {
3626-
<#
3627-
Get only the column storing the deadlock graph data that's not NULL, limit to one export per event by filtering for VICTIM, and write it to a file
3628-
#>
3629-
if (($TblLockDtl.Rows[$RowNum]["deadlock_graph"] -ne [System.DBNull]::Value) -and ($TblLockDtl.Rows[$RowNum]["deadlock_group"] -like "*VICTIM*")) {
3630-
#format the event date to append to file name
3631-
#[string]$DLDate =
3632-
[string]$DLFile = $TblLockDtl.Rows[$RowNum]["deadlock_graph_file"]
3633-
#write .xdl file
3634-
$TblLockDtl.Rows[$RowNum]["deadlock_graph"] | Format-XML | Set-Content -Path "$XDLOutDir\$DLFile" -Force
3635-
#$TblLockDtl.Rows[$RowNum]["deadlock_graph_file"] = $DLFile
3636-
$i += 1
3637-
}
3638-
#Increment row retrieval counter
3639-
$RowNum += 1
3640-
}
3559+
3560+
Export-PlansAndDeadlocks $TblLockDtl $XDLOutDir "deadlock_graph" "deadlock_graph_file" -DebugInfo:$DebugInfo -FileNameFromColumn
36413561

36423562
##Exporting execution plans to file
36433563
if ($DebugInfo) {
36443564
Write-Host " ->Exporting execution plans related to deadlocks." -fore yellow
36453565
}
3646-
#Set counter used for row retrieval
3647-
$RowNum = 0
3648-
#Setting $i to 0
3649-
$i = 0
36503566

3651-
foreach ($row in $TblLockPlans) {
3652-
#Increment file name counter
3653-
$i += 1
3654-
$SQLPlanFile = "-- N/A --"
3655-
$QueryName = "-- N/A --"
3656-
#Get only the column storing the execution plan data that's not NULL and write it to a file
3657-
if ($TblLockPlans.Rows[$RowNum]["query_plan"] -ne [System.DBNull]::Value) {
3658-
$SQLPlanFile = "Deadlock_" + $i + ".sqlplan"
3659-
$QueryName = "DeadlockPlan_" + $i + ".query"
3660-
$TblLockPlans.Rows[$RowNum]["query_plan"] | Format-XML | Set-Content -Path "$PlanOutDir\$SQLPlanFile" -Force
3661-
}
3662-
$TblLockPlans.Rows[$RowNum]["sqlplan_file"] = $SQLPlanFile
3663-
$TblLockPlans.Rows[$RowNum]["query"] = $QueryName
3664-
#Increment row retrieval counter
3665-
$RowNum += 1
3666-
}
3567+
Export-PlansAndDeadlocks $TblLockPlans $PlanOutDir "query_plan" "sqlplan_file" -FPrefix "DeadlockPlan" -DebugInfo:$DebugInfo
36673568

36683569
if ($ToHTML -eq "Y") {
36693570

@@ -3681,6 +3582,8 @@ ELSE IF ( (SELECT PARSENAME(CONVERT(NVARCHAR(128), SERVERPROPERTY ('PRODUCTVERSI
36813582

36823583
$htmlTable3 = Convert-QueryTableToHtml $TblLockDtl -Cols "query", "query_text" -AnchorToHere -AnchorID "DeadlockDtlTable" -DebugInfo:$DebugInfo
36833584

3585+
Add-QueryName $TblLockPlans "query" "query_text" "DeadlockPlan"
3586+
36843587
$htmlTable4 = Convert-TableToHtml $TblLockPlans -AnchorFromHere -ExclCols "query_text", "query_plan" -AnchorIDs "DeadlockPlan" -DebugInfo:$DebugInfo
36853588

36863589
$htmlTable5 = Convert-QueryTableToHtml $TblLockPlans -Cols "query", "query_text" -AnchorToHere -AnchorID "DeadlockPlan" -DebugInfo:$DebugInfo
@@ -4116,19 +4019,8 @@ finally {
41164019
if ($DebugInfo) {
41174020
Write-Host " ->Exporting execution plans" -fore yellow
41184021
}
4119-
$RowNum = 0
4120-
$i = 0
4121-
foreach ($row in $BlitzWhoAggTbl) {
4122-
$i += 1
4123-
$SQLPlanFile = "-- N/A --"
4124-
if ($BlitzWhoAggTbl.Rows[$RowNum]["query_plan"] -ne [System.DBNull]::Value) {
4125-
4126-
$SQLPlanFile = "RunningNow_" + $i + ".sqlplan"
4127-
$BlitzWhoAggTbl.Rows[$RowNum]["query_plan"] | Format-XML | Set-Content -Path "$PlanOutDir\$SQLPlanFile" -Force
4128-
}
4129-
$BlitzWhoAggTbl.Rows[$RowNum]["sqlplan_file"] = $SQLPlanFile
4130-
$RowNum += 1
4131-
}
4022+
4023+
Export-PlansAndDeadlocks $BlitzWhoAggTbl $PlanOutDir "query_plan" "sqlplan_file" -FPrefix "RunningNow" -DebugInfo:$DebugInfo
41324024

41334025
#Get capture time-frame
41344026
$BtilzWhoStartTime = $BlitzWhoTbl | Sort-Object -Property "CheckDate" | Select-Object -ExpandProperty "CheckDate" -First 1
@@ -4161,29 +4053,15 @@ finally {
41614053
Save-HtmlFile $html "BlitzWho.html" $HTMLOutDir $DebugInfo
41624054
Invoke-ClearVariables html, htmlTable
41634055

4164-
#$BlitzWhoAggTbl.Columns.Add("Query", [string]) | Out-Null
4165-
$RowNum = 0
4166-
$i = 0
4167-
4168-
foreach ($row in $BlitzWhoAggTbl) {
4169-
$i += 1
4170-
if ($BlitzWhoAggTbl.Rows[$RowNum]["query_text"] -ne [System.DBNull]::Value) {
4171-
$QueryName = "RunningNow_" + $i + ".query"
4172-
}
4173-
else { $QueryName = "-- N/A --" }
4174-
$BlitzWhoAggTbl.Rows[$RowNum]["Query"] = $QueryName
4175-
$RowNum += 1
4176-
}
41774056
$HtmlTabName = "Aggregated Session Activity"
41784057
if (!([string]::IsNullOrEmpty($CheckDB))) {
41794058
$HtmlTabName += " for $CheckDB"
41804059
}
41814060
elseif ($IsAzureSQLDB) {
41824061
$HtmlTabName += " for $ASDBName"
41834062
}
4184-
4063+
Add-QueryName $BlitzWhoAggTbl "Query" "query_text" "RunningNow"
41854064
$htmlTable = Convert-TableToHtml $BlitzWhoAggTbl -CSSClass "ActiveSessionsTab sortable" -AnchorFromHere -AnchorIDs "RunningNow" -ExclCols "query_text", "query_plan" -DebugInfo:$DebugInfo
4186-
41874065
$htmlTable1 = Convert-QueryTableToHtml $BlitzWhoAggTbl -Cols "query", "query_text" -AnchorToHere -AnchorID "RunningNow" -DebugInfo:$DebugInfo
41884066

41894067
$html = $HTMLPre + @"

0 commit comments

Comments
 (0)