Кажется, что переменные не работают внутри функции в PowerShell - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть функция ведения журнала в моем скрипте, однако, когда я вызываю функцию, она, кажется, работает правильно, за исключением фактической части ведения журнала. Это хорошо отражается на экране, но когда я go проверю файл журнала, он не обновляется. Ниже приведен код.

Function Get-Logger { 
    param(
       [Parameter(Mandatory=$true)]
       [String]$message,
       [Parameter(Mandatory=$false)]
       [validatescript({[enum]::getvalues([system.consolecolor]) -contains $_})][string]$Color
    )

    ### Function Variables ###
    $Log = $MyInvocation.MyCommand.ToString().Replace(".ps1",".log")
    $LogPath = "C:\Source\Scripts\ScriptLog" 
    $LogFile = "$LogPath\$Log" 
    $TimeStamp = Get-Date -Format "MM-dd-yyy hh:mm:ss"

    #Creates the ScriptLog folder in C:\Source\Scripts if it doesn't exist
    IF(-not(Test-Path $LogPath)) {
        New-Item -ItemType Directory -Path $LogPath
        Get-Logger "Created ScriptLog Directory"
    } 

    Write-Host $TimeStamp -NoNewline
    IF ($Color) {
        Write-Host `t $message -ForegroundColor $($color)
    } Else {
        Write-Host `t $message -ForegroundColor Cyan
        }       

    $logMessage = "[$TimeStamp]  $message"
    $logMessage | Out-File -Append -LiteralPath $LogFile


}

Переменные используются только внутри функции, если я помещаю переменные вне функции, с которой она работает, но я хочу попытаться сохранить переменные внутри самой функции.

Я также пытался добавить области действия $global:, $script:, $local:, et c .. и, похоже, ничего из этого не работает. Можно ли на самом деле оставить переменные внутри функции, или мне нужно разместить их вне функции?

1 Ответ

2 голосов
/ 14 апреля 2020

Локальные переменные всегда видны в одной и той же области (и во всех потомках, если они не созданы с помощью спецификатора области $private:), поэтому они не являются проблемой.

Однако, выглядит как ваше намерение состоит в том, чтобы основать значение переменной $Log на уровне сценария определения $MyInvocation, а не на функции (которая отражает, как функция был вызван).

Ссылка на определение сценария *1016* $MyInvocation - из которого можно получить имя файла сценария , как и предполагалось - используйте спецификатор области действия $script::

$Log = $script:MyInvocation.MyCommand.ToString().Replace(".ps1",".log")

Проще говоря, вы можете использовать automati c $PSCommandPath переменную , которая содержит полный путь к файлу сценария, даже внутренние функции:

$Log = [IO.Path]::GetFileNameWithoutExtension($PSCommandPath) + '.log'

В PowerShell [Core] 6+ вы также можете использовать Split-Path -LeafBase (не поддерживается в Windows PowerShell):

$Log = (Split-Path -LeafBase $PSCommandPath) + '.log'

Наконец, для ради полноты, собственная переменная $MyInvocation функции имеет свойство .PSCommandPath , которое тоже отражает полный путь к скрипту:

$Log = (Split-Path -LeafBase $MyInvocation.PSCommandPath) + '.log'
...