PSSDIAG Files

 ===============Confirm-FileAttributes.ps1======================

## Copyright (c) Microsoft Corporation.

## Licensed under the MIT license.

[CmdletBinding()]
param (
    [Parameter(Mandatory=$false)]
    [bool] $debug_on = $false
)

function Confirm-FileAttributes
{
<#
    .SYNOPSIS
        Checks the file attributes against the expected attributes in $expectedFileAttributes array.
    .DESCRIPTION
        Goal is to make sure that non-Powershell scripts were not inadvertently changed.
        Currently checks for changes to file size and hash.
        Will return $false if any attribute mismatch is found.
    .EXAMPLE
        $ret = Confirm-FileAttributes
#>

    if ($debug_on -eq $true)
    {
        $DebugPreference = "Continue"
    }

    


    Write-Host "Validating attributes for non-Powershell script files"

# TODO: deal with ManualStart, ManualStop and pssdiag_xevent.sql

    $validAttributes = $true #this will be set to $false if any mismatch is found, then returned to caller

    $expectedFileAttributes = @(
         [PSCustomObject]@{Algorithm = "SHA512"; Hash = "6AFC48EB276028FFC902B7856C19CA0C08ABB912E1EF9AAD81018E04D24DBDBD958E03ED3B588786332F5DFE239DFA237030372B204CBF60650B051EB277970C"; FileName = ".\AlwaysOnDiagScript.sql"; FileSize = 19874}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "C0D633F8AA0C7FAE10AB0E596DD710E2CBC673A4BFE93F124B14002E8F65F116DCDCC9CB94EA7CFCF7DBABC071947382DED4592C535FE6B9C00FC34A1D091599"; FileName = ".\AlwaysOnGetClusterLogs.cmd"; FileSize = 138}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "55B8B497973F9C0980C696A0599ECAF3401C4A02FBEBFDC78608CA3354AE01E1EA03508FB558AA4548EA74988C1BA9E5DFAE310F6D60A23B38D39B310A9A84A6"; FileName = ".\AutoUserDump.bat"; FileSize = 2829}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "41938EE0E0ADE87E0D26F88C28F8A70CC54D0AE8CA21657AD5F72918E364F4C3972F1C6C86267A79D39C2D418BF89A60AE2EA2EF9998084DFEA85F9DC8D61478"; FileName = ".\build.cmd"; FileSize = 609}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "4E2E0C0018B1AE4E6402D5D985B71E03E8AECBB9DA3145E63758343AEAC234E3D4988739CCE1AC034DDA7CE77482B27FB5C2A7A4E266E9C283F90593A1B562A2"; FileName = ".\ChangeDataCapture.sql"; FileSize = 4672}
		,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "72B955257DD659BC09EDF3621F90BA2731BE817F02972F2AFBDE0BB374AFA43FA582C72B7A6562A2C4950F435FCD7019D5DC354449CD4667F33D55763007694F"; FileName = ".\Change_Tracking.sql"; FileSize = 5112}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "BF6CF04DB43D9C41E34C12A81DFB6DE7D9187BA2EC89EF0AC5AE8BB842CD00EC1FBDCB7870249AE5F2A9950FE0FD85A3BE6275856504F49BF578A9693E49063C"; FileName = ".\CMemthread.sql"; FileSize = 461}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "75B822DAAED573CEC075EC39AF882FED3340B8809235AAB5DBFB5673008474DA8EF2B57ECC5F563668F8F526E24B22555B33F0D5167F5B83D7E16D41271F307A"; FileName = ".\collecterrorlog.cmd"; FileSize = 263}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "BC7120451387E14695D1E6AAC25783C2C7299A131672D0BB28CB6971DEE53DF23D82E6A5D2E63D20DCC0EEE8BB26A8D3E93B2EFF7E400641FA959BE829B9FFFD"; FileName = ".\collecterrorlog.sql"; FileSize = 361}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "F5AB1122719AC332E9359A3A4884BF6FA922383236858A0884EF6D9CEBD80ED2151AF7E95A9C4B6019C2A55A0A987037E16FD0443E7E487385502863C3A0A0E8"; FileName = ".\ColumnStore.sql"; FileSize = 4970}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "AEBBAB953A7187281EBCAE85FC38F3FCDBA600220FDFC3A29348626B394D2FC4E938065F1EF3375EB91A962F31572704E72814D76DB8264C35FFF01D55049BA2"; FileName = ".\ConnectivityTest.bat"; FileSize = 3746}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "7E794E2322F58933E8769FB680F3B232B3287EFAB71FF2D709273704BD578866E5A640FEBB935B9170570136C49905B52CD7BB7D4986D92D280B40B7F2F27C64"; FileName = ".\DefineCommonVars.cmd"; FileSize = 4321}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "99F853F56BD0253176F12678D25D1F564E3BD5C8E1432E669E3AF6126DD3169CAF2ECB6D3B03B08E65934B8BDD694B6C9708076FDFE003C293BA7346C8D58C3E"; FileName = ".\DefineSQLInstanceSetupPaths.cmd"; FileSize = 2410}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "FC627ABB404C01F9E1EF8A533F8D607B1FFF22D94E4E89D2A124B396F572724B9004D1B3B52240E6D2B1917FD9A0519189E88688BC72575462143975AC6134FF"; FileName = ".\errorlogs.js"; FileSize = 7731}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "EFC59387B7510BD7C79870C94A7DCB25D11FB04421D07B7C570ED809C85ADD64E0DC4A1FD3D6317106A837DBCAC3B1A15362D7F90AF45173E0D852C3F2D05350"; FileName = ".\FTS_Collector.sql"; FileSize = 13855}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "F539B33196C4BC259E2F9983D31F05DEAC93BC23794197A9580F9BC9E15F0274E5CC4673E36E04495ABF3A59CF78792489DE1537AEFB738DF179B745B8B43555"; FileName = ".\fts_info.sql"; FileSize = 5846}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "216681E0F3541DAD01652B4D319B3C6619EAC8684F33694F52DC3DC509B0D80D7E1B7F121642A0C275D60F1581B00089D0AD01A713745EEC3F0FFAA1A38EB3D4"; FileName = ".\GetAllSQLInstancePIDS.cmd"; FileSize = 734}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "96A70F624E21EAA4118AC10EE2D0168F6F4369886B218571237EFF9063A1C1FAAB749B4FDD57DFAD411262981C23540EE7CCD2906ED44C2E4F1664F282F4D193"; FileName = ".\GetFileVer.CMD"; FileSize = 1317}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "1A3BD5E09DAFCAD9F70BB0128007BD0BAF5CDD6916DA7A4F9815F8D92674D9EFA4252654B20AEE5CFAC3BAEABFB80DD03AC39FD4B11975B2D81174D289DA27DD"; FileName = ".\GetRegValue.CMD"; FileSize = 1117}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "7D890D6E26FD93676CDC7C5525D0D2F35BA1FEB8A0C2344C157922668798734907C5EC046B40F7DB1440E90E26406036B2AA44582F17B35B1789E122F323C30B"; FileName = ".\GetSQLInstancePID.CMD"; FileSize = 2118}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "9E6A3A9EDBBCDE9DA84D7635396977B6FEF6512A51A9A396004A6EFF67CEF4C99EE61CBD9CCE1776B55CD78442F1CA3300A99E170CBF3F99410364B45932DF9E"; FileName = ".\get_dbccloginfo.sql"; FileSize = 494}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "45B6F82A7993AABE6C1CB1ACE51F21EEA68CFB624F101F3E0604E41E20FCAAE48D50FC18EF165CC46F8C6450E6182C9101294550527DD5679A905E5D1E42E991"; FileName = ".\get_dbmirroringinfo.sql"; FileSize = 5138}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "FF0BE2ACCF32E5557C70774E480B48266355D928CDE07E1A265459D1FB660C86531AE354F5379263F99EDEBD4F4C1D37D0BED7919F3D92D19B65344432A9BBC7"; FileName = ".\get_dbmirroringinfo.vbs"; FileSize = 2556}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "A81FF0564F8D79674C36461D86E4338C0C28C7995CDEEE970107DD8FB3915ABC68380A1BCB01EFD8A839F26BCD271880118F6E0447972D37834DB0EB4C690CC8"; FileName = ".\get_tasklist.cmd"; FileSize = 373}
		,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "46D03FC5E13114C1DA826DB266EA5A5219E15510709EBEC416D9F30858325FE0F5E6AD94247431A34E8AAD09B62B15919FB3058F2B68D868703CF959ADC707DA"; FileName = ".\HighCPU_perfstats.sql"; FileSize = 5334}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "BA125F5D7F76C0B6D70A8B198532EE9DE6B179DAFECBC2D5AFE256DA569900CC483381EB1D717817FB7AB5AEF6DD8C30FD8A73819BA3B870C5838FDE37E9659E"; FileName = ".\In_Memory_OLTP.sql"; FileSize = 2273}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "804B3E27309C23E9530BF475DBD8DA52D1DFA334D7A118DE66B77E4E8182BA8FAC1F938C2FDC1D4CB11F73295354ADEECC33075BF7B87F2C505C03C1BB8E86FB"; FileName = ".\linked_server_config.sql"; FileSize = 3638}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "78CDEFB86A57A39A551DD8D7D38028AF6B8073C4175731AD014F9E90F136C5E0AFD0074C19CA4048492EFF5297867FF663531C90C3B012D0078561BCFD5F4177"; FileName = ".\ManualStart.cmd"; FileSize = 4015}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "7698E15AC47A1735C1C6D630CC4A451F13F80D3B3F578BA0802CDAD43DB224D78E9498B28B40FB929B12FCEB7129560565FC4AADBEE888863E268BC73B378AD0"; FileName = ".\ManualStop.cmd"; FileSize = 1727}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "CD1564EB4C7A1A404C2C6AD67417502257584F91BB57603E0A8B9940E3090252F9C8723454CB052803D911C9B084A6058993B2032BE9E9DCE906072C329743EA"; FileName = ".\ManualUserDump.bat"; FileSize = 1220}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "E5767D07D745ABEE75D3642C95EE3D89B56EFB1537DCC3B700FE16156E63614DCB9DF81DFB0028670488EFD362B1E66E13812E85F2E4E6973D0FD2CF95A823AB"; FileName = ".\MiscPssdiagInfo.sql"; FileSize = 14964}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "EB35C41EB301CED435EDEAD31CC6E23EB8B04EB7BDFC1A805CFA835B3D194DEF8FD7F111AF971122937FAF0AC1EF42B2CFA4CBC79EFAE4CB0438C91396F14F58"; FileName = ".\MSDiagProcs.sql"; FileSize = 191478}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "8366A86E01D3430AF1DF9E51A852324A64D5D63DAD3E68EF6AF240E29FAA8A397CF06390A05AB4CFF97FF3B65A825FAFA11381D2D10045AAE344FE1BEFE90A33"; FileName = ".\My Collector Script.sql"; FileSize = 47}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "0DA7B5F39B23196B16913AB660099B82F384E1C1757FF524894A37867010965E7E28ED87D87DAB00632482D12417DB9D21F1B52B4A8D8750192CECF39E57A448"; FileName = ".\OutputActiveTimeBias.CMD"; FileSize = 719}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "5CF137CA8F4C34DAD59D1C21D41F1C13D4AA933B7AB593272D4C785EE3F087689BEB9FBA0D163DD21AF2F4C68C574B5C3D33979ACE92E9D747503A1490671A9A"; FileName = ".\PolyBase.sql"; FileSize = 1959}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "782D8FFD9E46AAEA7ED70A608A2BAD37E1FAB7DDF6A8FF6423A365B69F0CC2DEBA753EF1E0C897412B6C115DC23A472320AF1465AFE702E1ED91C8123CA1E36C"; FileName = ".\PowerPlan.VBS"; FileSize = 650}
		,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "2E209F7D1ECA92396A620FB0B92DED937EBFF1F59A017B47A27672A151C4F32E8189CF1AB66E082946219AAEA091B6EF0D712C1D6080A19006702273D60957D2"; FileName = ".\Profiler Traces.sql"; FileSize = 2743}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "825C5281C6D1654A2E557814F751E7A50F6F525E9CF3529E4F1EDBE0FB68E42DC80517CD297CDE658540A6383EE54A2A5239ADFA994175274F8D96861C9F4DDB"; FileName = ".\Query Store.sql"; FileSize = 2589}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "6707EEE5E26A79C22AB0387B900EF4014599D33244E1E19CCB85206D58B26A659BE8E7585BCCC30FC7CB5E92C1348A30E94A8EC72DF04AEEDDB5E641DCF2DCE0"; FileName = ".\QueryNeverCompletes_perfstats.sql"; FileSize = 6854}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "4B7745C8EEB9BFE49AD89B481591F3FAA1FAC8B1D6909A8C43C091CED79F609E57274284CB23FADB14447979AC11A0427F379E1D509D7CA33BADF0F9D42F52CB"; FileName = ".\Repl_Metadata_Collector.sql"; FileSize = 50941}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "902A5292AF20AD580AD196828C7EAA0E97E35308E919A4E1999F92C6486A09147690FF493752316613EDE36E41ACE5D743D9D52E69C4D678FEE1D6E03C11A4B9"; FileName = ".\rtrim.vbs"; FileSize = 423}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "15C8D2F26416FFA1C0A913A2E22A4448CB1E777D3EA7558F4E58C83C7462A2069BEA6AE687C741D89059DBB98C52FA30E900324EC9D98261A13E1DFE083A19C7"; FileName = ".\run_in_dir.cmd"; FileSize = 49}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "0E5EDDED466F2AE758E7B1CE1A9C66952F29251BB3B980145688A969B76711AFAE60528E2B9942E43BA268A5D50BCADD88FBE354184C47F6D456FDAE50DFB9A0"; FileName = ".\SetSqlEnvVariables.cmd"; FileSize = 1008}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "AE3BFFB70FAC3DCCFA61192DF515635832D819545B84F915AF63378C33422E8FCAC23BEA128B91907F420E46524321866904C24CCA6A352B85E9519CB2A35EDD"; FileName = ".\SetupVars.bat"; FileSize = 1126}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "586CD47C9668C7FF3412D3FD8F5AC56F2E7AC386A53404E4002DD3CD7C1B4B0354500C4973A1C8296E3C932DF62D6641B52EA1C13E4674BB6299FD7B390A642F"; FileName = ".\SQL Server Perf Stats Snapshot.sql"; FileSize = 34914}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "7D6A02F371BC1F4043998EDFF1E252B74DDA1B7435A649E74CFD2E41C1BFA5630508D06FD68BC432008137A82DCA0DF0B45D2127C3A66736DA5E4C4CDD0463C8"; FileName = ".\SQL Server Perf Stats.sql"; FileSize = 71410}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "46BD5A2066A43B03816FAE181C9ECB8653E24C6542F391A3FF74E503C5A0D8485EC0EB8CBAE941D8FF028B7F5DB7124325547F94EDCE566E9486E36149DD1924"; FileName = ".\SQL_Server_Mem_Stats.sql"; FileSize = 16909}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "5CB4E3F3B3FD99E90603D84AD8C18C6A06E663210C2FD6FB42718431CACB7F84E5DFA3B172C1E065F70504B415D4EE9AAB2CFE0333A9CD28381D73E39C77A781"; FileName = ".\SSB_pssdiag.sql"; FileSize = 10531}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "D5DB0DC73327FAA34A67DFC7EFFED7A740994AFACE122DEAC2F3905F52747FFF1D1DB83518EA3F7DC937A045A6E5EA5DC947C6E00BE0591640371B88B5ED7DA7"; FileName = ".\StartFromPSSDiag.bat"; FileSize = 1607}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "93C312346BD00C02B7241813397C9B99F9400BB2ADF31077E5B4BA1FF7ABAE656490AF3D049B3F2D621D93C972157F860E5C2BCF4D7EC4A52904B4EACD7FF6D3"; FileName = ".\StartPSS.bat"; FileSize = 310}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "ABA1A57AB4E5FAA9D3D783C29AFBB74E874A58E50A2889661F7CA57EACC9FB4A9B4D7182B069A4DBE815E951370E7BAC78FDB2A2D0D601458A2A2C7B970A2E06"; FileName = ".\StretchDB.sql"; FileSize = 29}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "A5AB03D93D7FB256C2DC08B9E5C46CF7D71C403F3074564A66E37DF46F75396BE69593DA2ECA2480073608C5FF215EDE36C6571155BD7EF6B2282C7888EF9401"; FileName = ".\TempDB_and_Tran_Analysis.sql"; FileSize = 9054}
        ,[PSCustomObject]@{Algorithm = "SHA512"; Hash = "81EB149D0182A4E7FD62007B69A3658E1126F9723DB386BD358CA7CAC695431AFB2684D4A40D7F7A4E07F2FB727B4F904507CC6E0A6F03B5BBE9323AB0F60681"; FileName = ".\TopCPUQueryShowPlanXML.bat"; FileSize = 883}


)

    # global array to keep a System.IO.FileStream object for each of the non-Powershell files
    # files are opened with Read sharing before being hashed
    # files are kept opened until SQL LogScout terminates preventing changes to them
    #[System.Collections.ArrayList]$Global:hashedFiles = [System.Collections.ArrayList]::new()
    $Global:hashedFiles = New-Object -TypeName  System.Collections.ArrayList

    
    foreach ($efa in $expectedFileAttributes) 
    {
        
        try
        {
            Write-Debug ("Attempting to open file with read sharing: " + $efa.FileName)
            
            $cur_file = $efa.FileName

            if ((Test-Path -Path $cur_file) -eq $true)
            {
                $cur_file = Convert-Path -Path $cur_file
                
                $fstream = [System.IO.File]::Open($cur_file, 
                [System.IO.FileMode]::Open, 
                [System.IO.FileAccess]::Read, 
                [System.IO.FileShare]::Read)

                
                Write-Debug ("FileName opened = " + $fstream.Name)
            }
            else 
            {
                Write-Debug ("File " + $efa.FileName + " not present")
                Continue 
            }
            

            # open the file with read sharing and add to array
            [void]$Global:hashedFiles.Add($fstream)
            

        } catch {
            $validAttributes = $false
            Write-Host ("Error opening file with read sharing: " + $efa.FileName ) -ForegroundColor Red
            Write-Host $_ -ForegroundColor Red

            return $validAttributes
        }

        Write-Debug  ("Validating attributes for file " + $efa.FileName)

        try {
            $file = Get-ChildItem -Path $efa.FileName

            if ($null -eq $file){
                throw "`$file is `$null"
            }
        }
        catch {
            $validAttributes = $false
            Write-Host "" -ForegroundColor Red
            Write-Host ("Could not get properties from file " + $efa.FileName) -ForegroundColor Red
            Write-Host $_ -ForegroundColor Red
            Write-Host "" -ForegroundColor Red
            return $validAttributes
        }

        try {
            $fileHash = Get-FileHash -Algorithm $efa.Algorithm -Path $efa.FileName

            if ($null -eq $fileHash){
                throw "`$fileHash is `$null"
            }
    
        }
        catch {
            $validAttributes = $false
            Write-Host "" -ForegroundColor Red
            Write-Host ("Could not get hash from file " + $efa.FileName) -ForegroundColor Red
            Write-Host $_ -ForegroundColor Red
            Write-Host "" -ForegroundColor Red
            return $validAttributes
        }

        if(($file.Length -ne $efa.FileSize) -or ($fileHash.Hash -ne $efa.Hash))
        {
            $validAttributes = $false
            Write-Host "" -ForegroundColor Red
            Write-Host ("Attribute mismatch for file: " + $efa.FileName) -ForegroundColor Red
            Write-Host "" -ForegroundColor Red
            Write-Host ("Expected File Size: " + $efa.FileSize) -ForegroundColor Red
            Write-Host ("Actual   File Size: " + $file.Length) -ForegroundColor Red
            Write-Host "" -ForegroundColor Red
            Write-Host ("Expected Hash: `n" + $efa.Hash) -ForegroundColor Red
            Write-Host ("Actual   Hash: `n" + $fileHash.Hash) -ForegroundColor Red
            Write-Host "" -ForegroundColor Red
            
        } else {
            Write-Debug ("Actual File Size matches Expected File Size: " + $efa.FileSize + " bytes")
            Write-Debug ("Actual Hash matches Expected Hash (" + $efa.Algorithm + "): " + $efa.Hash )
        }

        if (-not($validAttributes)){
            # we found a file with mismatching attributes, therefore backout indicating failure
            return $validAttributes
        }

        
        $fstream.Close()
        $fstream.Dispose()


    } #foreach

    return $validAttributes
}

