Below is my function present in file streamMonitor.ps1
.
function streamMonitor {
[cmdletbinding()]
param(
[string]$directoryPath,
[string]$scriptToRestartPath
)
while ($true) {
Write-Host "Monitoring directory: $directoryPath"
Write-Host "Script to restart: $scriptToRestartPath"
# Get the current time
$currentTime = Get-Date
# Get the latest creation time of any file in the directory
$latestCreationTime = Get-ChildItem -Path $directoryPath -Recurse |
Where-Object { !$_.PSIsContainer } |
Sort-Object CreationTime -Descending |
Select-Object -First 1 |
ForEach-Object { $_.CreationTime }
# Ensure $latestCreationTime is not $null
if ($null -eq $latestCreationTime) {
Write-Host "No files found in the directory."
return
}
# Check if the latest write time is within the last 30 seconds
$timeDifference = New-TimeSpan -Start $latestCreationTime -End $currentTime
if ($timeDifference.TotalSeconds -gt 30) {
# No changes in the last 30 seconds, restart the specified script
Write-Host "No changes detected within the last 30 seconds. Restarting script..."
Start-Process -FilePath "cmd.exe" -ArgumentList "/c `"$scriptToRestartPath`"" -NoNewWindow
} else {
Write-Host "Changes detected within the last 30 seconds. No action taken."
}
Start-Sleep -Seconds 30
continue
}
}
My streamMonitor function works fine, so I'm confused what the issue is.
A different file called invokingStream.ps1
, where I would like to call multiple instances of the function.
What do I need to change in order to get these jobs to run in parallel?
When I run this file, nothing happens, it just completes the process. However with the function it is calling, it should run indefinitely.
I am running PS 5.1
#Invoking Functions in Parallel
$job1 = Start-Job -ScriptBlock {
. C:\pathto\streamMonitor.ps1
streamMonitor -directoryPath "C:\pathto\stream1" -scriptToRestartPath "C:\pathto\stream1.bat"
}
$job2 = Start-Job -ScriptBlock {
. C:\pathto\streamMonitor.ps1
streamMonitor -directoryPath "C:\pathto\stream2" -scriptToRestartPath "C:\pathto\stream2.bat"
}
$job3 = Start-Job -ScriptBlock {
. C:\pathto\streamMonitor.ps1
streamMonitor -directoryPath "C:\pathto\stream3" -scriptToRestartPath "C:\pathto\stream3.bat"
}
Something you're missing in your code is blocking the thread that starts the jobs, otherwise, your script ends right after invoking them and in consequence the jobs also end. You can use Receive-Job -Wait
for this, it also allows you to get back the Write-Host
output to your main thread.
$streamMonitor = @(
@{
directoryPath = 'C:\pathto\stream2'
scriptToRestartPath = 'C:\pathto\stream2.bat'
}
@{
directoryPath = 'C:\pathto\stream3'
scriptToRestartPath = 'C:\pathto\stream3.bat'
}
@{
directoryPath = 'C:\pathto\stream1'
scriptToRestartPath = 'C:\pathto\stream1.bat'
}
)
$streamMonitor | ForEach-Object {
Start-Job {
. C:\pathto\streamMonitor.ps1
streamMonitor @using:_
}
} | Receive-Job -Wait -AutoRemoveJob