变量似乎在 PowerShell 的函数内部不起作用
Variables don't seem to be working inside of the function in PowerShell
我的脚本中有一个日志记录函数,但是当我调用该函数时,除了实际的日志记录部分外,它似乎工作正常。它很好地回显到屏幕上,但是当我去检查日志文件时它没有更新。下面是代码。
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:
等。其中 none 似乎有效。是否可以将变量实际保留在函数内,还是必须将它们放在函数外?
局部变量在同一范围内始终可见(以及所有后代范围,除非使用 $private:
范围说明符创建),因此它们不是问题。
但是,您的意图似乎是将 $Log
变量值基于 $MyInvocation
的 脚本级 定义,而不是函数的(它反映了函数是如何被调用的)。
参考脚本对$MyInvocation
的定义——您可以从中导出脚本文件名预期 - 使用 $script:
范围说明符:
$Log = $script:MyInvocation.MyCommand.ToString().Replace(".ps1",".log")
然而,更简单的是,您可以使用 automatic $PSCommandPath
variable,它包含脚本的完整文件路径,甚至在函数内部:
$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'
我的脚本中有一个日志记录函数,但是当我调用该函数时,除了实际的日志记录部分外,它似乎工作正常。它很好地回显到屏幕上,但是当我去检查日志文件时它没有更新。下面是代码。
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:
等。其中 none 似乎有效。是否可以将变量实际保留在函数内,还是必须将它们放在函数外?
局部变量在同一范围内始终可见(以及所有后代范围,除非使用 $private:
范围说明符创建),因此它们不是问题。
但是,您的意图似乎是将 $Log
变量值基于 $MyInvocation
的 脚本级 定义,而不是函数的(它反映了函数是如何被调用的)。
参考脚本对$MyInvocation
的定义——您可以从中导出脚本文件名预期 - 使用 $script:
范围说明符:
$Log = $script:MyInvocation.MyCommand.ToString().Replace(".ps1",".log")
然而,更简单的是,您可以使用 automatic $PSCommandPath
variable,它包含脚本的完整文件路径,甚至在函数内部:
$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'