externalLibs/SQLPSX/SQLProfiler/SQLProfiler.psm1
# --------------------------------------------------------------------------- ### <Script> ### <Author> ### Laerte Junior ### </Author> ### <Description> ### Work with SQL Server Profiler Traces ### </Description> ### <Usage> ### </Usage> ### </Script> # --------------------------------------------------------------------------- #Test if Powershell is 64 or X86..This module only works in X86. $ErrorActionPreference = "Stop" $PowershellRunning = [intptr]::Size if ($PowershellRunning -ne 4) { Write-Host -ForegroundColor Red 'Attention. This module only runs on x86 Powershell. Execution interrupted' break } try { add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop } catch { add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo" } try { add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop; $smoVersion = 10 } catch { add-type -AssemblyName "Microsoft.SqlServer.Smo"; $smoVersion = 9 } try { add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfoExtended, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop; $smoVersion = 10 } catch { add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfoExtended"; $smoVersion = 9 } try { try { add-type -AssemblyName "Microsoft.SqlServer.SMOExtended, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop } catch { add-type -AssemblyName "Microsoft.SqlServer.SMOExtended" -EA Stop } } catch { Write-Warning "SMOExtended not available" } #Original Function Invoke-Sqlcmd2 in http://poshcode.org/1791 function Invoke-Sqlcmd2 { param( [Parameter(Position=0, Mandatory=$true ,ValueFromPipeline = $false)] [string]$ServerInstance, [Parameter(Position=1, Mandatory=$true ,ValueFromPipeline = $false)] [string]$Database, [Parameter(Position=2, Mandatory=$false ,ValueFromPipeline = $false)] [string]$UserName, [Parameter(Position=3, Mandatory=$false ,ValueFromPipeline = $false)] [string]$Password, [Parameter(Position=4, Mandatory=$true ,ValueFromPipeline = $false)] [string]$Query, [Parameter(Position=5, Mandatory=$false ,ValueFromPipeline = $false)] [Int32]$QueryTimeout=30 ) $conn=new-object System.Data.SqlClient.SQLConnection if ($UserName -and $Password) { $conn.ConnectionString="Server={0};Database={1};User ID={2};Pwd={3}" -f $ServerInstance,$Database,$UserName,$Password } else { $conn.ConnectionString="Server={0};Database={1};Integrated Security=True" -f $ServerInstance,$Database } $conn.Open() $cmd=new-object system.Data.SqlClient.SqlCommand($Query,$conn) $cmd.CommandTimeout=$QueryTimeout $ds=New-Object system.Data.DataSet $da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd) [void]$da.fill($ds) $conn.Close() $ds.Tables[0] } ####################### <# .SYNOPSIS Save SQLProfiler Trace into SQL Server Table. .DESCRIPTION Save SQLProfiler Trace into SQL Server Table.You can read and combine multiple SQL Server Trace files into a single SQL Server Table .PARAMETER $TraceFile Mandatory Object Object with Trace Files .PARAMETER $ServerName Mandatory String SQL Server Name .PARAMETER $DatabaseName Mandatory String SQL Server Database Name .PARAMETER $UserName String User name .PARAMETER $Password String Password .PARAMETER $TableName String SQL Server Table Name .PARAMETER $NewTable Switch IF informed, a new table will be created .INPUTS You can Pipe $TraceFile Object .OUTPUTS None .EXAMPLE Get-SQLProfiler -TraceFileName "c:\Temp\*.trc" | Save-SQLTraceToSQLTable -ServerName MyServer -DatabaseName MyDatabase -NewTable -TableName MyTable This command gets all Trace files in c:\temp and insert into a new table called Mytable .EXAMPLE Get-SQLProfiler -TraceFileName "c:\Temp\*.trc" | Save-SQLTraceToSQLTable -ServerName MyServer -DatabaseName MyDatabase -NewTable This command gets all Trace files in c:\temp and insert into a new table. The name will be created by the function = SQLTraceToSQLTable_yyyyMMddhhmmss .EXAMPLE Get-SQLProfiler -TraceFileName "c:\Temp\*.trc" | Save-SQLTraceToSQLTable -ServerName MyServer -DatabaseName MyDatabase -TableName MyTable This command gets all Trace files in c:\temp and insert into a created table called MyTable. .LINK http://sqlpsx.codeplex.com/ #> Function Save-InfoToSQLTable { PARAM( [Parameter(Position=1,Mandatory=$true, ValueFromPipeline=$true,HelpMessage="Object SQL Server Trace")] [ValidateScript({$_.GetType().Name -is [System.Object]})] $TraceFile , [Parameter(Position=2, Mandatory=$true, ValueFromPipeline = $false,HelpMessage="SQL Server Name")] [String] $ServerName, [Parameter(Position=3, Mandatory=$true, ValueFromPipeline = $false,HelpMessage="SQL Server Database Name")] [String] $DatabaseName, [Parameter(Position=4, Mandatory=$false, ValueFromPipeline = $false,HelpMessage="SQL Server Server User Name")] [string] $UserName, [Parameter(Position=5, Mandatory=$false, ValueFromPipeline = $false,HelpMessage="Password")] [string] $Password, [Parameter(Position=6, Mandatory=$false, ValueFromPipeline = $false,HelpMessage="SQL Server Table Name")] [String] $TableName ="", [Parameter(Position=7, Mandatory=$false, ValueFromPipeline = $false,HelpMessage="New Table will be created")] [switch] $NewTable = $false ) Begin { function ConvertTo-SQLDataType { param ([string] $DataType) switch -regex ($DataType) { ('^System.Int32|^System.Int16|^System.Int64') {'Int'} '^System.Boolean' {'Bit'} ('^System.Decimal|^System.Double') {'Float'} '^System.DateTime' { 'DateTime'} default {'Varchar(max)'} } } $verbosePreference="continue" $CreatedTable = $false $NewTablename = $Tablename $TodayDate = Get-Date -Format "yyyy-MM-dd" $FirsTime = $true if ($TableName -eq "" -and !$NewTable) { Write-output "Save-InfoToSQLTable Error Detail : You need to specify table name or -newtable" throw New-Object System.Management.Automation.PipelineStoppedException } try { if ($TableName) { $query = "sp_tables $TableName" } else { $query = 'Select getdate()' } Invoke-Sqlcmd2 -ServerInstance $ServerName -Database $DatabaseName -UserName $UserName -Password $Password -Query $query | Out-Null if ($UserName -and $Password) { $ConnectionString="Server={0};Database={1};User ID={2};Pwd={3}" -f $ServerName,$DatabaseName,$UserName,$Password } else { $ConnectionString="Server={0};Database={1};Integrated Security=True" -f $ServerName,$DatabaseName } } catch { Write-output "Save-InfoToSQLTable Error Detail : Connection to SQL Server. Please Verify parameters" throw New-Object System.Management.Automation.PipelineStoppedException } } Process { try { if ($FirsTime) { $ColumnsInsert = "" ; $Columns ="" ; $SQLCol="" ; $SQLData="" ; $Command="" ; $CommandCreate="" $ColumnsInsert = "SQLCommand.Parameters.Add(""@datetime"", '$(get-date)') | Out-Null ; " $TraceFile | Get-Member -MemberType NoteProperty | % { $Columns += "$($_.name) $(ConvertTo-SQLDataType $_.definition.substring(0,$_.definition.indexof(' ')))," $ColumnsInsert += "SQLCommand.Parameters.Add(""@$($_.name)"", NewTrace.$($_.name)) | Out-Null ; " $SQLCol += "$($_.name)," $SQLData += "@$($_.name)," } $SQLCol = "$($SQLCol.substring(0,$SQLCol.Length-1))" $SQLData = "$($SQLData.substring(0,$SQLData.Length-1))" $Command += "$($Columns.Substring(0,$Columns.Length-1)))" $ColumnsInsert = (($ColumnsInsert.substring(0,$ColumnsInsert.Length-1)) -replace 'NewTrace','$NewTrace') -replace 'SQLCommand','$SQLCommand' $FirsTime = $false } if (!$CreatedTable -and $Newtable ) { if ($tableName -eq "") { $NewTablename = "SQLTraceToSQLTable_$(get-date -format yyyyMMddhhmmss)"} $CommandCreate = " Create table dbo.$NewTablename([DateTime] Datetime,$($command)" $drop = "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[$NewTablename]') AND type in (N'U')) DROP TABLE [dbo].[$NewTablename]" Invoke-Sqlcmd2 -ServerInstance $ServerName -Database $DatabaseName -UserName $UserName -Password $Password -Query $drop | Out-Null Invoke-Sqlcmd2 -ServerInstance $ServerName -Database $DatabaseName -UserName $UserName -Password $Password -Query $CommandCreate | Out-Null $CreatedTable = $true Write-Host "Saving into SQL Server Table $($NewTableName) Server $($ServerName) Database $($DatabaseName)" } $SQLInsert = "Insert into $DatabaseName.dbo.$NewTablename ([DateTime],$($SQLCol)) values (@DateTime,$($SQLdata))" foreach ($NewTrace in $TraceFile) { $SqlConnection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString) $SqlConnection.open() $SQLCommand = new-object System.Data.SqlClient.SqlCommand($SQLInsert,$SqlConnection) Invoke-Expression $ColumnsInsert $SQLCommand.executenonquery() | Out-Null $SqlConnection.close() } } Catch { Write-output - "Save-SQLTraceToSQLTable Error Detail : $Error[0]" throw New-Object System.Management.Automation.PipelineStoppedException } } } ####################### <# .SYNOPSIS Read SQL Server Profiler Traces. .DESCRIPTION Read SQL Server Profiler Traces.You can read and combine multiple SQL Server Trace files and differents events. .PARAMETER $TraceFileName Mandatory Object Object with Trace Files .PARAMETER $FileToTable String Switch indicate that each SQL Server Trace will inserted on New SQL Server Table. Each table will be called PowershellTraceTable_ and .trc Name. .PARAMETER $ServerName String SQL Server Name .PARAMETER $ServerName String SQL Server Name .PARAMETER $DatabaseName String SQL Server Database Name .INPUTS You can Pipe $TraceFileName Files .OUTPUTS PowerShell Object .EXAMPLE Get-SQLProfiler -TraceFileName "c:\Temp\*.trc" This command gets all Trace files in c:\temp .EXAMPLE Get-SQLProfiler -TraceFileName "c:\Temp\*.trc" | where-object {$_.TexTdata -like '*usp_dosomething*'} | Select * This command gets all Trace files in c:\temp and filter only textdata like *usp_dosomething* .EXAMPLE (Get-SQLProfiler -TraceFileName "c:\Temp\SQL*.trc" | where-object {$_.TexTdata -like '*usp_dosomething*'} | ConvertTo-XML -Notypeinformation).save("c:\temp\TraceOut.XML) This command gets all Trace files started with SQL in c:\temp filter by usp_dosomething and output to XML .EXAMPLE Get-SqlProfiler -TraceFileName "c:\Temp\SQL*.trc" -FileToTable -ServerName MyServer -DatabaseName MyDatabase This command gets all Trace files started with SQL in c:\temp and create a SQL Server Table for each Trace File called PowershellTraceTable_ and .trc Name .LINK http://sqlpsx.codeplex.com/ #> Function Get-SQLProfiler () { [CmdletBinding()] PARAM( [Parameter(Position=1,Mandatory=$true, ValueFromPipeline=$true,HelpMessage="SQL Server Profiler Trace File")] [String] $TraceFileName ) begin { $verbosePreference="continue" } process { try { $LineNumber = 1 # Get All .trc files (one or various) foreach ($TraceFilePath in Get-ChildItem $TraceFileName -ErrorAction Stop ) { try { #get trace name to create table $TraceFileNameTRC = ($TraceFilePath.PSChildName).trim() $TraceFileNameTRC = $TraceFileNameTRC.Trim() [String] $TraceFilePathString = $TraceFilePath $TableName = "PowershellTraceTable_" + $TraceFileNameTRC.substring(0,$TraceFileNameTRC.length -4) #$TableName = "Powershell" $TraceFileReader = New-Object Microsoft.SqlServer.Management.Trace.TraceFile $TraceFileReader.InitializeAsReader($TraceFilePathString) if ($TraceFileReader.Read()-eq $true) { #get all columns from the trace $TotalFields = ($TraceFileReader.FieldCount) -1 for($Count = 0;$Count -le $TotalFields;$Count++) { $block += '$FieldName = $TraceFileReader.GetName(' + $Count + '); $FieldValue = $TraceFileReader.GetValue($TraceFileReader.GetOrdinal($FieldName)); if ($FieldValue -eq $Null){ $FieldValue = ''''}; $ObjectTrace| add-member Noteproperty $FieldName $FieldValue ; ' } while ($TraceFileReader.Read()) { $ObjectTrace = New-Object PSObject $ObjectTrace | add-member Noteproperty LineNumber $LineNumber $ObjectTrace | add-member Noteproperty TraceFile $TraceFileNameTRC Invoke-Expression $block $ObjectTrace $LineNumber ++ } $TraceFileReader.close() } } Catch { $msg = $error[0] write-warning $msg } } } Catch { $msg = $error[0] write-warning $msg } } } |