简体   繁体   中英

Variables don't seem to be working inside of the function in PowerShell

I have a logging function in my script however when I call the function it seems to work properly except for the actual logging portion. It echos to the screen just fine, but when I go to check the log file it doesn't update. Below is the code.

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


}

The variables are only used within the function, if I place the variables outside of the function it works, but I want to try and keep the variables within the function itself.

I've tried adding scopes as well $global: , $script: , $local: , etc.. and none of that seems to work. Is it possible to actually have the variables stay within the function, or do I have to place them outside the function?

Local variables are always visible in the same scope (and all descendant scopes, unless created with the $private: scope specifier), so they aren't the problem.

However, it looks like your intent is to base the $Log variable value on the script-level definition of $MyInvocation , not the function's (which reflects how the function was invoked).

To refer to the script 's definition of $MyInvocation - from which you can derive the script file name as intended - use the $script: scope specifier:

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

More simply, however, you can use the automatic $PSCommandPath variable , which contains the script's full file path, even inside functions:

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

In PowerShell [Core] 6+, you can alternatively use Split-Path -LeafBase (not supported in Windows PowerShell):

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

Finally, for the sake of completeness, the function's own $MyInvocation variable has a .PSCommandPath property that too reflects the full script path:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM