How to pass event properties to a CommandLine event consumer in a permanent event monitor?

Viewed 89

I need to continuously watch a particular "drop" folder for (tiny) pdfs and auto-print and delete them. The printing itself will be 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 

Because it uses a scriptblock, the variables referencing the event aren't processed until $Action is called after each event.

For permanent event monitors with string properties rather than scriptblocks, how do I use the event properties in the consumer?

I'm hoping to call a PowerShell script using CommandLineEventConsumer and pass it the file name that triggered the event. For example:

$FilterArgs = @{
   ClassName    = '__EventFilter'
   NameSpace    = 'root\subscription'
   ErrorAction  = 'Stop'
   Property     = @{
      Name           = 'PDFCreatedFilter'
      EventNamespace = 'root\CIMV2'
      QueryLanguage  = 'WQL'
      Query          = $WQLQuery
   }
}
$FilterInstance = New-CimInstance @FilterArgs

$ConsumerArgs = @{
   ClassName    = 'CommandLineEventConsumer'
   NameSpace    = 'root\subscription'
   ErrorAction  = 'Stop'
   KillTimeout    = 10
   Property     = @{
      Name           = 'FileCreatedConsumer'
      EventNamespace = 'root\CIMV2'
      ExecutablePath = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
      CommandLineTemplate  = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe ' +
                              '-ExecutionPolicy bypass -NoProfile -file "$MyScriptPath" ' +
                              "-Name `"$($EventArgs.NewEvent.TargetInstance.Name)`" -Printer $MyPrinterName"
   }
}

$ConsumerInstance = New-CimInstance @ConsumerArgs

However, that $EventArgs.NewEvent.TargetInstance.Name will not be defined at the time I create the consumer.

If an ActiveScriptEventConsumer using the ScriptText parameter is the only way to do this, I can probably stumble through a VBscript, but I still would need the syntax to get it to work.

Thanks.

0 Answers
Related