File System Fixations
(I am testing an experimental table of contents feature)
In this article:
Let's continue exploring how to use eventing in PowerShell to monitor changes. Today, I want to focus on filesystem changes. You might want to monitor a directory for new files, or changes to existing files. PowerShell provides several ways to do this. Although, I will tell you up front, I have yet to find a method that will show you what changed in a file's content. But, you can watch for creations, deletions, and modifications to files and folders.
CIM Indication Events
You can use CIM indication events to monitor filesystem changes. The __InstanceCreationEvent
, __InstanceDeletionEvent
, and __InstanceModificationEvent
classes can be used to watch for changes in the filesystem. For files, you will need to use the CIM_DataFile
class. When creating a monitoring query, you want to be as specific as possible. If your query is too broad, you will most likely get a quota violation error. This means it would take too many system resources to fulfill the request.
Here's an example that will watch for new files created in the C:\Work
directory:
$query="Select * from __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'CIM_DATAFILE' AND TargetInstance.Drive='C:' AND TargetInstance.Path='\\work\\'"
Register-CimIndicationEvent -query $query -source "NewWorkFile" -messageData "A new file has been created in C:\Work"
Notice that I am escaping the backslashes in the path. The value in the instance will be \work\
, so you need to escape the backslashes in the query string.
When a new file is created, I get an event just as I've shown you before.
PS C:\> Get-Event
ComputerName :
RunspaceId : e661d573-8701-45df-b103-67fcdaccab95
EventIdentifier : 1
Sender : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher
SourceEventArgs : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationEventInstanceEventArgs
SourceArgs : {Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher, }
SourceIdentifier : NewWorkFile
TimeGenerated : 9/17/2025 9:19:56 AM
MessageData : A new file has been created in C:\Work
The object in the SourceEventArgs
property contains the CIM_DataFile
object that represents the new file.
PS C:\> (Get-Event).SourceEventArgs.NewEvent.TargetInstance | Select *
Status : OK
Name : c:\work\newData.txt
Caption : c:\work\newData.txt
Description : c:\work\newData.txt
InstallDate : 9/17/2025 9:19:50 AM
AccessMask : 18809343
Archive : True
Compressed : False
CompressionMethod :
CreationClassName : CIM_LogicalFile
CreationDate : 9/17/2025 9:19:50 AM
CSCreationClassName : Win32_ComputerSystem
CSName : PROSPERO
Drive : c:
EightDotThreeFileName : c:\work\newdata.txt
Encrypted : False
EncryptionMethod :
Extension : txt
FileName : newdata
FileSize : 49
FileType : txt File
FSCreationClassName : Win32_FileSystem
FSName : NTFS
Hidden : False
InUseCount :
LastAccessed : 9/17/2025 9:19:50 AM
LastModified : 9/17/2025 9:19:50 AM
Path : \work\
Readable : True
System : False
Writeable : True
Manufacturer :
Version :
PSComputerName :
CimClass : root/CIMV2:CIM_DataFile
CimInstanceProperties : {Caption, Description, InstallDate, Name…}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
I have not found a way to identity who created the file from the event. Although, if the file still exists, you can use the Get-Acl
cmdlet to find out who the owner is.
PS C:\> (Get-Event).SourceEventArgs.NewEvent.TargetInstance.name | Get-Acl |
Select-Object -ExpandProperty Owner
BUILTIN\Administrators
The query I am using will not capture events in subdirectories of C:\Work
. It will only capture events for files created directly in C:\Work
. While it is possible to use the LIKE
operator in the query:
$query="Select * from __InstanceCreationEvent Within 10 where TargetInstance ISA 'CIM_DATAFILE' AND TargetInstance.Drive='c:' AND TargetInstance.Path='\\work\\' AND TargetInstance.FileName LIKE '%data-%'"
Register-CimIndicationEvent -query $query -source "NewWorkDataFile" -messageData "A new data file has been created in C:\Work"
When I try to use a wildcard match in the Name
or Path
properties, the Register-CimIndicationEvent
command never completes.
Watching Files with CIM Indication Events
You can also use CIM indication events to watch for changes to specific files. However, you need to be as specific as possible in your query to avoid quota violations. Here is an example that watches for changes to my PowerShell profile.
$path = (Get-Item $profile).Target.replace("\","\\")
$query="Select * from __InstanceModificationEvent Within 10 where TargetInstance ISA 'CIM_DATAFILE' AND TargetInstance.Name='$path'"
Register-CimIndicationEvent -query $query -source "PSProfileChange" -messageData "The PowerShell profile has changed"
My PowerShell profile uses a symbolic link, so I need to get the target of the link. Then I escape the backslashes in the path. As I mentioned before, I can't tell what changed in the file, only that it was modified.
PS C:\> Get-event
ComputerName :
RunspaceId : c4e209cc-e3cb-41fc-adec-9672382c0eae
EventIdentifier : 1
Sender : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher
SourceEventArgs : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationEventInstanceEventArgs
SourceArgs : {Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher, }
SourceIdentifier : PSProfileChange
TimeGenerated : 9/17/2025 11:28:09 AM
MessageData : The PowerShell profile has changed
PS C:\> (Get-Event).SourceEventArgs.NewEvent.TargetInstance
Compressed : False
Encrypted : False
Size :
Hidden : False
Name : D:\OneDrive\PSProfiles\PowerShell7\Microsoft.PowerShell_profile.ps1
Readable : True
System : False
Version :
Writeable : True