I am dealing with a situation where some of the properties returned by invoke-restmethod
such as link
, are nested, this is based on the URI/Feed:
Invoke-RestMethod https://gurneyjourney.blogspot.com/feeds/posts/default |select-object title,link
title link
----- ----
title {link, link, link, link…}
title {link, link, link, link…}
...
...
and some are not:
Invoke-RestMethod https://hacks.mozilla.org/feed|select-object title, link
title link
----- ----
Puppeteer Support for the Cross-Browser WebDriver BiDi Standard https://hacks.mozilla.org/2023/12/puppeteer-webdriver-bidi/
Firefox Developer Edition and Beta: Try out Mozilla’s .deb package! https://hacks.mozilla.org/2023/11/firefox-developer-edition-and-beta-try-out-mozillas-deb-package/
...
...
I would like to handle each RSS feed/URI in a forEach-Object
loop and "un-nest" any nested properties and return objects that conform to the hacks.mozilla.org/
example. How I am thinking of doing this is:
#A small sample of a much larger CSV file
@'
Url, link_nested
"https://gurneyjourney.blogspot.com/feeds/posts/default",link[4].href
"https://hacks.mozilla.org/feed",0
'@
|convertfrom-csv| forEach-Object {
$link = $_.link_nested ? $_.link_nested : "link"
$feed = Invoke-RestMethod $_.url -AllowInsecureRedirect
$feed.$link # I also tried --> $feed.($link) ; $feed."$link" ; ($feed).$link ; $feed."$($link)"
}
The above does not work. I get no output. What I am doing is no different from the following (I think), which works fine:
$obj = [pscustomobject]@{foo = "foo" ; bar = "bar"}
$thisProperty = "foo"
$obj.$thisProperty
foo #output
At this point this is really not about the current task I am trying to solve but finding away to pass a dynamic string to dot notation, a capability I am in sore need of.
It has always been a flaky experience, it works sometimes and sometimes not.
I am hoping to conclude this affair. Cheers.
Indeed, PowerShell allows you to use the results of expressions, such as variable references, as property names.
Your own example demonstrates this:
$thisProperty = 'foo'
# -> 'foo val'
([pscustomobject]@{ foo='foo val'; bar='bar val' }).$thisProperty
However, the expression results cannot themselves be expressions, such as indexes and/or nested property accesses, e.g. [0]
or .link[4].ref
.
If you fully control the textual representations of such expressions (as in your case), you can use Invoke-Expression
to apply them, as if they had been literally specified in PowerShell source code.
Invoke-Expression
(iex
) is otherwise best avoided.Therefore, use the following - note how the link_nested
column in the CSV input data now specifies (nested) property-access expressions rather than mere names or index numbers:
@'
Url,link_nested
"https://gurneyjourney.blogspot.com/feeds/posts/default",.link[4].href
"https://hacks.mozilla.org/feed",[0].link
'@ |
ConvertFrom-Csv |
ForEach-Object {
$feed = Invoke-RestMethod $_.url -AllowInsecureRedirect
# Note the following, necessitated by the use of "...":
# ` before $feed to prevent its up-front expansion
# $(...) enclosure around $_.link_nested to embed its value
Invoke-Expression "`$feed$($_.link_nested)"
}
Note that an expandable (interpolating), double-quoted string ("..."
) is used as Invoke-Expression
's input:
Since the evaluation of $feed
should be delayed, its $
sigil is `
-escaped. That is, Invoke-Expression
itself should resolve this variable reference.
By contrast, the value of $_.link_nested
must be interpolated up front, so as to make it a literal part of the string to be evaluated by Invoke-Expression
as source code; because it is an expression rather than a mere variable reference, it requires enclosure in $(...)
, the subexpression operator
Output:
http://gurneyjourney.blogspot.com/2023/12/background-painting-with-ice-and-snow.html
https://hacks.mozilla.org/2023/12/puppeteer-webdriver-bidi/