Skip to content

Commit

Permalink
Added Invoke-Process
Browse files Browse the repository at this point in the history
  • Loading branch information
adbertram committed Oct 18, 2017
1 parent 4b7c55b commit be2a5ca
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 12 deletions.
29 changes: 17 additions & 12 deletions File-Folder Management/FileMonitor.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -48,30 +48,35 @@ function New-FileMonitor {
param (
[Parameter(Mandatory)]
[string]$Name,

[Parameter(Mandatory)]
[string]$MonitorInterval,

[Parameter(Mandatory)]
[string]$FolderPath,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Modification', 'Creation')]
[string]$EventType,

[Parameter(Mandatory)]
[ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })]
[ValidatePattern('.*\.ps1')]
[string]$ScriptFilePath,

[ValidatePattern('.*\.vbs')]
[string]$VbsScriptFilePath = "$($env:TEMP)\FileMonitor.vbs"
)
process {
try {
## Break apart the drive and path to meet WMI specs
$Drive = $FolderPath | Split-Path -Qualifier
$FolderPath = "$($FolderPath | Split-Path -NoQualifier)\".Replace('\', '\\')

## Create the event query to monitor only the folder we want. Also, set the monitor interval
## to something like 10 seconds to check the folder every 10 seconds.
$WmiEventFilterQuery = "
SELECT * FROM __InstanceCreationEvent WITHIN $MonitorInterval
WHERE targetInstance ISA 'CIM_DataFile'
AND targetInstance.Drive = `"$Drive`"
AND targetInstance.Path = `"$FolderPath`""
$WmiEventFilterQuery = @'
SELECT * FROM __Instance{0}Event WITHIN {1}
WHERE targetInstance ISA 'CIM_DirectoryContainsFile'
and TargetInstance.GroupComponent = 'Win32_Directory.Name="{2}"'
'@ -f $EventType, $MonitorInterval, ($FolderPath -replace '\\+$').Replace('\', '\\')

## Subscribe to the WMI event using the WMI filter query created above
$WmiFilterParams = @{
Expand All @@ -86,15 +91,15 @@ function New-FileMonitor {
## WMI events cannot auto-trigger another PowerShell script.
$VbsScript = "
Set objShell = CreateObject(`"Wscript.shell`")`r`n
objShell.run(`"powershell.exe -NoProfile -WindowStyle Hidden -executionpolicy bypass -file `"`"$ScriptFilePath`"`"`")
objShell.run(`"powershell.exe -NonInteractive -NoProfile -WindowStyle Hidden -executionpolicy bypass -file `"`"$ScriptFilePath`"`"`")
"
Set-Content -Path $VbsScriptFilePath -Value $VbsScript

## Create the WMI event consumer which will actually consume the event
$WmiConsumerParams = @{
'Class' = 'ActiveScriptEventConsumer'
'Namespace' = 'root\subscription'
'Arguments' = @{ Name = $Name; ScriptFileName = $VbsScriptFilePath; ScriptingEngine = 'VBscript' }
'Arguments' = @{ Name = $Name; ScriptFileName = $VbsScriptFilePath; ScriptingEngine = 'VBScript' }
}
Write-Verbose -Message "Creating WMI consumer using script file name $VbsScriptFilePath"
$WmiConsumer = Set-WmiInstance @WmiConsumerParams
Expand Down Expand Up @@ -138,7 +143,7 @@ function Get-FileMonitor {
$Monitor.Binding = Get-WmiObject @BindingParams
$Monitor.Filter = Get-WmiObject @FilterParams
$Monitor.Consumer = Get-WmiObject @ConsumerParams
if (@($Monitor.Values | where { $_ }).Count -eq $Monitor.Keys.Count) {
if ($Monitor.Consumer -and $Monitor.Filter) {
[pscustomobject]$Monitor
} elseif (-not $Monitor.Consumer -and -not $Monitor.Filter) {
$null
Expand Down
46 changes: 46 additions & 0 deletions Processes/Invoke-Process.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
function Invoke-Process {
[CmdletBinding(SupportsShouldProcess)]
param
(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,

[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$ArgumentList
)

$ErrorActionPreference = 'Stop'

try {
$stdOutTempFile = "$env:TEMP\$((New-Guid).Guid)"
$stdErrTempFile = "$env:TEMP\$((New-Guid).Guid)"

$startProcessParams = @{
FilePath = $FilePath
ArgumentList = $ArgumentList
RedirectStandardError = $stdErrTempFile.FullName
RedirectStandardOutput = $stdOutTempFile.FullName
Wait = $true;
PassThru = $true;
NoNewWindow = $true;
}
if ($PSCmdlet.ShouldProcess("Process [$($FilePath)]", "Run with args: [$($ArgumentList)]")) {
$cmd = Start-Process @startProcessParams
$cmdOutput = Get-Content -Path $stdOutTempFile.FullName -Raw
$cmdError = Get-Content -Path $stdErrTempFile.FullName -Raw
if ([string]::IsNullOrEmpty($cmdOutput) -eq $false) {
Write-Output -InputObject $cmdOutput
}
if ($cmd.ExitCode -ne 0) {
throw $cmdError.Trim()
}
}
} catch {
$PSCmdlet.ThrowTerminatingError($_)
} finally {
Remove-Item -Path $stdOutTempFile.FullName, $stdErrTempFile.FullName -Force
$ErrorActionPreference = 'Continue'
}
}

0 comments on commit be2a5ca

Please sign in to comment.