我已将 FileSystemWatcher 的功能封装到一个模块中,并提供了一个小示例,说明如何将其用于您的要求。
# Module FileSystemWatcher
<#
.SYNOPSIS
Register to receive filesystemwatcher events for a file or folder.
#>
function Register-FileSystemEvent
{
[CmdLetBinding(DefaultParameterSetName="File")]
param
(
[Parameter(Mandatory=$true,Position=0,ParameterSetName="File")]
[string]$path,
[Parameter(Mandatory=$true,Position=0,ParameterSetName="Folder")]
[string]$folder,
[Parameter(Mandatory=$false,Position=1,ParameterSetName="Folder")]
[string]$filter="*.*",
[Parameter(Mandatory=$true,Position=2)]
[string]$event,
[scriptblock]$action={
# Action code here
$sourceidentifier = $Event.SourceIdentifier
$FileName = $Event.SourceEventArgs.FullPath
$EventType = $Event.SourceEventArgs.ChangeType
$EventTime = $Event.TimeGenerated
$message = ("File {0} {1} at {2:yyyyMMdd HH:mm:ss}" -f $FileName, $EventType, $EventTime)
Msg ([environment]::UserName) $message
},
$MessageData
)
if ($PSCMdLet.ParameterSetName -eq "File")
{
$folder = $path.Replace(([System.IO.Path]::GetFileName($path)), "")
$filter = [System.IO.Path]::GetFileName($path)
}
$watcher = New-Object System.IO.FileSystemWatcher -ArgumentList $folder, $filter
$uniqueId = ("{0:yyyyMMddHHmmss}" -f [DateTime]::Now)
$sourceIdentifier = ("File_{0}_{1}" -f $event, $uniqueId)
$job = Register-ObjectEvent -InputObject $watcher -EventName $event -SourceIdentifier $sourceIdentifier -Action $action -MessageData $MessageData
$Script:ActiveWatchers += @{$sourceIdentifier = $job}
}
<#
.SYNOPSIS
Unregister a FileSystem event or All
.PARAMETER All
Unregisters all events
#>
function Unregister-FileSystemEvent
{
param
(
$id,
[switch]$All
)
if ($All.IsPresent)
{
foreach ($item in $Script:ActiveWatchers.Keys)
{
Unregister-Event $item
Remove-Job $item
}
$Script:ActiveWatchers = @{}
}
else
{
Unregister-Event $id
Remove-Job $id
$Script:ActiveWatchers.Remove($id)
}
}
function Init
{
if ($Script:ActiveWatchers.Count -gt 0){Unregister-FileSystemEvent -All}
$Script:ActiveWatchers = @{}
}
Init
Export-ModuleMember -Function Register-FileSystemEvent, Unregister-FileSystemEvent `
-Variable ActiveWatchers
这个模块的基本思想是能够指定一个脚本块在文件事件被触发后执行。 -MessageData 用于在事件触发后将更多数据附加到事件中。在下面的示例中,它用于发送 smtpserver 和凭据。
下面的示例代码使用 fileSystemWatcher 模块并在每次创建文件时发送一封包含结果的电子邮件。
请注意,Send-MailMessage 的参数可能不是您的邮件服务器所必需的,而是我过去使用 office365 服务器发送电子邮件的参数。
# Demo using FileSystemWatcher to validate created files
Import-Module .\FileSystemWatcher
$smtpserver = Read-Host -Prompt "Specify your smtp server"
$mailcred = Get-Credential -Message "Specify credentials for your smtp server"
$eventid = Register-FileSystemEvent -folder C:\users\Jower\OneDrive\Documents -event Created -MessageData @{SmtpServer = $smtpserver;Credentials = $mailcred} -action {
function ValidateFile($filename)
{
$messages = @()
if ([System.IO.Path]::GetExtension($filename) -ne ".xls")
{
$messages += ("{0}: Only excel version 97 files allowed here" -f $filename)
}
if ([System.IO.Path]::GetFileName($filename).Contains(" "))
{
$messages += ("{0}: Spaces are not allowed in filename" -f $filename)
}
if ($filename.Length -gt 15)
{
$messages += ("{0}: Filenames of more than 15 characters is not allowed" -f $filename)
}
return $messages
}
$smtpserver = $Event.MessageData.SmtpServer
$credentials = $Event.MessageData.Credentials
$messages = ValidateFile $Event.SourceEventArgs.Name
if ($messages.Count -gt 0)
{
Send-MailMessage -From "filealerts@domain.com" -To "recipient@domain.com" -Subject "File validation" -SmtpServer $smtpserver -Body ([string]::Join("`n", $messages)) -port 587 -UseSsl -Credential $credentials
}
}
# To disable events again.
# Unregister-FileSystemEvent -id $eventid
# Can also use
# Unregister-FileSystemEvent -All