AD After Create Rule Logging file access

We have an ConnectorAfterCreate rule for AD source to do some extra things with PS scripting. With the PS call, we run a script which logs every action into a file.
Since May 15, this ps script throws error randomly(I mean not every time.) This was not happening before that day. The error is simple:

20250521-101412  ------------------------------------------------------------------------------------------------------------------------
20250521-101412  Entering ActiveDirectory-AfterCreate
20250521-101412  => server = Server1
20250521-101412  => user   = SPUser
20250521-101412  Exception calling "AppendAllLines" with "2" argument(s): "The process cannot access the file '\\contoso.net\IAM\PROD\Logs\Utility Server\Scripts\ActiveDirectory-AfterCreate\ActiveDirectory-AfterCreate-20250521-101412-381708-l6on.log' because it is being used by another process."

As you can see we create the log file with timestamp plus 4 random characters and the timestamp shows microseconds.
Does anyone have an idea about this problem?

Hi @gkiris1

Yes, i remember seeing this error in my iqService and turned out there was powershell process instance which was running or hanging for long time and had acquired the lock on my log file due to which writing to the same file was not happening properly.
Can you please try closing that process from task manager or try to restart the server. May be that might solve your issue.
Otherwise you can also try to create another file in the same folder location and try to edit this file using powershell, just to see if there are no changes on the security of the folder.

Another tip, you can try to double check if the file path is correct which i am sure you might have already tried.

I hope this helps.

Regards
Vikas.

Hi Vikas,

Thank you for your prompt and detailed reply.
We restarted the server. But didn’t work.
We checked if there is another process currently locked the file. There is none.
For every account creation process we create another log file with timestamp and 4 char long random string.

Hi Gorkem,

Yes creating individual files for each user is the way to go for. Can you please check manually adding the line in that file if it still throws the same error.

Can you please send me the code snippet which you are using to write into file, just want to check if you are using

Add-Content -Path $FilePath -Value 

OR using something like below 

" user created ">>$FilePath

Thank You.
Regards
Vikas

This where we call the log writing function:

 # Write to global log file
    Write-LogSeparator
    Write-Log "Entering $ScriptName"
    Write-Log "=> server = $($env:computername)"
    Write-Log "=> user   = $($env:username)"
    Write-Log "=> domain = $($env:userdomain)"
    Write-Log "=> stage  = $stagingEnvironment"
    Write-Log "=> logfile = $logFilePath" 

And this is the Write-Log function

function Write-Log {
    <#
        .SYNOPSIS
        Writes a message to screen and log file.

        .NOTES
        - only writes to log FILE if global variable $global:LogFilePath is set
    #>
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is used only once, and for better visual cues')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '', Justification = 'having the log file declared at global scope keeps the function signatures short')]
    param(
        [Parameter(Mandatory = $True)][string]$Message,
        [Parameter(Mandatory = $False)][ConsoleColor]$ForegroundColor = $host.Ui.RawUi.ForegroundColor,
        [Parameter(Mandatory = $False)][ConsoleColor]$BackgroundColor = $host.Ui.RawUi.BackgroundColor,
        [switch] $SkipFileWrite

    )

    # always write message to screen
    Write-Host $message -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor

    # no file-write if skipped
    if ($SkipFileWrite) {
        return
    }

    # no file-write if global LogFile variable is not set (e.g. when running functions directly)
    if (-not(Get-Variable -Name LogFilePath -Scope Global -ErrorAction SilentlyContinue)) {
        return
    }

    $logLine = "$(Get-Date -Format "yyyyMMdd-HHmmss")  $Message"

    # append to log file using UTF-8 Without Bom
    [IO.File]::AppendAllLines($global:LogFilePath, [string[]]$logLine)
}

One side note, this code is in production for the last 4 years and we hadn’t seen this error before 15th May.

1 Like

Hi @gkiris1

Yes, this file access issue could be tricky sometimes and is difficult to deal with. It could be occurring suddenly if there were some updates to the windows service or might be too many events triggered for the user at the same time. But honestly not sure if i can help but below are some more things you can try if they helps.

Can you please try to use the code block appendAllLines in the powershell terminal by giving this affected file path, and see if the same error is appearing ?

If so, can you try some other native method to write something dummy to the log file like below. May be this might help.

Add-Content -Path $global:LogFilePath -Value "Testing if the file is locked" -Encoding UTF8

Another possible code snippet you can try below to see if the file is indeed still locked

try {
$Path = "Log File Path here " 
$stream = [System.IO.File]::Open($Path, 'Open', 'ReadWrite', 'None')
$stream.Close()
return $false # if the file is not locked it will return here false
}
catch{
return $true # if the file is locked by some other process it will return true then. 
}

IF above code returns true then it is being locked by other process and i do not know if it is possible by powershell to know which process has locked it but may be there might be some external tools or other languages that can give you that information and then you can try to kill that process using terminal.

I hope this information helps if you have not already tried it. :slight_smile:

Regards
Vikas.

Hi Vikas,

With your suggestion, I put logging line into try catch and so far the problem seems resolved.

Thank you.

1 Like