# use to calculate filehash values when files are changed

function Get-FileAttributes([string] $file_name = ""){
<#
    .SYNOPSIS
        Display string for $expectedFileAttributes.
    .DESCRIPTION
        This is to be used only when some script is changed and we need to refresh the file attributes in Confirm-FileAttributes.ps1
    .EXAMPLE
        . .\Confirm-FileAttributes.ps1
        Get-FileAttributes
#>

    [int]$fileCount = 0
    [System.Text.StringBuilder]$sb = New-Object -TypeName System.Text.StringBuilder

    [void]$sb.AppendLine("`$expectedFileAttributes = @(")
    
    foreach($file in (Get-ChildItem -Path . -File -Filter $file_name)){
        
        # Powershell files are signed, therefore no need to hash-compare them
        # "Get-ChildItem -Exclude *.ps1 -File" yields zero results, therefore we skip .PS1 files with the following IF
        if (".ps1" -ne $file.Extension){
            
            $fileCount++

            # append TAB+space for first file (identation)
            # append TAB+comma for 2nd file onwards
            if($fileCount -gt 1){
                [void]$sb.Append("`t,")
            } else {
                [void]$sb.Append("`t ")
            }
    
            $fileHash = Get-FileHash -Algorithm SHA512 -Path $file.FullName

            $algorithm = $fileHash.Algorithm
            $hash = $fileHash.Hash
            $fileName = ".\" + $file.Name
            $fileSize = [string]$file.Length

            [void]$sb.AppendLine("[PSCustomObject]@{Algorithm = `"$algorithm`"; Hash = `"$hash`"; FileName = `"$fileName`"; FileSize = $fileSize}")

        }

    }

    [void]$sb.AppendLine(")")
    
    Write-Host $sb.ToString()
}
=================================Multicopy.ps1========================================

