【问题标题】:Powershell - How To Run A Monitoring Folder Script From A Batch In The Background?Powershell - 如何在后台批量运行监控文件夹脚本?
【发布时间】:2018-03-29 08:26:41
【问题描述】:

我编写了一个 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

如何让它在后台/作为进程运行?

【问题讨论】:

  • 不要使用写主机。

标签: powershell process monitor


【解决方案1】:

根据评论,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/

【讨论】:

  • 我已经删除了写主机部分。但行为似乎是相同的。没有变化。它仍然没有写入日志文件。
【解决方案2】:

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

function CreateMonitor { ... }
CreateMonitor

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

如果你添加

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

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

【讨论】:

    猜你喜欢
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 2012-10-20
    相关资源
    最近更新 更多