functions/Read-DbaTransactionLog.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
function Read-DbaTransactionLog {
    <#
    .SYNOPSIS
        Reads the live Transaction log from specified SQL Server Database
 
    .DESCRIPTION
        Using the fn_dblog function, the live transaction log is read and returned as a PowerShell object
 
        This function returns the whole of the log. The information is presented in the format that the logging subsystem uses.
 
        A soft limit of 0.5GB of log as been implemented. This is based on testing. This limit can be overridden
        at the users request, but please be aware that this may have an impact on your target databases and on the
        system running this function
 
    .PARAMETER SqlInstance
        The target SQL Server instance or instances
 
    .PARAMETER SqlCredential
        A credential to use to connect to the SQL Instance rather than using Windows Authentication
 
    .PARAMETER Database
        Database to read the transaction log of
 
    .PARAMETER IgnoreLimit
        Switch to indicate that you wish to bypass the recommended limits of the function
 
    .PARAMETER RowLimit
        Will limit the number of rows returned from the transaction log
 
    .PARAMETER EnableException
        By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.
        This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting.
        Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch.
 
    .NOTES
        Tags: Database, Log, LogFile
        Author: Stuart Moore (@napalmgram), stuart-moore.com
 
        Website: https://dbatools.io
        Copyright: (c) 2018 by dbatools, licensed under MIT
        License: MIT https://opensource.org/licenses/MIT
 
    .EXAMPLE
        PS C:\> $Log = Read-DbaTransactionLog -SqlInstance sql2016 -Database MyDatabase
 
        Will read the contents of the transaction log of MyDatabase on SQL Server Instance sql2016 into the local PowerShell object $Log
 
    .EXAMPLE
        PS C:\> $Log = Read-DbaTransactionLog -SqlInstance sql2016 -Database MyDatabase -IgnoreLimit
 
        Will read the contents of the transaction log of MyDatabase on SQL Server Instance sql2016 into the local PowerShell object $Log, ignoring the recommendation of not returning more that 0.5GB of log
 
    #>

    [CmdletBinding(DefaultParameterSetName = "Default")]
    param (
        [parameter(Position = 0, Mandatory)]
        [Alias("ServerInstance", "SqlServer")]
        [DbaInstanceParameter]$SqlInstance,
        [PSCredential]$SqlCredential,
        [parameter(Mandatory)]
        [object]$Database,
        [Switch]$IgnoreLimit,
        [int]$RowLimit = 0,
        [Alias('Silent')]
        [switch]$EnableException
    )

    try {
        $server = Connect-SqlInstance -SqlInstance $SqlInstance -SqlCredential $SqlCredential
    } catch {
        Stop-Function -Message "Error occured while establishing connection to $instance" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue
        return
    }

    if (-not $server.databases[$Database]) {
        Stop-Function -Message "$Database does not exist"
        return
    }

    if ('Normal' -notin ($server.databases[$Database].Status -split ',')) {
        Stop-Function -Message "$Database is not in a normal State, command will not run."
        return
    }

    if ($RowLimit -gt 0) {
        Write-Message -Message "Limiting results to $RowLimit rows" -Level Verbose
        $RowLimitSql = " TOP $RowLimit "
        $IgnoreLimit = $true
    } else {
        $RowLimitSql = ""
    }


    if ($IgnoreLimit) {
        Write-Message -Level Verbose -Message "Please be aware that ignoring the recommended limits may impact on the performance of the SQL Server database and the calling system"
    } else {
        #Warn if more than 0.5GB of live log. Dodgy conversion as SMO returns the value in an unhelpful format :(
        $SqlSizeCheck = "select
                                sum(FileProperty(sf.name,'spaceused')*8/1024) as 'SizeMb'
                                from sys.sysfiles sf
                                where CONVERT(INT,sf.status & 0x40) / 64=1"

        $TransLogSize = $server.Query($SqlSizeCheck, $Database)
        if ($TransLogSize.SizeMb -ge 500) {
            Stop-Function -Message "$Database has more than 0.5 Gb of live log data, returning this may have an impact on the database and the calling system. If you wish to proceed please rerun with the -IgnoreLimit switch"
            return
        }
    }

    $sql = "select $RowLimitSql * from fn_dblog(NULL,NULL)"
    Write-Message -Level Debug -Message $sql
    Write-Message -Level Verbose -Message "Starting Log retrieval"
    $server.Query($sql, $Database)

}