Skip to main content
Group PoliciesPowershellWindowsWindows 10Windows Server

How to Detect Who Deleted a File on Windows Server with Audit Policy

By June 23, 2021January 28th, 2022No Comments

You can use file system object access event auditing to identify a specific user who created, deleted, or modified a specific file. In this post, we’ll show you how to configure event auditing for files on a shared network folder on Windows Server 2016. After configuring auditing, you can use the information from the Event Viewer to find the user who deleted specific file on the file server. When you delete a file from a shared network folder, it is deleted immediately instead of being sent to the user’s recycle bin.

How to Enable File and Folder Access Auditing Policy on Windows

By default, File System Object Access audit is not enabled on Windows Server. You can enable and configure audit settings using Group Policy. If you need to enable audit policies on multiple servers or computers, you can use domain GPOs (configurable using the gpmc.msc mmc console). If you only want to configure auditing on one server, you can use Local Group Policy Editor.

  1. Open the Local Group Policy Editor console – gpedit.msc;
  2. Go to the GPO section with advanced audit policies: Windows Settings -> Security Settings -> Advanced Audit Policy Configuration -> Object Access;
  3. Open the Audit File System policy and specify that you want to log only successful access events to file system objects (Configure the following audit events -> Success); You can also enable auditing of local objects access using the Audit Object Access policy under Windows Settings -> Security Settings -> Local Policy -> Audit Policy. However, using the File System Audit policy is preferable because it only tracks NTFS access events.
  4. Save the changes and update your local Group Policy settings using the command: gpupdate /force.

Configuring File Deleted Audit Settings on a Shared Folder

Now you need to configure auditing in the properties of the share network folder you want to track access to. 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.

configure audit settings on a shared folder

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.

Then you need to specify which permissions used to access the object should be logged. To save only file deletion events in the Event Log, click the Show advanced permissions button. In the event list, leave auditing only for folder and file deletion events – Delete and Delete subfolders and files.

configure audit of file deletion actions on shared folder on Windows Server 2016folder

Remember that auditing policy for 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', 'none', 'none', 'Success')
$Acl = Get-Acl -Path $Path
$Acl.AddAuditRule($AuditChangesRules)
Set-Acl -Path $Path -AclObject $Acl

Now, if the user deletes any file or folder in the shared network folder, the File System -> Audit Success file delete event appears in the Security log with Event ID 4663 from the Microsoft Windows security auditing source.

Open the Event Viewer mmc console (eventvwr.msc), expand the Windows Logs -> Security section. Enable event log filter by the EventID 4663.

file deletion event id 4663 in the security log of windows event viewer

Open any of the remaining events in the Event Viewer. As you can see, it contains information about the name of the deleted file, the account of the user who deleted the file and the process name.

An attempt was made to access an object.
Subject:Security ID:                            CORP\jsmith
Account Name:                     jsmith
Account Domain:                  CORP
Logon ID:                               0x32B12627
Object:Object Server:                        Security
Object Type:                          File
Object Name:                        E:\Distr\Backup.rar
Handle ID:                              0x7bc4
Resource Attributes:            S:AI
Process Information:
Process ID:                             0x4
Process Name:
Access Request Information:
Accesses:                               DELETE
Access Mask:                         0x10000
file deletion audit event 4663 with username in security log

After enabling file access auditing policy, you can find in the Security log :

  • Who deleted the file from the shared network folder and when it happened;
  • What application (process) was used to delete the file;
  • What is the date of the backup to be restored.

How to Write File Deletion Events to SQL Database (MySQL/MSSQL)?

However, even if the audit of the deleted files is enabled, it can be troublesome to find something in the logs. Firstly, it is quite hard to find a specific entry among thousands of events (in Windows there are no convenient tool to search an event with a flexible filter). Secondly, if a file was deleted a long time ago, this event may be absent in the logs, since it was overwritten by new events.

You can save all file delete events to the SQL database. You can use Microsoft SQL Server, Elasticsearch, or MySQL/MariaDB databases to store your events.

In this example, we’ll show you how to log audit events to a separate database table on a MySQL. I will use the following table format:

  • Server name;
  • Name of the deleted file;
  • Date and time;
  • Name of the user who has deleted the file.

The MySQL query to create this table looks like that:

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));

