如何用字符串变量替代PowerShell字面量点表示法取值?
动态访问PowerShell对象的嵌套属性(含索引)
你的问题核心在于:PowerShell的点符号仅支持直接访问简单属性名,无法解析包含索引(如[4])和多层嵌套的字符串路径。比如"link[4].href"这种字符串,直接用$feed.$link会被当作一个完整的属性名去查找,自然找不到对应值。
下面提供两种可靠的解决方法:
方法1:使用Invoke-Expression(适合可信输入场景)
如果你的CSV输入是可控、可信的,可以直接把属性路径拼成PowerShell表达式,用Invoke-Expression(简称iex)执行:
@' Url, link_nested "https://gurneyjourney.blogspot.com/feeds/posts/default",link[4].href "https://hacks.mozilla.org/feed",link '@ | ConvertFrom-Csv | ForEach-Object { # 处理默认值:如果link_nested是0或空,使用"link" $linkPath = if ($_.link_nested -eq '0' -or [string]::IsNullOrEmpty($_.link_nested)) { "link" } else { $_.link_nested } $feed = Invoke-RestMethod $_.Url -AllowInsecureRedirect # 用iex解析嵌套路径表达式 Invoke-Expression "`$feed.$linkPath" }
注意:
Invoke-Expression会执行任意字符串代码,若输入不可信(比如来自外部用户),存在安全风险,此时建议用方法2。
方法2:手动解析属性路径(安全通用)
写一个通用函数,递归解析包含嵌套属性和索引的路径字符串,完全避免执行未知代码:
function Get-NestedProperty { param( [Parameter(Mandatory)] [object]$InputObject, [Parameter(Mandatory)] [string]$PropertyPath ) $currentObj = $InputObject # 按.分割路径节点 $pathNodes = $PropertyPath -split '\.' foreach ($node in $pathNodes) { # 检查节点是否包含索引(如link[4]) if ($node -match '^(\w+)\[(\d+)\]$') { $propName = $matches[1] $index = [int]$matches[2] $currentObj = $currentObj.$propName[$index] } else { # 普通属性名 $currentObj = $currentObj.$node } # 如果中途找不到对象,提前返回null if ($null -eq $currentObj) { return $null } } return $currentObj } # 调用示例 @' Url, link_nested "https://gurneyjourney.blogspot.com/feeds/posts/default",link[4].href "https://hacks.mozilla.org/feed",link '@ | ConvertFrom-Csv | ForEach-Object { $linkPath = if ($_.link_nested -eq '0' -or [string]::IsNullOrEmpty($_.link_nested)) { "link" } else { $_.link_nested } $feed = Invoke-RestMethod $_.Url -AllowInsecureRedirect Get-NestedProperty -InputObject $feed -PropertyPath $linkPath }
为什么你的简单例子能运行?
你测试的$obj.$thisProperty能生效,是因为$thisProperty是简单属性名(比如"foo"),PowerShell的点符号可以直接识别。但一旦路径包含索引、嵌套层级,点符号就无法自动解析字符串里的语法结构了。
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

