如何让PowerShell Hashtable的指定键每次调用时自动重建?
PowerShell哈希表动态更新值的解决方案
我常用PowerShell,在$Profile里定义了有序哈希表来存储常用数据,方便快速调用:
$SYS = [Ordered]@{ Posh = "C:\Program Files\PowerShell\7\pwsh.exe" ReflectLogs = Get-ChildItem -Path "C:\Users\All Users\Macrium\Reflect" -Filter *.html* ShareXUploadHistory = ConvertFrom-Json -InputObject (Get-Content -Path "C:\Users\...\Documents\Sharex\History.Json") }
但ShareXUploadHistory对应的History.Json文件会持续更新,目前每次调用$SYS.ShareXUploadHistory拿到的都是加载$Profile时的旧数据,无法获取文件的最新状态。我尝试过用脚本块执行的写法,但没有效果:
$SYS = [Ordered]@{ Posh = "C:\Program Files\PowerShell\7\pwsh.exe" ReflectLogs = Get-ChildItem -Path "C:\Users\All Users\Macrium\Reflect" -Filter *.html* ShareXUploadHistory = . {ConvertFrom-Json -InputObject (Get-Content -Path "C:\Users\...\Documents\Sharex\History.Json")} }
问题根源
哈希表的键值是静态值——不管直接执行命令还是用.执行脚本块,都是在定义哈希表的瞬间执行一次,把结果存入键中,后续调用不会重新执行逻辑。要实现每次调用都获取最新数据,需要用脚本块存储逻辑并在调用时执行。
解决方案
方法1:存储脚本块,调用时手动执行
将ShareXUploadHistory的值设为脚本块,每次调用时用&执行它来获取最新数据:
$SYS = [Ordered]@{ Posh = "C:\Program Files\PowerShell\7\pwsh.exe" ReflectLogs = Get-ChildItem -Path "C:\Users\All Users\Macrium\Reflect" -Filter *.html* ShareXUploadHistory = { ConvertFrom-Json -InputObject (Get-Content -Path "C:\Users\...\Documents\Sharex\History.Json") } } # 获取最新数据的调用方式 & $SYS.ShareXUploadHistory
方法2:用ScriptProperty实现自动动态更新(无需手动执行)
如果想保持$SYS.ShareXUploadHistory的直接调用方式,可通过Add-Member添加脚本属性(ScriptProperty),每次访问属性时自动执行逻辑:
# 先定义基础的PSCustomObject $SYS = [PSCustomObject]@{ Posh = "C:\Program Files\PowerShell\7\pwsh.exe" ReflectLogs = Get-ChildItem -Path "C:\Users\All Users\Macrium\Reflect" -Filter *.html* } # 添加动态属性 $SYS | Add-Member -MemberType ScriptProperty -Name ShareXUploadHistory -Value { # 简化写法:直接读取文件并转JSON Get-Content -Path "C:\Users\...\Documents\Sharex\History.Json" | ConvertFrom-Json }
这样每次直接调用$SYS.ShareXUploadHistory,都会自动读取最新的JSON文件内容。
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