If you want to use Microsoft SQL Server database, check out the post “How to run a MSSQL Server Query from PowerShell?

To get events with EventID 4663 from the Security log for the current day, you can use the following PowerShell script:

$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName="Security";starttime="$today";id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$User = $event.Event.EventData.Data[1]."#text"
$Computer = $event.Event.System.computer
}
}

Windows Security audit - event 4663 properties

The next PowerShell script will write the data you get to the MySQL database on a remote server (with the IP address 10.1.1.13):

Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll'
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString='server=10.1.1.13;uid=posh;pwd=P@ssw0rd;database=aduser'}
$Connection.Open()
$sql = New-Object MySql.Data.MySqlClient.MySqlCommand
$sql.Connection = $Connection
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName="Security";starttime="$today";id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$File = $File.Replace(‘\’,’|’)
$User = $event.Event.EventData.Data[1]."#text"
$Computer = $event.Event.System.computer
$sql.CommandText = "INSERT INTO deleted_items (server,file_name,dt_time,user_name ) VALUES ('$Computer','$File','$Time','$User')"
$sql.ExecuteNonQuery()
}
}
$Reader.Close()
$Connection.Close()
After saving events to an external database, this Event log can be cleared.

Now, to find out who has deleted the file “AnnualReport.DOC“, it is enough to run the following script in the PowerShell console:
$DeletedFile = "%AnnualReport.DOC%"
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll'
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString='server=10.1.1.13;uid=posh;pwd=P@ssw0rd;database=aduser'}
$Connection.Open()
$MYSQLCommand = New-Object MySql.Data.MySqlClient.MySqlCommand
$MYSQLDataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter
$MYSQLDataSet = New-Object System.Data.DataSet
$MYSQLCommand.Connection=$Connection
$MYSQLCommand.CommandText="SELECT user_name,dt_time    from  deleted_items where file_name LIKE '$DeletedFile'"
$MYSQLDataAdapter.SelectCommand=$MYSQLCommand
$NumberOfDataSets=$MYSQLDataAdapter.Fill($MYSQLDataSet, "data")
foreach($DataSet in $MYSQLDataSet.tables[0])
{
write-host "User:" $DataSet.user_name "at:" $DataSet.dt_time
}
$Connection.Close()

You can now see the username and the time the file was deleted in the PS console.

select file deletion event from mysql db

Since an issue has been found that the symbol “\” is not written to the database, we have replaced it for “|”. So if you have to display the full path to the file, you can perform a reverse replacement when selecting from the database:

$DataSet.file_name.Replace(‘|’,’\’).

The script of writing the information from the Event log to the database can be run at the end of the day using Task Scheduler or attached to the file deletion EventID (On Event), which is more resource-consuming. It depends on the requirements to the system. Make sure you set the maximum size of the Security event log file to be large enough to log all events for the day. Otherwise, you will have to run the task of exporting the data to the database more often than once a day or even on the trigger. Typically, the Maximum Log Size on the workstations has to be at least 64 MB, and 262 MB on the Windows File servers. The option to overwrite old events should be left enabled (Overwrite events as needed).

If necessary, you can create a simple PHP web page to get the information about the users who have deleted files in a more convenient form. If the log contains an entry that the file was deleted by the user, do not hurry to interpret it as a deliberate or malicious action. Many programs (especially MS Office apps) create a temporary file when saving changes and then delete the old version of the file. In this case, enable logging of process name (ProcessName fileld), from which the file was deleted, and you can parse file deletion events based on it. Or you can filter the events from such processes, like winword.exe, excel.exe, etc.

Logging File Delete Audit Events to a Text File

If you don’t want to use a separate database server, you can save file deletion audit events to a plain text log file. Use this PowerShell script to save you output to a text file:

$Outfile = "C:\Logs\Deleted-file-history-log.txt"
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName="Security";starttime="$today";id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$User = $event.Event.EventData.Data[1]."#text"
$strLog = $Computer + " " + $File + " " + $Time + " " +  $User
$strLog  | out-file $Outfile –append
}
}

save file deletion events history to a text file using powershell

So, we have suggested an idea and the general model of the system to audit and store the information about the deleted files in the shared network folders. If needed, it can easily be modified to meet your requirements.

Leave a Reply