param(
  [Parameter(Position=0)]
  [string]$sourcePath,
  [Parameter(Position=1)]
  [string]$destinationPath,
  [Parameter(Position=2)]
  [string]$serverName
)

if ($serverName -Like '*\*')
{
  $serverName = $serverName -replace"\\","_"
}

Get-ChildItem $sourcePath -FILE | ForEach-Object { 

		If ([String]::IsNullOrEmpty($serverName))
		{
			$newFileName = $_.Name
		}
		else
		{
			$newfileName = $serverName + "_" + $_.Name
		}

		$newfileName = Join-path $destinationPath $newfileName

	Try { 
				Copy-Item -Path $_.FullName -Destination $newFileName -ErrorAction Stop
		}		
	Catch {
				Write-Output $_.Exception.Message 
		}
	}

=================================SetSqlEnvVariables.cmd==================================

set MACHINENAME=%1
set INSTANCENAME=%2
set SSVER=%3

echo MACHINENAME: %MACHINENAME%
echo INSTANCENAME: %INSTANCENAME%
echo SSVER: %SSVER%

set SQLGLOBAL_VERSION=130
if "%SSVER%"=="10.50" (
 set SQLGLOBAL_VERSION=110
 ) else (
 set SQLGLOBAL_VERSION=%SSVER%0
)

