You can use file system object access event auditing to identify which user created, deleted, or modified a specific file. In this article, we’ll show you how to configure event auditing for a shared network folder on a file server running Windows Server 2025/2022/2019. After configuring auditing, you can use the information from the Event Viewer to find the user who deleted a specific file from a shared folder on a file server. Once auditing is enabled, administrators can use the Event Viewer to identify relevant security events and determine which user deleted a file or folder on the file server.
How to Enable File and Folder Access Audit Policy in Windows
By default, auditing of file system object access is not enabled on Windows. If auditing was not enabled when the file was deleted, it will not be possible to determine which user performed the deletion retrospectively, since the necessary audit trail will not exist in the logs.
You can use Group Policy to enable and configure auditing of file and folder access events. The audit policy can be configured using either the domain group Policy editor (gpmc.msc snap-in) or the Local Group Policy Editor (gpedit.msc) on a specific host.
- Go to the GPO section with advanced audit policies: Windows Settings -> Security Settings -> Advanced Audit Policy Configuration -> Object Access
- Enable the Audit File System policy and specify that only successful access events to file system objects should be logged. (Configure the following audit events -> Success);
- Save the changes and update the Group Policy settings on a file server using the command:
gpupdate /force.
Tracking File and Folder Deletions with Audit Policy
Next, configure the audit settings for each shared network folder you want to monitor. Run File Explorer and open the folder properties. Go to the Security tab. Click the Advanced button -> go to the Auditing tab.
If the message “You must be an administrator or have been given the appropriate privileges to view the audit properties of this object” appears, click the Continue button.
Then click the Add button to specify the user or group for which you want to capture audit events. If you want to track access events for all users, specify the Everyone group.
To log only file deletion events in the Event Log, click the Show advanced permissions button. Only folder and file deletion events should be checked in the permissions list.
Keep in mind that auditing Windows objects requires additional computing resources. Use it carefully, always try to minimize the number of audit objects and events to log.
$Path = "E:\Public"
$AuditChangesRules = New-Object System.Security.AccessControl.FileSystemAuditRule('Everyone', 'Delete,DeleteSubdirectoriesAndFiles', 'ContainerInherit,ObjectInherit', 'None', 'Success')
$Acl = Get-Acl -Path $Path
$Acl.AddAuditRule($AuditChangesRules)
Set-Acl -Path $Path -AclObject $Acl
When a user deletes any file from an audited shared folder, events from the Microsoft Windows security auditing source will be logged in the Security log of the file server, and can be viewed in the Event Viewer
Open the Event Viewer MMC console (eventvwr.msc), expand the Windows Logs -> Security section. Enable the event log filter by the EventIDs 4663 and 4659:
- 4663 – this event occurs when an object is deleted from a local folder.
- 4659 – event of deletion from a shared folder (access via a UNC path or mapped network drive) or local deletion bypassing the Recycle Bin (
SHIFT+DEL).
Event descriptions include the name of the user who deleted the file (Subject: Account Name) and the name of the deleted file (Object Name). The Access Masks 0x10000 and 0x10080 indicate that the file was deleted.
A handle to an object was requested with intent to delete.
Subject:
Security ID: WOSHUB\jsmith
Account Name: jsmith
Account Domain: WOSHUB
Logon ID: 0xD9F590
Object:
Object Server: Security
Object Type: File
Object Name: C:\Public\it_reports2025.pdf
Handle ID: 0x0
Process Information:
Process ID: 0x4
Access Request Information:
Transaction ID: {00000000-0000-0000-0000-000000000000}
Accesses: DELETE
ReadAttributes
Access Mask: 0x10080
Privileges Used for Access Check:
After enabling the file access auditing policy, you can find in the Security log:
- Who deleted the file from the shared network folder, and when did it happen
- Which program (process) was used to delete the file
- What is the date of the backup to be restored?
Even with the audit of file deletions enabled, it can be difficult to find something in the Security logs. First, it is difficult to find the necessary entry among thousands of events (Windows doesn’t have convenient, built-in tools for searching the Event Viewer). Secondly, if a file was deleted a long time ago, it may be missing from the log because it was overwritten by new events.
In this case, you can export all file deletion events to an external storage. For example:
- Ideally, events should be sent to a specialized log collector like Graylog or Elasticsearch (refer to the post that explains how to collect Windows events in Graylog)
- Text log file
- Database
Logging File Deletion Events to a Text File
The simplest case is to export file deletion events from the Event Viewer to a plain text file on the file server. The following PowerShell script searches the Security log for all events with event IDs 4663 and 4659 that occurred today, extracts the deleted file or folder name along with the username who deleted it, and saves the results to a text log file.
$outputFile = "C:\Logs\Deleted-file-history-log.txt"
$auditfolder= "C:\Public\*"
$eventIds = 4663, 4659
$computer = $env:COMPUTERNAME
$startTime = [datetime]::Today
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=$eventIds; StartTime=$startTime} | ForEach-Object {
$xml = [xml]$_.ToXml()
$user = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'SubjectUserName' } | Select-Object -ExpandProperty '#text'
$file = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'ObjectName' } | Select-Object -ExpandProperty '#text'
if ($file -and $file -like $auditfolder) {
"$computer`t$($_.TimeCreated)`t$user`t$file" | Add-Content -Path $outputFile
}
}
Save File Deletion Events to the SQL Database
Another option is to save file deletion events from a file server to an external SQL database. You can use Microsoft SQL Server, Elasticsearch, PostgreSQL, MySQL/MariaDB, or any other database to store events.
In this example, we will demonstrate how to export audit events from the Event Viewer to a database table on a MariaDB server. I will use the following table format:
- FileServer name (hostname)
- Name of the deleted file
- Date and time
- Name of the user who has deleted the file.
The SQL query to create this table in MariaDB might look like this:
CREATE TABLE deleted_items (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), file_name VARCHAR(255), dt_time DATETIME, user_name VARCHAR(100), PRIMARY KEY (ID));
The above example shows a PowerShell script that retrieves file deletion events (4663 and 4659) from the Security log. Rather than storing data in a text file, we will now save it to a table on the MariaDB server.
To connect to the remote database, we will use the SimplySql PowerShell module. You can install it from the PowerShell gallery or install the PowerShell module manually (in case of an offline environment):
Install-Module -Name SimplySql
Add the following code to connect to a MariaDB database on a remote server:
import-module SimplySql
$db_host="192.168.31.115"
$db_name="FileDelLog"
$db_user="rwusr"
$db_pass="P@ssw0rd"
$PassSecure = ConvertTo-SecureString $db_passs -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential($db_user, $PassSecure)
$sqlConnect = Open-MySqlConnection -ConnectionName rDBCon -Server $db_host -Database $db_name -Credential $creds -Port 3306 -Verbose
Next is the code for selecting events from the Event Viewer and writing the data to the SQL table on a remote MariaDB host.
$audit_folder= "C:\Public\*"
$eventIds = 4663, 4659
$computer = $env:COMPUTERNAME
$startTime = [datetime]::Today
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=$eventIds; StartTime=$startTime} | ForEach-Object {
$xml = [xml]$_.ToXml()
$user = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'SubjectUserName' } | Select-Object -ExpandProperty '#text'
$file = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'ObjectName' } | Select-Object -ExpandProperty '#text'
if ($file -and $file -like $audit_folder) {
$time = $_.TimeCreated.ToString('yyyy-MM-dd HH:mm:ss')
$fileEscaped = $file -replace '\\', '\\\\'
$sql_query = "INSERT INTO track_del (server, file_name, dt_time, user_name) VALUES ('$computer', '$fileEscaped', '$time', '$user');"
Invoke-SqlQuery -ConnectionName rDBCon -Query $sql_query
}
}
Close-SqlConnection -ConnectionName rDBCon
C:\Public\IT\report.docx. Therefore, they must be escaped by replacing each backslash with double slashes.Now, to find out who deleted the specific file, run the following script in the PowerShell console to search the SQL database. In this example, we are searching for deleted files containing “report2025” in their names.
$file_to_search = "%report2025%"
$PassSecure = ConvertTo-SecureString $db_passs -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential($db_user, $PassSecure)
$sqlConnect = Open-MySqlConnection -ConnectionName rDBCon -Server $db_host -Database $db_name -Credential $creds -Port 3306 -Verbose
$fileSearchEscaped = $file_to_search -replace '\\', '\\\\'
$sql_query = @"
SELECT server, REPLACE(file_name, '\\\\', '\\') AS file_name, dt_time, user_name FROM track_del
WHERE file_name LIKE '%$fileSearchEscaped%'
ORDER BY dt_time DESC;
"@
$data = Invoke-SqlQuery -ConnectionName rDBCon -Query $sql_query
$data | Format-Table -AutoSize
Close-SqlConnection -ConnectionName rDBCon
You will see the username and the time the file was deleted in the PS console.
- The script that writes information from the event log to the database can be run at the end of the day using Task Scheduler. As an alternative, it can be attached to the file deletion event ID, which is a more resource-intensive option.
- Ensure that the maximum size of the Security log on the file server is large enough to log all events for the day. Otherwise, you will need to export logs to the database more than once a day or via a trigger.
- If you don’t need the other logs after saving events to an external database, you can clear this Event Viewer log.
You can use PHP to create a simple webpage that conveniently provides information about users who have deleted files.
*.tmp or *.temp.So, we have suggested an idea and a general model of the system to audit and store the information about the deleted files in the shared network folders. It is easy to adapt it to suit your requirements.






5 comments
Well summarized !
Thank you for sharing this interesting post.
Here is one more informative article which provides step-wise instructions to enable security auditing on important files and track every critical changes/access or file deletion into real time – https://community.spiceworks.com/how_to/123983-track-file-deletions-and-permission-changes-on-windows-file-server
Great stuff. Just what I was looking for. Thank you.
This produces a very, very large number of logs. For example, all temporarily created files that are deleted when a program is ended or when files are closed are also recorded. That may be correct in principle, but it goes far beyond my requirements.
The question that now arises is it possible to reduce the logging to the essentials in some way or does the effort involved in developing such a concept far outweigh the benefits?
Drag the logs into any data grave (Elastic Stack and the Log Ingestor are available for free), then it doesn’t really matter how many there are…
Thanks a lot sir, it is very helpful to track who deleted files / folder.