在后台运行Powershell功能/任务

时间:2009-11-07 01:38:33

标签: windows powershell background

我有一个函数可以让我根据您的输入将文件的文件路径写入文本文件。这听起来令人困惑,但我不知道更好的方式,所以这是功能:

Function writeAllPaths([string]$fromFolder,[string]$filter,[string]$printfile) {
    Get-ChildItem -Path $fromFolder -Recurse $filter | Select-Object -Property FullName > $printfile
}

第一个参数是您开始搜索的文件夹。
第二个参数,过滤器。 * .zip例如,将列出所有zip文件。 第三个参数,你必须提供文本文件的最终位置。

示例用法:writeAllPaths c:\ *.zip c:\allZips.txt

问题是,当我这样做时,Powershell将不会接受命令,直到它完成。这不是很有成效。有没有办法在启动时在后台运行。最好在完成后给出一些消息。我可以打开在进程中间创建的任何文件......

另外,我在Windows 7上,所以我猜我有Powershell 2.0

是的,我不确定:p

编辑:

我按照建议使用Start-Job,如下所示:

Function writeAllPaths([string]$fromFolder,[string]$filter,[string]$printfile) {
  Start-Job -ScriptBlock {Get-ChildItem -Path $fromFolder -Recurse $filter | Select-Object -Property FullName > $printfile}
}

但是,不会创建该文件。旧函数会创建一个文件。

EDIT2:最好在我的Powershell配置文件中使用此功能。这样,我可以随时执行它,而不是每次启动Powershell时都必须加载特定的ps1文件。

可以找到有关Powershell个人资料的更多信息here 您可以输入以下内容来召唤自己的个人资料:notepad $profile

2 个答案:

答案 0 :(得分:6)

在为后台作业创建的新范围中,未定义为您定义的参数WriteAllPaths函数。试试这个,你会发现它们不是:

Function writeAllPaths([string]$fromFolder,[string]$filter,[string]$printfile) 
{    
    Start-Job { "$fromFolder, $filter, $printFile" }
}

$job = WriteAllPaths .\Downloads *.zip zips.txt
Wait-Job $job
Receive-Job $job

, ,

请改为尝试:

Function writeAllPaths([string]$fromFolder, [string]$filter, [string]$printfile) 
{    
    Start-Job {param($fromFolder,$filter,$printfile) 
               "$fromFolder, $filter, $printfile" } `
               -ArgumentList $fromFolder,$filter,$printfile
}

$job = WriteAllPaths .\Downloads *.zip z.txt
Wait-Job $job
Receive-Job $job

.\Downloads, *.zip, z.txt

现在您看到了输出,因为我们通过-ArgumentList将参数传递给了scriptblock。我建议的是一个可以选择使用后台作业的功能。只需在您的个人资料中添加此功能定义即可设置:

function WriteAllPaths([string]$FromFolder, [string]$Filter, 
                       [string]$Printfile, [switch]$AsJob) 
{
    if (![IO.Path]::IsPathRooted($FromFolder)) {
        $FromFolder = Join-Path $Pwd $FromFolder
    }
    if (![IO.Path]::IsPathRooted($PrintFile)) {
        $PrintFile = Join-Path $Pwd $PrintFile
    }

    $sb = {
        param($FromFolder, $Filter, $Printfile)
        Get-ChildItem $FromFolder -r $filter | Select FullName > $PrintFile
    }

    if ($AsJob) {
        Start-Job $sb -ArgumentList $FromFolder,$Filter,$PrintFile
    }
    else {
        & $sb $FromFolder $Filter $PrintFile        
    }
}

像这样测试功能(同步):

$job = WriteAllPaths Downloads *.zip z.txt -AsJob
Wait-Job $job
Receive-Job $job

请注意,我正在测试路径是否为root,如果不是,我正在预先设置当前目录。我这样做是因为后台作业的起始目录并不总是与你执行Start-Job的地方相同。

答案 1 :(得分:2)

哪个版本的powershell?在Powershell 2.0中,我认为您可以使用后台作业Start-Job

  

启动Windows PowerShell后台作业。