echo SQLGLOBAL_VERSION: %SQLGLOBAL_VERSION%


@echo off
rem getting tools root dir
set KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\%SQLGLOBAL_VERSION%
set VALUE_NAME=VerSpecificRootDir
 
FOR /F "skip=2 tokens=1,2*" %%A IN ('REG QUERY "%KEY_NAME%" /v "%VALUE_NAME%" 2^>nul') DO (
    set ValueName=%%A
    set ValueType=%%B
    set ValueValue=%%C
)

if defined ValueName (
    echo Value Name = %ValueName%
    echo Value Type = %ValueType%
    echo Value Value = %ValueValue%
) else (
    @echo "%KEY_NAME%"\"%VALUE_NAME%" not found.
)


set SQLTOOLSROOT=%ValueValue%
echo SQLTOOLSROOT:%SQLTOOLSROOT%

set SQLDUMPERPATH=%SQLTOOLSROOT%shared

echo SQLDUMPERPATH: %SQLDUMPERPATH%

=====================================perfmon_translate.ps1===============================

#Check if the language is not English
if(((Get-WinUserLanguageList).LanguageTag | Select -First 1) -notlike "en*"){

    Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Executing:Perfmon Counters localization. Please wait..."
    #Get all Local existing counters paths in array for future check
    $counterexistingpaths = @(Get-Counter -ListSet *).Paths
    $countertranslatedcounters = 1
    #Get performance counters names and ID's in english and local languages to hash table
    $pc_en_names = [Microsoft.Win32.Registry]::PerformanceData.GetValue("Counter 009")
    $pc_en_hash = @{}
    $duplicated_en_names_pc_hash = @{} 
    foreach ($item in $pc_en_names) {
        $pc_id_indexnumber = $pc_en_names.IndexOf($item)
        $pc_name_indexnumber = $pc_id_indexnumber+1
        $pv_name_to_add = $pc_en_names[$pc_name_indexnumber]
        if($pc_id_indexnumber% 2 -eq 0 ) {
            #check IF Hash Key already exist
            if(-not ([string]::IsNullOrEmpty($pv_name_to_add)) -and $pc_en_hash.ContainsKey($pv_name_to_add)) {
                $existing_name = $pc_en_hash.$pv_name_to_add
                $duplicated_en_names_pc_hash["$existing_name"] = $pv_name_to_add
                $duplicated_en_names_pc_hash["$item"] = $pv_name_to_add
            }
            $pc_en_hash["$pv_name_to_add"] = $item
        }

    }



    $pc_local_names = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage' -Name 'counter').Counter
    $pc_local_hash = @{}
    foreach ($item in $pc_local_names) {
        $pc_id_indexnumber = $pc_local_names.IndexOf($item)
        $pc_name_indexnumber = $pc_id_indexnumber+1
        if($pc_id_indexnumber% 2 -eq 0 ) {
            #Write-Host "$($pc_id_indexnumber) is even and the name is $($pc_en_names[$pc_name_indexnumber])"
            $pc_local_hash["$item"] = $pc_local_names[$pc_name_indexnumber]
        }

    }


    #get pssdiag xml with performance counters info
    $pathxml = "pssdiag.xml"
    $xml = [xml](Get-Content $pathxml)



    #Get all Perfmon Objects
    $obnodes = $xml.dsConfig.Collection.Machines.Machine.MachineCollectors.PerfmonCollector.PerfmonCounters.SelectNodes("//PerfmonObject[@name]")



    #Translate each Object
    foreach ($obnode in $obnodes) {
        #find performance object in XML
        $xmlPerfObejct = $xml.dsConfig.Collection.Machines.Machine.MachineCollectors.PerfmonCollector.PerfmonCounters.SelectSingleNode("//PerfmonObject[@name='" + $obnode.name + "']")

        #split the string before and after the (), add the first parenteses after split
        IF($xmlPerfObejct.name.Contains("(")) {
            $afixo = $xmlPerfObejct.name.Split('(')
            $afixo[1] = '(' + $afixo[1]
        }ELSE{
            $afixo[0] = $xmlPerfObejct.name
            $afixo[1] = ""
        }


        #Remove the \ at the beginning of the performance object name and make sure exact match name search
        $searchOBname= $afixo[0].substring(1)
        #Get the Object ID based on the line before of the name match
        $LocalPerfObID = $pc_en_hash.$searchOBname
    
        IF (-not ([string]::IsNullOrEmpty($LocalPerfObID))){
            $pob_local_name = $pc_local_hash."$LocalPerfObID"


            IF (-not ([string]::IsNullOrEmpty($pob_local_name))){
            $pob_translated_name = "\" + $pob_local_name + $afixo[1]

            #change the xml of the counter
            $xmlPerfObejct.name = $pob_translated_name
            }
        }



        #Get Perfmon Counters per perfmonobject
        $pcnodes = $xml.dsConfig.Collection.Machines.Machine.MachineCollectors.PerfmonCollector.PerfmonCounters.SelectNodes("//PerfmonObject[@name='" + $obnode.name + "']/PerfmonCounter[@name]")

        foreach ($pcnode in $pcnodes) {
            #find performance object in XML
            $xmlPerfCounter = $xml.dsConfig.Collection.Machines.Machine.MachineCollectors.PerfmonCollector.PerfmonCounters.SelectSingleNode("//PerfmonObject[@name='" + $obnode.name + "']/PerfmonCounter[@name='" + $pcnode.name + "']")

            IF ($xmlPerfCounter.name -ne "\(*)"){

                #Remove the \ at the beginning of the performance object name and make sure exact match name search
                $searchpcname= $xmlPerfCounter.name.substring(1)
                #Get the Object ID based on the line before of the name match
                $LocalPerfCounterID = $pc_en_hash.$searchpcname
    
                IF (-not ([string]::IsNullOrEmpty($LocalPerfCounterID))){
                

                    $pc_local_name = $pc_local_hash."$LocalPerfCounterID"

                    IF (-not ([string]::IsNullOrEmpty($pc_local_name))){

                        #Confirm correct name translation per object+countername
                        IF ($duplicated_en_names_pc_hash.ContainsKey($LocalPerfCounterID)){

                            $pc_duplicated_id = $duplicated_en_names_pc_hash.Keys.Where({$duplicated_en_names_pc_hash[$_] -eq $searchpcname})

                            foreach ($dup_node in $pc_duplicated_id){
                                $dup_node_name = $pc_local_hash."$dup_node"
                                $confirm_counter = $pob_translated_name + "\" + $dup_node_name

                                IF ($counterexistingpaths.Contains($confirm_counter)){
                                    $pc_local_name = $dup_node_name
                                }
                            }
                        }

                        $pc_translated_name = "\" + $pc_local_name


                        #change the xml of the counter

                        $xmlPerfCounter.name = $pc_translated_name
                        $countertranslatedcounters = $countertranslatedcounters +1                
                    }
                }
            }
        }


    }




    #save the XML file with the changes
    $xmlsavelocation = (Get-Location).Path + "\" + $pathxml
    $xml.Save($xmlsavelocation)
    Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") $countertranslatedcounters Perfmon counters in local Language saved in pssdiag.xml"}

