2013-10-09 4 views
3

Почему следующий код не работает? Согласно этой статье, использование глобальной должно быть правильным: http://technet.microsoft.com/en-us/library/ff730957.aspxPowerShell и глобальные функции

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 
+0

ли ваш '$ {темп WriteLog ...}' существует для чего-нибудь, кроме передачи аргументов? Вместо этого передайте аргументы непосредственно из «Start-Job» в функцию, используя параметр «ArgumentList», пропуская среднего человека. –

ответ

1

работы PowerShell фактически выполняется в отдельном процессе PowerShell. Вы можете увидеть это так:

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

Где $pid это идентификатор процесса текущего PowerShell в.

Все, что должно быть доступно из сценария, выполняющегося в задании, должно быть либо определено в скриптблоке, переданном в Start-Job, т.е. в функции, определенном в блоке сценария, или как параметры, переданные в блок сценария, с использованием параметра -ArgumentList в Start-Job или сценарий может передать источник другому сценарию (или импортировать модуль), который содержит нужные ему функции. Лично я бы поставил общие функции в модуле, как Utils.psm1, а затем импортировать так:

Start-Job {param($scriptdir) Import-Module $scriptdir\Utils.psm1; ...} -Arg $PSScriptRoot 
1

Из документации Start-Job:

под управлением Windows PowerShell фоне задание запускает команду «в фоновом режиме» без взаимодействия с текущим сеансом.

Для этого текущая область сеанса игнорируется.

Тривиальное решение: Определите функцию внутри скриптового блока.

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

Кроме того, проверить эти вопросы, связанные с:

Powershell: passing parameters to a job

Variables in Start-Job

Смежные вопросы