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

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: и т. Д. И ничего из этого, похоже, не работает. Возможно ли, чтобы переменные оставались внутри функции, или мне нужно разместить их вне функции?

0
Fitzgery 14 Апр 2020 в 18:06

1 ответ

Лучший ответ

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

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

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

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

Однако проще использовать автоматическая $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'
2
mklement0 14 Апр 2020 в 16:56