====================================pssdiag.ps1======================
param
(
    [Parameter(ParameterSetName = 'ServiceRelated',Mandatory=$true)]
    [Parameter(Position = 0)]
    [string] $ServiceState = "",

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $help,

    [Parameter(ParameterSetName = 'Config',HelpMessage='/I xml_config_file',Mandatory=$false)]
    [string] $I = "pssdiag.xml",

    [Parameter(ParameterSetName = 'Config',HelpMessage='/O output_path',Mandatory=$false)]
    [string] $O = "output",

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $P = "",

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $N = "1",

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $M = [string]::Empty,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $Q ,
    
    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $C = "0",

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $G,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $R,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $U,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $A = [string]::Empty,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $L,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $X,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $B = [string]::Empty,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $E = [string]::Empty,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [string] $T = [string]::Empty,

    [Parameter(ParameterSetName = 'Config',Mandatory=$false)]
    [switch] $DebugOn


)


. ./Confirm-FileAttributes.ps1


function Check-ElevatedAccess
{
    try 
    {
	
        #check for administrator rights
        if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
        {
            Write-Warning "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Elevated privilege (run as Admininstrator) is required to run PSSDIAG. Exiting..."
            exit
        }
        
    }

    catch 
    {
        Write-Error "Error occured in $($MyInvocation.MyCommand), $($PSItem.Exception.Message ), line number: $($PSItem.InvocationInfo.ScriptLineNumber)" 
		exit
    }
    

}


