2 years ago
#7561
Teknowledgist
Can PowerShell be an ActiveScriptEventConsumer?
I need to continuously watch a particular "drop" folder for (tiny) pdfs and auto-print and delete them. The printing itself is being handled by SumatraPDF (because I don't think there is a built-in, Windows method).
Creating a temporary WMI event monitor in PowerShell is pretty straightforward:
$WQLquery = "SELECT * FROM __InstanceCreationEvent WITHIN 5 " +
"WHERE TargetInstance ISA 'CIM_DataFile' " +
"AND TargetInstance.Extension = 'pdf' " +
"AND TargetInstance.Drive = '$($Drive):' " +
"AND TargetInstance.Path = '$($Folder.replace('\','\\'))'"
$Action = {
$TimedOut = $null
$PrintProcess = Start-Process -FilePath $Sumatra -ArgumentList "-Print-To $Printer `"$($EventArgs.NewEvent.TargetInstance.Name)`"" -PassThru
$PrintProcess | Wait-Process -Timeout 10 -ErrorAction SilentlyContinue -ErrorVariable TimedOut
if ($TimedOut) {
"Printing $($EventArgs.NewEvent.TargetInstance.Name) timed out." | Out-File $ErrorLogPath -Append
$PrintProcess.kill
} elseif ($PrintProcess.ExitCode -ne 0) {
"Error for $($EventArgs.NewEvent.TargetInstance.Name) : $($PrintProcess.ExitCode)" | Out-File $ErrorLogPath -Append
} else {
Remove-Item $EventArgs.NewEvent.TargetInstance.Name -Force
}
}
Register-CimIndicationEvent -Query $wqlquery -SourceIdentifier 'FileCreated' -Action $Action
When it comes to creating a permanent event subscription, I can replace the Action
and Register-CimIndicationEvent
with:
# This creates a permanent event monitor that lasts through a reboot
# Step One: Create a Filter object
$FilterArgs = @{
ClassName = '__EventFilter'
NameSpace = 'root\subscription'
Computername = $env:COMPUTERNAME
ErrorAction = 'Stop'
Property = @{
Name = 'PDFCreatedFilter'
EventNamespace = 'root\CIMV2'
QueryLanguage = 'WQL'
Query = $WQLQuery
}
}
$FilterInstance = New-CimInstance @FilterArgs
# Step Two: Create a Consumer object
$ConsumerArgs = @{
ClassName = 'ActiveScriptEventConsumer'
NameSpace = 'root\subscription'
Computername = $env:COMPUTERNAME
ErrorAction = 'Stop'
Property = @{
Name = 'FileCreatedConsumer'
EventNamespace = 'root\CIMV2'
ScriptingEngine = '' # <---- What goes here for PowerShell?
ScriptFileName = '' # <---- What goes here for PowerShell?
}
}
$ConsumerInstance = New-CimInstance @ConsumerArgs
# Step Three: Create a Binding object between the Filter and Consumer
$BindingArgs = @{
ClassName = '__FilterToConsumerBinding'
NameSpace = 'root\subscription'
Computername = $env:COMPUTERNAME
ErrorAction = 'Stop'
Property = @{
Filter = [Ref]$FilterArgs
Consumer = [Ref]$ConsumerArgs
}
}
$BindingInstance = New-CimInstance @BindingArgs
However, and you can see, I am unsure about the ActiveScriptEventConsumer
. Microsoft's documentation says it can be "in an arbitrary scripting language", but every example I can find uses VBScript only. I'd really like to use PowerShell.
Is PowerShell a valid Scripting Engine
?
If yes, can someone provide the syntax for the ScriptingEngine
and ScriptText
properties to get it to work?
If no, am I better off hacking together some noob VBScript (yuck!) or using an CommandLineEventConsumer
to start a PowerShell script (that I then have to watch/protect)?
Thanks!
windows
powershell
vbscript
event-handling
wmi-query
0 Answers
Your Answer