Skip to content

Commit be2a5ca

Browse files
committedOct 18, 2017
Added Invoke-Process
1 parent 4b7c55b commit be2a5ca

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed
 

‎File-Folder Management/FileMonitor.psm1

+17-12
Original file line numberDiff line numberDiff line change
@@ -48,30 +48,35 @@ function New-FileMonitor {
4848
param (
4949
[Parameter(Mandatory)]
5050
[string]$Name,
51+
5152
[Parameter(Mandatory)]
5253
[string]$MonitorInterval,
54+
5355
[Parameter(Mandatory)]
5456
[string]$FolderPath,
57+
58+
[Parameter(Mandatory)]
59+
[ValidateNotNullOrEmpty()]
60+
[ValidateSet('Modification', 'Creation')]
61+
[string]$EventType,
62+
5563
[Parameter(Mandatory)]
5664
[ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })]
5765
[ValidatePattern('.*\.ps1')]
5866
[string]$ScriptFilePath,
67+
5968
[ValidatePattern('.*\.vbs')]
6069
[string]$VbsScriptFilePath = "$($env:TEMP)\FileMonitor.vbs"
6170
)
6271
process {
6372
try {
64-
## Break apart the drive and path to meet WMI specs
65-
$Drive = $FolderPath | Split-Path -Qualifier
66-
$FolderPath = "$($FolderPath | Split-Path -NoQualifier)\".Replace('\', '\\')
67-
6873
## Create the event query to monitor only the folder we want. Also, set the monitor interval
6974
## to something like 10 seconds to check the folder every 10 seconds.
70-
$WmiEventFilterQuery = "
71-
SELECT * FROM __InstanceCreationEvent WITHIN $MonitorInterval
72-
WHERE targetInstance ISA 'CIM_DataFile'
73-
AND targetInstance.Drive = `"$Drive`"
74-
AND targetInstance.Path = `"$FolderPath`""
75+
$WmiEventFilterQuery = @'
76+
SELECT * FROM __Instance{0}Event WITHIN {1}
77+
WHERE targetInstance ISA 'CIM_DirectoryContainsFile'
78+
and TargetInstance.GroupComponent = 'Win32_Directory.Name="{2}"'
79+
'@ -f $EventType, $MonitorInterval, ($FolderPath -replace '\\+$').Replace('\', '\\')
7580

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

9398
## Create the WMI event consumer which will actually consume the event
9499
$WmiConsumerParams = @{
95100
'Class' = 'ActiveScriptEventConsumer'
96101
'Namespace' = 'root\subscription'
97-
'Arguments' = @{ Name = $Name; ScriptFileName = $VbsScriptFilePath; ScriptingEngine = 'VBscript' }
102+
'Arguments' = @{ Name = $Name; ScriptFileName = $VbsScriptFilePath; ScriptingEngine = 'VBScript' }
98103
}
99104
Write-Verbose -Message "Creating WMI consumer using script file name $VbsScriptFilePath"
100105
$WmiConsumer = Set-WmiInstance @WmiConsumerParams
@@ -138,7 +143,7 @@ function Get-FileMonitor {
138143
$Monitor.Binding = Get-WmiObject @BindingParams
139144
$Monitor.Filter = Get-WmiObject @FilterParams
140145
$Monitor.Consumer = Get-WmiObject @ConsumerParams
141-
if (@($Monitor.Values | where { $_ }).Count -eq $Monitor.Keys.Count) {
146+
if ($Monitor.Consumer -and $Monitor.Filter) {
142147
[pscustomobject]$Monitor
143148
} elseif (-not $Monitor.Consumer -and -not $Monitor.Filter) {
144149
$null

‎Processes/Invoke-Process.ps1

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
function Invoke-Process {
2+
[CmdletBinding(SupportsShouldProcess)]
3+
param
4+
(
5+
[Parameter(Mandatory)]
6+
[ValidateNotNullOrEmpty()]
7+
[string]$FilePath,
8+
9+
[Parameter()]
10+
[ValidateNotNullOrEmpty()]
11+
[string]$ArgumentList
12+
)
13+
14+
$ErrorActionPreference = 'Stop'
15+
16+
try {
17+
$stdOutTempFile = "$env:TEMP\$((New-Guid).Guid)"
18+
$stdErrTempFile = "$env:TEMP\$((New-Guid).Guid)"
19+
20+
$startProcessParams = @{
21+
FilePath = $FilePath
22+
ArgumentList = $ArgumentList
23+
RedirectStandardError = $stdErrTempFile.FullName
24+
RedirectStandardOutput = $stdOutTempFile.FullName
25+
Wait = $true;
26+
PassThru = $true;
27+
NoNewWindow = $true;
28+
}
29+
if ($PSCmdlet.ShouldProcess("Process [$($FilePath)]", "Run with args: [$($ArgumentList)]")) {
30+
$cmd = Start-Process @startProcessParams
31+
$cmdOutput = Get-Content -Path $stdOutTempFile.FullName -Raw
32+
$cmdError = Get-Content -Path $stdErrTempFile.FullName -Raw
33+
if ([string]::IsNullOrEmpty($cmdOutput) -eq $false) {
34+
Write-Output -InputObject $cmdOutput
35+
}
36+
if ($cmd.ExitCode -ne 0) {
37+
throw $cmdError.Trim()
38+
}
39+
}
40+
} catch {
41+
$PSCmdlet.ThrowTerminatingError($_)
42+
} finally {
43+
Remove-Item -Path $stdOutTempFile.FullName, $stdErrTempFile.FullName -Force
44+
$ErrorActionPreference = 'Continue'
45+
}
46+
}

0 commit comments

Comments
 (0)
Please sign in to comment.