使用 Test-Path 在哈希表中查找值项
Using Test-Path to find value item in hashtable
我最近开始使用 Set-StrictMode
来学习更好的脚本编写习惯(即声明变量等),我 运行 遇到了一个小问题。对于我的大多数脚本,我将创建一个哈希表 $Script = @{}
,然后将脚本中使用的所有变量声明为该哈希表下的子属性,因为无论如何,当您启动脚本时,所有变量都将是干净的,如果您打印输出脚本末尾的所有变量,您知道它们将来自该特定会话。
从历史上看,如果我需要查看是否声明了诸如 $Script.RunOnce
之类的子变量,我只会使用 If ($Script.RunOnce) {}
但在严格模式下,您必须按照 If (Test-Path Variable:\Script.WriteOnce) {}
除了 test-path 将 "Script.WriteOnce" 视为自己的变量,而不是 $Script
下的子变量
您可能会问为什么我需要这样做?好吧,我正在编写一个使用 .Net Streamwriter 的函数,我想确保如果变量“$WriteTee.StreamWriter”存在 运行,那么在声明之前 $WriteTee.StreamWriter.Close
和 $WriteTee.StreamWriter.Flush
再次 $Write-Tee
否则当我尝试打开一个新的 streamwriter 时它会出错,我必须手动关闭文件上的 .net 句柄才能继续测试脚本。
长话短说
有没有一种方法可以使用 Test-Path
或其他不会在 Set-Strictmode
中产生错误的方法来测试 $WriteTee.StreamWriter
我的脚本的超级内脏示例版本。
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Inquire'
Function Write-Tee {
Begin {
#Variables that are needed only the first time the log function is started.
If ($WriteTee.RunOnce) {
If ($WriteTee.StreamWriter) { Write-Tee -Severity Error -Message "Log Writer Already Open. Attempting to close." -Close}
New-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee -Value @{} -Scope Script
$Script:WriteTee.RunOnce = $True
}
}#End-Begin
Process {}#End-Process
End {
If ($Close -AND $Script:WriteTee) {
Write-Tee -Severity Info -Message "Flushing Log Writer and closing."
$WriteTee.StreamWriter.Flush()
$WriteTee.StreamWriter.Close()
Remove-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee -Scope Script
Remove-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee
}#End-If
}#End-End
}
Write-Tee -Message "Test" -Severity "Warning"
您可以使用带有变量提供者和变量名称的测试路径来查明是否已将变量分配给,但是查找变量的属性(或哈希表中的项目,不清楚您正在处理)需要其他策略:
要查明哈希表是否有带键的项目,您可以执行以下操作:
$writeTee.ContainsKey('StreamWriter') #returns $true or $false
要查明一个变量是否有特定的 属性,您可以使用 get-member:
$writeTee | Get-Member -name StreamWriter #returns the member or nothing
我最近开始使用 Set-StrictMode
来学习更好的脚本编写习惯(即声明变量等),我 运行 遇到了一个小问题。对于我的大多数脚本,我将创建一个哈希表 $Script = @{}
,然后将脚本中使用的所有变量声明为该哈希表下的子属性,因为无论如何,当您启动脚本时,所有变量都将是干净的,如果您打印输出脚本末尾的所有变量,您知道它们将来自该特定会话。
从历史上看,如果我需要查看是否声明了诸如 $Script.RunOnce
之类的子变量,我只会使用 If ($Script.RunOnce) {}
但在严格模式下,您必须按照 If (Test-Path Variable:\Script.WriteOnce) {}
除了 test-path 将 "Script.WriteOnce" 视为自己的变量,而不是 $Script
您可能会问为什么我需要这样做?好吧,我正在编写一个使用 .Net Streamwriter 的函数,我想确保如果变量“$WriteTee.StreamWriter”存在 运行,那么在声明之前 $WriteTee.StreamWriter.Close
和 $WriteTee.StreamWriter.Flush
再次 $Write-Tee
否则当我尝试打开一个新的 streamwriter 时它会出错,我必须手动关闭文件上的 .net 句柄才能继续测试脚本。
长话短说
有没有一种方法可以使用 Test-Path
或其他不会在 Set-Strictmode
$WriteTee.StreamWriter
我的脚本的超级内脏示例版本。
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Inquire'
Function Write-Tee {
Begin {
#Variables that are needed only the first time the log function is started.
If ($WriteTee.RunOnce) {
If ($WriteTee.StreamWriter) { Write-Tee -Severity Error -Message "Log Writer Already Open. Attempting to close." -Close}
New-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee -Value @{} -Scope Script
$Script:WriteTee.RunOnce = $True
}
}#End-Begin
Process {}#End-Process
End {
If ($Close -AND $Script:WriteTee) {
Write-Tee -Severity Info -Message "Flushing Log Writer and closing."
$WriteTee.StreamWriter.Flush()
$WriteTee.StreamWriter.Close()
Remove-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee -Scope Script
Remove-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee
}#End-If
}#End-End
}
Write-Tee -Message "Test" -Severity "Warning"
您可以使用带有变量提供者和变量名称的测试路径来查明是否已将变量分配给,但是查找变量的属性(或哈希表中的项目,不清楚您正在处理)需要其他策略: 要查明哈希表是否有带键的项目,您可以执行以下操作:
$writeTee.ContainsKey('StreamWriter') #returns $true or $false
要查明一个变量是否有特定的 属性,您可以使用 get-member:
$writeTee | Get-Member -name StreamWriter #returns the member or nothing