PowerShell和全局功能

时间:2013-10-09 16:14:07

标签: function powershell global

为什么以下代码不起作用?根据这篇文章,全局的用法应该是正确的: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

3 个答案:

答案 0 :(得分:1)

来自Start-Job的文档:

  

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

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

Trivial Solution:定义scriptblock中的函数。

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

或者,请检查以下相关问题:

Powershell: passing parameters to a job

Variables in Start-Job

答案 1 :(得分:1)

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

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

其中$pid是当前PowerShell的进程ID。

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

-ArgumentList

答案 2 :(得分: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