Powershell - 如何在后台批量运行监控文件夹脚本?

时间:2018-03-29 08:26:42

标签: powershell process monitor

我编写了一个PowerShell脚本,用于监视特定文件夹的更改,例如:创建/删除/重命名项目。

然后它将所有这些操作写入日志文件。它工作正常。唯一的问题是,它仅在控制台打开时才有效。

每当我尝试使用批处理文件运行它时,它似乎不起作用(写入日志文件)。我正在尝试将其作为后台进程运行。

这是监控功能:

function CreateMonitor($folder)
{    
    $folder = 'C:\Users\...\Monitored Folder\' # Enter the root path you want to monitor. 
    $filter = '*.*'  # You can enter a wildcard filter here.          

    $fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

    Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
    $name = $Event.SourceEventArgs.Name 
    $changeType = $Event.SourceEventArgs.ChangeType 
    $timeStamp = $Event.TimeGenerated 
    Write-Host "The file '$name' was $changeType at $timeStamp" -fore green 
    Out-File -FilePath C:\Users\...\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"}                 
}

这是批处理文件内容:

powershell.exe -windowstyle hidden -file C:\Users\....ps1

如何让它在后台运行/作为一个过程?

2 个答案:

答案 0 :(得分:0)

根据评论,Write-Host语句可能会破坏您的脚本,因为它会尝试将输出写入控制台,当您运行没有窗口的脚本时,没有可写入的控制台。

最佳做法是将其更改为Write-Verbose,然后将[cmdletbinding()]添加到您的函数中。然后,如果/当您想要查看该语句时,可以使用-Verbose开关调用您的函数:

function CreateMonitor
{    
    [cmdletbinding()]
    Param(
        $folder = 'C:\Users\...\Monitored Folder\',
        $filter = '*.*'
    )

    $fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

    Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
    $name = $Event.SourceEventArgs.Name 
    $changeType = $Event.SourceEventArgs.ChangeType 
    $timeStamp = $Event.TimeGenerated 
    Write-Verbose "The file '$name' was $changeType at $timeStamp" -fore green 
    Out-File -FilePath C:\Users\...\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"}                 
}

您需要Param()阻止使用[cmdletbinding()],因此我已将$folder参数移至此处。我也在这里设置了它的默认值,就像你在原始函数中一样,它是覆盖它的(如果它是通过参数设置的)。在我看来,将$filter作为参数也是有意义的。

如果您现在想要查看详细输出,只需通过以下方式调用您的函数:

CreateMonitor -Verbose

当然在后台运行时你不会使用这个开关,因为没有地方可以看到输出。

有关为何通常不鼓励使用Write-Host的详细信息,请参阅PowerShell创建者发布的这篇博文:http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/

答案 1 :(得分:0)

作为猜测,我假设您的文件看起来像

function CreateMonitor { ... }
CreateMonitor

如果是这种情况,那么它就会失败,因为一旦ps1文件执行它然后退出并退出,因为不需要进一步的命令。

如果你添加

while ($true) {} # alternately add Start-Sleep -s 1

然后ps1文件将继续运行,并且在成功创建filewatcher的那一刻不会退出。