1

I have this function to read the SQL Server errorlog but the problem is that I'm not able to read the errorlog that the server is using at the time. I have been google-ing and it seems that the Fileshare flag isn't working for powershell. Is there some way to set the the Fileshare flag when I try to open the file?

    function check_logs{
        param($logs)
        $pos
        foreach($log in $logpos){
            if($log.host -eq $logs.host){
                $currentLog = $log
                break
            }
        }
        if($currentLog -eq $null){
            $currentLog = @{}
            $logpos.Add($currentLog)
            $currentLog.host = $logs.host
            $currentLog.event = $logs.type
            $currentLog.lastpos = 0
        }
        $path = $logs.file
        if($currentLog.lastpos -ne $null){$pos = $currentLog.lastpos}
        else{$pos = 0}
        if($logs.enc -eq $null){$br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open))}
        else{
            $encoding = $logs.enc.toUpper().Replace('-','')
            if($encoding -eq 'UTF16'){$encoding = 'Unicode'}
            $br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open), [System.Text.Encoding]::$encoding)
        }
        $required = $br.BaseStream.Length - $pos
        if($required -lt 0){
            $pos = 0
            $required = $br.BaseStream.Length
        }
        if($required -eq 0){$br.close(); return $null}
        $br.BaseStream.Seek($pos, [System.IO.SeekOrigin]::Begin)|Out-Null
        $bytes = $br.ReadBytes($required)
        $result = [System.Text.Encoding]::Unicode.GetString($bytes)
        $split = $result.Split("`n")
        foreach($s in $split)
         {
            if($s.contains("  Error:"))
            {
                $errorLine = [regex]::Split($s, "\s\s+")
                $err = [regex]::Split($errorLine[1], "\s+")
                if(log_filter $currentLog.event $err[1..$err.length]){$Script:events = $events+ [string]$s + "`n" }         
            }
        }
        $currentLog.lastpos = $br.BaseStream.Position 
        $br.close()
     }

To be clear the error comes when I try to open the file. The error message is:

 Exception calling "Open" with "2" argument(s): "The process cannot access the file
 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Log\ERRORLOG' 
  because it is being used by another process."

Gísli

1 Answer 1

1

So I found the answer and it was pretty simple.

The binary reader constructor takes as input a stream. I didn't define the stream seperately and that's why I didn't notice that you set the FileShare flag in the stream's constructor.

What I had to do was to change this:

{$br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open))}

To this:

{$br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite))}

And then it worked like a charm.

Gísli

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.