3

为什么以下代码不起作用?根据这篇文章,全局的用法应该是正确的:http ://technet.microsoft.com/en-us/library/ff730957.aspx

Function global:writeLog {
    param($logType, $logString, $logFile)

    $fileStream = New-Object IO.FileStream $logFile ,'Append','Write','Read'
    $streamWriter = New-Object System.IO.StreamWriter $fileStream

    $time = get-date -Format "hh:mm:ss"
    $streamWriter.writeLine("[${time}][$logType] ${logString}")

    $streamWriter.close()

}

$temp = {
    writeLog -logType "INFO" -logString "Test" -logFile "d:\scripts\powershell\logtest.txt"
}

Start-Job -ScriptBlock $temp 
get-job | receive-job -AutoRemoveJob -Wait

这是powershell抛出的异常

The term 'writeLog' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, 
verify that the path is correct and try again.
    + CategoryInfo          : ObjectNotFound: (writeLog:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : localhost
4

3 回答 3

2

从以下文档Start-Job

Windows PowerShell 后台作业“在后台”运行命令,而不与当前会话交互。

因此,当前会话范围被忽略。

简单的解决方案:在脚本块内定义函数。

$JobScript = { 
    function write-log {
        ....
    }
    write-log <parameters>
}

或者,检查这些相关问题:

Powershell:将参数传递给作业

Start-Job 中的变量

于 2013-10-09T16:42:17.837 回答
1

PowerShell 作业实际上在单独的 PowerShell 进程中运行。你可以这样看:

$pid
Start-Job {$pid} | Receive-Job -Wait

$pid当前 PowerShell 的进程 ID 在哪里。

需要从作业中运行的脚本访问的任何内容都必须在传递给 Start-Job 的脚本块中定义,即在脚本块中定义的函数,或者作为使用-ArgumentListStart-Job 上的参数传递到脚本块的参数,或者该脚本可以点源另一个包含所需功能的脚本(或导入模块)。就个人而言,我会将共享函数放在像 Utils.psm1 这样的模块中,然后像这样导入:

Start-Job {param($scriptdir) Import-Module $scriptdir\Utils.psm1; ...} -Arg $PSScriptRoot
于 2013-10-09T16:51:46.727 回答
0

在脚本块中定义函数,然后使用

  1. 使用 NoNewScope 调用命令以使其在当前范围内
  2. InitializationScript 参数以使其进入作业
#Create Shared Functions Script Block
[scriptblock] $func = {function getPID() {write-output "Function Running in process id: $pid!"}}

#Set up functions in normal script scope so they're accessible here
Invoke-Command -NoNewScope -ScriptBlock $func

write-output "Main script started"

#run the function from the parent script
getPID

#Create background job script
$jobScript = {getPID}

#Run background job
write-output "starting background job"
Start-Job $jobScript -name "Job1" -InitializationScript $func

get-job | Receive-Job
get-job | Stop-Job
get-job | Remove-Job
于 2019-05-20T21:11:27.563 回答