function FindSQLDiag ()
{

    try
    {
				
        [bool]$is64bit = $false

        [xml]$xmlDocument = Get-Content -Path .\pssdiag.xml
        [string]$sqlver = $xmlDocument.dsConfig.Collection.Machines.Machine.Instances.Instance.ssver
		
		#first find out if their registry is messed up
		ValidateCurrentVersion -ssver $sqlver

		[string[]] $valid_versions = "10", "10.50", "11", "12", "13", "14", "15", "16"

		while ($sqlver -notin $valid_versions)
		{
			Write-Warning "An invalid version is specified for SQL Server (ssver = '$sqlver') in the pssdiag.xml file. This prevents selecting correct SQLDiag.exe path."
			$sqlver = Read-Host "Please enter the 2-digit version of your SQL Server ($valid_versions) to help locate SQLDiag.exe"

		}

        if ($sqlver -eq "10.50")
        {
              $sqlver = "10"
        }

        [string]$plat = $xmlDocument.dsConfig.DiagMgrInfo.IntendedPlatform


        [string] $x86Env = [Environment]::GetEnvironmentVariable( "CommonProgramFiles(x86)");


         #[System.Environment]::Is64BitOperatingSystem

        if ($x86Env -ne $null)
        {
            $is64bit = $true
        }

        $toolsRegStr = ("HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\" + $sqlver+"0\Tools\ClientSetup")
		
	
	
        # for higher versions of PS use: [string]$toolsBinFolder = Get-ItemPropertyValue -Path $toolsRegStr -Name Path
        [string]$toolsBinFolder = (Get-ItemProperty -Path $toolsRegStr -Name Path).Path


		#strip "(x86)" in case Powershell goes to HKLM\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\ under the covers, which it does
		
		$toolsBinFolderx64 = $toolsBinFolder.Replace("Program Files (x86)", "Program Files")

		
		$sqldiagPath = ($toolsBinFolder + "sqldiag.exe")
        $sqldiagPathx64 = ($toolsBinFolderx64 + "sqldiag.exe")
		
		
	
        if ((Test-Path -Path $sqldiagPathx64))
        {
			return $sqldiagPathx64
		}
		
		else
		{
			#path was not valid so checking second path
			
			if ($sqldiagPath -ne $sqldiagPathx64)
			{
				if ((Test-Path -Path $sqldiagPath))
				{
					return $sqldiagPath
				}
			}
			
			Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Unable to find 'sqldiag.exe' version: $($sqlver)0 on this machine.  Data collection will fail"
			return "Path_Error_"
        }
        
		
    }
    catch 
    {
        Write-Error "Error occured in finding SQLDiag.exe: $($PSItem.Exception.Message)  line number: $($PSItem.InvocationInfo.ScriptLineNumber)" 
		return "Path_Error_"
    }

}

function ValidateCurrentVersion ([string]$ssver)
{
	[string[]] $intermediateNames = @()
	[string[]] $currentVersionReg = @()

	$regInstNames = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" 
	
	$instNames = Get-Item $regInstNames | Select-Object -ExpandProperty Property 

	# add the discovered values in an array
	foreach ($inst in $instNames)
	{
		# for higher versions of Powershell use: $intermediateNames+= ( Get-ItemPropertyValue -Path $regInstNames -Name $inst)
        $intermediateNames+= ( Get-ItemProperty -Path $regInstNames -Name $inst).$inst
	}


	[int] $nonMatchCounter = 0

	foreach($name in $intermediateNames)
	{

		$regRoot = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\" + $name + "\MSSQLServer\CurrentVersion"
		
        # for higher versions of PS use: $verString = Get-ItemPropertyValue -Path $regRoot -Name CurrentVersion
        $verString = (Get-ItemProperty -Path $regRoot -Name CurrentVersion).CurrentVersion

		$currentVersionReg+= ($regRoot + "=>" + $verString)

		# get the major version value from the reg entry
		$majVersion = $verString.Substring(0, $verString.IndexOf("."))

        # for version 2008R2 number is 10.50 and we had to remove .50
        #IndexOf function returns -1 for SQLs without minor version number (only 2008R2 has this number, which is 50. All others are zero). 

        if ($ssver.IndexOf(".") -eq -1) 
        {
            $tempssver =  $ssver

        }
        else 
        {
            $tempssver = $ssver.Substring(0, $ssver.IndexOf("."))
        }



        if ($majVersion -ne $tempssver)
		{
			$nonMatchCounter++
		}

	}

    if ($nonMatchCounter -eq $intermediateNames.Count)
	{
		Write-Warning "Collection may fail. No instance was found for the version of SQL Server configured in pssdiag.xml (ssver='$ssver')."
        Write-Warning "Examine these reg keys to see if the one or more versions is different from expected version $ssver (first 2 digits in NN.n.nnnn):`n"
        foreach ($entry in $currentVersionReg)
		{
			Write-Warning $entry 
		}
	}

}



function PrintHelp
{
	 Write-Host " [-I cfgfile] = sets the configuration file, typically either pssdiag.xml or sqldiag.xml.`n"`
        "[-O outputpath] = sets the output folder.  Defaults to startupfolder\SQLDIAG (if the folder does not exist, the collector will attempt to create it) `n" `
        "[-N #] = output folder management at startup #: 1 = overwrite (default), 2 = rename (format is OUTPUT_00001,...00002, etc.) `n" `
        "[-P supportpath] = sets the support path folder.  Defaults to startupfolder if not specified `n" `
        "[-M machine1 [machine2 machineN]|`@machinelistfile] = overrides the machines specified in the config file. When specifying more than one machine, separate each machine name with a space. "`@" specifies a machine list file `n" `
        "[-Q]  = quiet mode -- supresses prompts (e.g., password prompts) `n" `
        "[-C #] = file compression type: 0 = none (default), 1 = NTFS, 2 = CAB `n" `
        "[-G]  = generic mode -- SQL Server connectivity checks are not enforced; machine enumeration includes all servers, not just SQL Servers `n" `
        "[-R]  = registers the collector as a service `n" `
        "[-U]  = unregisters the collector as a service `n" `
        "[-A appname] = sets the application name.  If running as a service, this sets the service name `n" `
        "[-L] = continuous mode -- automatically restarts when shutdown via -X or -E `n" `
        "[-X] = snapshot mode -- takes a snapshot of all configured diagnostics and shuts down immediately `n" `
        "[-B [+]YYYYMMDD_HH:MM:SS] = specifies the date/time to begin collecting data; "+HH:MM:SS" specifies a relative time `n" `
        "[-E [+]YYYYMMDD_HH:MM:SS]  = specifies the date/time to end data collection; "+HH:MM:SS" specifies a relative time `n" `
        "[-T {tcp[,port]|np|lpc|via}] = connects to sql server using the specified protocol `n" `
        "[-Debug] = print some verbose messages for debugging where appropriate `n" `
        "[START], [STOP], [STOP_ABORT] = service commands for a registered (-R) SQLDIAG service `n" `
        ""        -ForegroundColor Green

        exit
}

function main 
{

    [bool] $debug_on = $false

    if ($DebugOn -eq $true)
    {
        $debug_on = $true
    }
	
	if (Check-ElevatedAccess -eq $true)
	{
		exit
	}
	

    $validFileAttributes = Confirm-FileAttributes $debug_on
        if (-not($validFileAttributes)){
            Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") File attribute validation FAILED. Exiting..." -ForegroundColor Red
            return
        }
        
    
    [string[]] $argument_array = @()

    if ($ServiceState -iin "stop", "start", "stop_abort")
    {
        Write-Host "ServiceState = $ServiceState"
        $argument_array += $ServiceState   
    }
    elseif (($ServiceState -iin "--?", "/?", "?", "--help", "help") -or ($help -eq $true) )
    {
        PrintHelp
    }
    else
    {
        
        # [/I cfgfile] = sets the configuration file, typically either sqldiag.ini or sqldiag.xml.  Default is sqldiag.xml
        $lv_I = "/I" + $I

        # [/O outputpath] = sets the output folder.  Defaults to startupfolder\SQLDIAG (if the folder does not exist, the collector will attempt to create it)
        #if this is a full directory path make sure to trim a final backslash because SQLDiag would fail to start the service if that exists
        if ($O.Substring($O.Length -1) -eq "`\")
        {
          $O = $O.Substring(0,$O.Length -1)
        }

        $lv_O = "/O" + $O

        
        # [/P supportpath] = sets the support path folder.   By default, /P is set to the folder where the SQLdiag executable resides. 
		# The support folder contains SQLdiag support files, such as the XML configuration file, Transact-SQL scripts, and other files that the utility uses during diagnostics collection. 
		# If you use this option to specify an alternate support files path, SQLdiag will automatically copy the support files it requires to the specified folder if they do not already exist.
        $pwd = Get-Location
        
        if ([string]::IsNullOrWhiteSpace($P) -eq $false) 
        {
          #trim a final backslash because SQLDiag would fail to start the service if that exists
          if ($P.Substring($P.Length -1) -eq "`\")
          {
            $P = $P.Substring(0,$P.Length -1)
          }

          $lv_P = "/P" + $P 
        }

        else
        {
            $lv_P = "/P" + $pwd.Path
        }
        


        # [/N #] = output folder management at startup #: 1 = overwrite (default), 2 = rename (format is OUTPUT_00001,...00002, etc.)
        $lv_N = "/N" + $N

        # [/M machine1 [machine2 machineN]|@machinelistfile] = overrides the machines specified in the config file. When specifying more than one machine, separate each machine name with a space. "@" specifies a machine list file
        if ([string]::IsNullOrWhiteSpace($M))
        {
            $lv_M = ""
        }
        else 
        {
            $lv_M = "/M" + $M    
        }


        # [/Q]  = quiet mode -- supresses prompts (e.g., password prompts)

        if ($Q -eq $false)
        {
            $lv_Q = ""
        }
        else 
        {
            $lv_Q = "/Q"
        }
        
        # [/C #] = file compression type: 0 = none (default), 1 = NTFS, 2 = CAB

        $lv_C = "/C" + $C
        
        # [/G]  = generic mode -- SQL Server connectivity checks are not enforced; machine enumeration includes all servers, not just SQL Servers
        
        if ($G -eq $false)
        {
            $lv_G = ""
        }
        else 
        {
            $lv_G = "/G"
        }
        
        # [/R]  = registers the collector as a service

        if ($R -eq $false)
        {
            $lv_R = ""
        }
        else 
        {
            $lv_R = "/R"
        }
        
        # [/U]  = unregisters the collector as a service
        
        if ($U -eq $false)
        {
            $lv_U = ""
        }
        else 
        {
            $lv_U = "/U"
        }

        # [/A appname] = sets the application name to DIAG$appname.  If running as a service, this sets the service name to DIAG$appname

        if ([string]::IsNullOrWhiteSpace($A))
        {
            $lv_A = ""
        }
        else 
        {
            $lv_A = "/A" + $A
        }

        # [/L] = continuous mode -- automatically restarts when shutdown via /X or /E
        
        if ($L -eq $false)
        {
            $lv_L = ""
        }
        else 
        {
            $lv_L = "/L"
        }

        
        # [/X] = snapshot mode -- takes a snapshot of all configured diagnostics and shuts down immediately

        if ($X -eq $false)
        {
            $lv_X = ""
        }
        else 
        {
            $lv_X = "/X"
        }

        
        # [/B [+]YYYYMMDD_HH:MM:SS] = specifies the date/time to begin collecting data; "+" specifies a relative time

        if ([string]::IsNullOrWhiteSpace($B))
        {
            $lv_B = ""
        }
        else 
        {
            $lv_B = "/B" + $B
        }
        
        # [/E [+]YYYYMMDD_HH:MM:SS]  = specifies the date/time to end data collection; "+" specifies a relative time
        
        if ([string]::IsNullOrWhiteSpace($E))
        {
            $lv_E = ""
        }
        else 
        {
            $lv_E = "/E" + $E
        }

        # [/T {tcp[,port]|np|lpc|via}] = connects to sql server using the specified protocol

        if ([string]::IsNullOrWhiteSpace($T))
        {
            $lv_T = ""
        }
        else 
        {
            $lv_T = "/T" + $T
        }    
        
        [string[]] $argument_arrayTemp = @()  
		
        if ($lv_U -eq "/U")
        {
            $argument_arrayTemp = $lv_A, $lv_U
        }
        else 
        {
            # special case if user typed /r instead of -R
            if ($ServiceState -eq "/r")
            {
                $lv_R = "/R"
            }
            
            $argument_arrayTemp = $lv_I, $lv_O, $lv_P, $lv_N, $lv_M, $lv_Q, $lv_C, $lv_G, $lv_R, $lv_A, $lv_L, $lv_X, $lv_B, $lv_E, $lv_T
        }
        
        foreach ($item in $argument_arrayTemp)
        {
            if (($item.Trim()) -ne "")
            {
                $argument_array += $item.Trim()
            }		
        }
        
    }

	# locate the SQLDiag.exe path for this version of PSSDIAG
	[string]$sqldiag_path = FindSQLDiag
	
	if ("Path_Error_" -eq $sqldiag_path)
	{
		#no valid path found to run SQLDiag.exe, so exiting
		exit
	}

		

	#Translate Performance Counters if((Get-WinSystemLocale).name -notlike "en*")
    & .\perfmon_translate.ps1

    # launch the sqldiag.exe process and print the last 5 lines of the console file in case there were errors

    Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Executing: $sqldiag_path $argument_array"
    Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Number of parameters passed: $($argument_array.Length)"
    & $sqldiag_path $argument_array

    
    $console_log = ".\output\internal\##console.log"

    if (($R -eq $true) -or ($ServiceState -in "stop", "start", "stop_abort") -or ($U -eq $true))
    {
        if($R -eq $true)
        {
            Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Registered SQLDiag as a service. Please make sure you run 'pssdiag.ps1 START' or 'SQLDIAG START' or 'net start SQLDIAG'" -ForegroundColor Green
        }

        if($U -eq $true)
        {
            Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Un-registered SQLDiag as a service." -ForegroundColor Green
        }
        
    }
    elseif (Test-Path -Path $console_log )
    {
        Write-Warning "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") Displaying the last 5 lines from \output\internal\##console.log file. If SQLDiag did not run for some reason, you may be reading an old log."
	    Get-Content -Tail 5 $console_log 
        Write-Host "$(Get-Date -Format "MM/dd/yyyy HH:mm:ss.fff") SQLDiag has completed. You can close the window. If you got errors, please review \output\internal\##SQLDIAG.LOG file"
    }

	

}


main

======================rtrim.vbs=================================

if (WScript.Arguments.Length <> 2) then
	WScript.Echo "Usage: rtrim.vbs infile outfile"
	WScript.Quit (-1)
end if
Set fso = CreateObject("Scripting.FileSystemObject")
set File = fso.OpenTextFile (WScript.Arguments (0), 1, False)
set OutFile = fso.OpenTextFile (WScript.Arguments(1), 2, True)

  While not File.AtEndOfStream

    OutFile.WriteLine (RTrim (File.ReadLine))

  WEnd

  File.Close
OutFile.Close

===============================run_in_dir.cmd===========================================
@echo off

pushd 
cd /d %2
%1 >nul 2>&1
popd




Popular posts from this blog