How to pass a simple string variable in place of a literal dot notation value?

111 views Asked by At

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.

2

There are 2 answers

2
mklement0 On BEST ANSWER
  • 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.

    • For security reasons, 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/
1
jerdub1993 On

You can loop through the items, check if the link property is a string, and if it isn't you can then loop through the link items and return each of them:

PS > $nested = Invoke-RestMethod https://gurneyjourney.blogspot.com/feeds/posts/default | Select-Object title, link
PS > $notNested = Invoke-RestMethod https://hacks.mozilla.org/feed | Select-Object title, link
PS > $fullList = $nested + $notNested
PS > foreach ($item in $fullList){
    if ($item.link -is [string]){
        $item
    } else {
        foreach ($link in $item.link){
            $link.link | Select-Object title, @{
                Name = 'link'
                Expression = { $_.href }
            }
        }
    }
}

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/
Introducing llamafile                                                      https://hacks.mozilla.org/2023/11/introducing-llamafile/
Mozilla AI Guide Launch with Summarization Code Example                    https://hacks.mozilla.org/2023/11/mozilla-ai-guide-launch-with-summarization-code-example/
Down and to the Right: Firefox Got Faster for Real Users in 2023           https://hacks.mozilla.org/2023/10/down-and-to-the-right-firefox-got-faster-for-real-users-in-2023/
Built for Privacy: Partnering to Deploy Oblivious HTTP and Prio in Firefox https://hacks.mozilla.org/2023/10/built-for-privacy-partnering-to-deploy-oblivious-http-and-prio-in-firefox/
Faster Vue.js Execution in Firefox                                         https://hacks.mozilla.org/2023/09/faster-vue-js-execution-in-firefox/
Autogenerating Rust-JS bindings with UniFFI                                https://hacks.mozilla.org/2023/08/autogenerating-rust-js-bindings-with-uniffi/
So you want to build your own open source ChatGPT-style chatbot…           https://hacks.mozilla.org/2023/07/so-you-want-to-build-your-own-open-source-chatbot/
Letting users block injected third-party DLLs in Firefox                   https://hacks.mozilla.org/2023/03/letting-users-block-injected-third-party-dlls-in-firefox/
Mozilla Launches Responsible AI Challenge                                  https://hacks.mozilla.org/2023/03/mozilla-launches-responsible-ai-challenge/
Announcing Interop 2023                                                    https://hacks.mozilla.org/2023/02/announcing-interop-2023/
Interop 2022: Outcomes                                                     https://hacks.mozilla.org/2023/01/interop-2022-outcomes/
How the Mozilla Community helps shape our products                         https://hacks.mozilla.org/2022/12/how-the-mozilla-community-helps-to-shape-our-products/
Improving Firefox stability with this one weird trick                      https://hacks.mozilla.org/2022/11/improving-firefox-stability-with-this-one-weird-trick/
Revamp of MDN Web Docs Contribution Docs                                   https://hacks.mozilla.org/2022/10/revamp-of-mdn-web-docs-contribution-docs/
Improving Firefox responsiveness on macOS                                  https://hacks.mozilla.org/2022/10/improving-firefox-responsiveness-on-macos/
The 100% Markdown Expedition                                               https://hacks.mozilla.org/2022/09/the-100-percent-markdown-expedition/
Merging two GitHub repositories without losing commit history              https://hacks.mozilla.org/2022/08/merging-two-github-repositories-without-losing-commit-history/
Neural Machine Translation Engine for Firefox Translations add-on          https://hacks.mozilla.org/2022/06/neural-machine-translation-engine-for-firefox-translations-add-on/