Search code examples
powershelllogfilelocked-files

Powershell: Write Log-file with paralell file access


i try to write a logfile with some debug output. My it runs fine with sequential runs, but as soon as i start the baseapplication in more instances, i get an error.

Der Prozess kann nicht auf die Datei zugreifen, da ein anderer Prozess einen Teil der Datei gesperrt hat. : 'B:\Logfiles\Startup.log' The process can not access the file because it is locked by another process.

So i tried to do a do - try - catch construct to retry if the file is locked. But for some reason this is not working:(

do{
    $Failed = $false
    Try{
        Write-Output "C:\KFZBooth\Software\02_remove.bg\AIBackgroundRemove.exe" -ArgumentList '"batch"',`"$Original`",'""',`"$AIAusgabepfad\$Originaldatei$Originaltyp`" | Out-file $StartUpLog -append
    } catch { 
        $Failed = $true
        Write-Host "RETRY Reduce Credit"
        Write-Host $_.Exception.Message
        Write-Host $_.Exception.ItemName
        Write-Output "Logproblem im Startup.log - RETRY" | Out-file $UsageLog -append
    } 
} while ($Failed)

Is there a better way of writing logfiles or wait for a file to be unlocked?


Solution

  • It really depends on the file type. for example, if you were logging using MSWord or other MSOffice files:

    Run the code below with the file closed, and then the file opened.

    $FileName = 'D:\temp\TestDoc.docx'
    Try 
    {
        $FileStream = [System.IO.File]::Open($FileName,'Open','Write')
        $FileStream.Close()
        $FileStream.Dispose()
        ($IsLocked  = $False)
    } 
    Catch [System.UnauthorizedAccessException] {($IsLocked = 'AccessDenied')} 
    Catch {($IsLocked = $True)}
    

    Text files do not have this issue.

    Yet, why use a file at all. Create your own event log and write directly to that.

    Use PowerShell to Create and to Use a New Event Log

    https://devblogs.microsoft.com/scripting/use-powershell-to-create-and-to-use-a-new-event-log/

    Have you looked at using PowerShell transcripts?

    Get-Command -Name '*transcript*' | ft -a
    # Results
    <#
    CommandType Name             Version Source                   
    ----------- ----             ------- ------                   
    Cmdlet      Start-Transcript 3.0.0.0 Microsoft.PowerShell.Host
    Cmdlet      Stop-Transcript  3.0.0.0 Microsoft.PowerShell.Host
    #>
    # Get specifics for a module, cmdlet, or function
    (Get-Command -Name Start-Transcript).Parameters
    (Get-Command -Name Start-Transcript).Parameters.Keys
    Get-help -Name Start-Transcript -Examples
    # Results
    <#
    Start-Transcript
    Start-Transcript -Path "C:\transcripts\transcript0.txt" -NoClobber
    #>
    Get-help -Name Start-Transcript -Full
    Get-help -Name Start-Transcript -Online