Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6026193
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T04:24:37+00:00 2026-05-23T04:24:37+00:00

One question for you is here ;) I have this function: function Set-DbFile {

  • 0

One question for you is here 😉

I have this function:

function Set-DbFile {
    param(
        [Parameter(ValueFromPipeline=$true)]
        [System.IO.FileInfo[]]
        $InputObject,
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [scriptblock]
        $Properties
    )
    process {
        $InputObject | % { 
            Write-Host `nInside. Storing $_.Name
            $props = & $Properties
            Write-Host '  properties for the file are: ' -nonew
            write-Host ($props.GetEnumerator()| %{"{0}-{1}" -f $_.key,$_.Value})
        }
    }
}

Look at the $Properties. It should be evaluated for each file and then the file and the properties should be processed further.

Example how to use it might be:

Get-ChildItem c:\windows |
    ? { !$_.PsIsContainer } |
    Set-DbFile -prop { 
        Write-Host Creating properties for $_.FullName
        @{Name=$_.Name } # any other properties based on the file
    }

When I copy & paste function Set-dbFile to command line and run the example snippet, everything is fine.

However, when I store the function in a module, import it and run the example, the $_ variable is empty. Does anybody know why? And how to solve it? (other solutions are welcome as well)


Results for function defined in a script/typed in commandline:

Inside. Storing adsvw.ini
Creating properties for C:\windows\adsvw.ini
  properties for the file are: Name-adsvw.ini

Inside. Storing ARJ.PIF
Creating properties for C:\windows\ARJ.PIF
  properties for the file are: Name-ARJ.PIF
....

Results for function defined in module:

Inside. Storing adsvw.ini
Creating properties for
  properties for the file are: Name-

Inside. Storing ARJ.PIF
Creating properties for
  properties for the file are: Name- 
....
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T04:24:37+00:00Added an answer on May 23, 2026 at 4:24 am

    Looks like GetNewClosure() is as good a work around as any, but it changes the way the script block sees those variables. Passing $_ to the scriptblock as an argument works, too.

    It has nothing to do with normal scope issues (e.g., global vs local), but it appears like that at first. Here’s my very simplified reproduction and some explanation following:

    script.ps1 for normal dot-sourcing:

    function test-script([scriptblock]$myscript){
        $message = "inside"
        &{write-host "`$message from $message"}    
        &$myscript
    }
    

    Module\MyTest\MyTest.psm1 for importing:

    function test-module([scriptblock]$myscript){
        $message = "inside"
        &{write-host "`$message from $message"}    
        &$myscript
    }
    
    function test-module-with-closure([scriptblock]$myscript){
        $message = "inside"
        &{write-host "`$message from $message"}    
        &$myscript.getnewclosure()
    }
    

    Calls and output:

    » . .\script.ps1
    
    » import-module mytest
    
    » $message = "outside"
    
    » $block = {write-host "`$message from $message (inside?)"}
    
    » test-script $block
    $message from inside
    $message from inside (inside?)
    
    » test-module $block
    $message from inside
    $message from outside (inside?)
    
    » test-module-with-closure $block
    $message from inside
    $message from inside (inside?)
    

    So I started hunting around since this piqued my curiosity, and I found a few interesting things.

    This Q&A, which also features a link to this bug report is pretty much the exact same topic, as are some other blog articles I ran across. But while it was reported as a bug, I disagree.

    The about_Scopes page has this to say (w:

    ...
    
    Restricting Without Scope
    
      A few Windows PowerShell concepts are similar to scope or interact with 
      scope. These concepts may be confused with scope or the behavior of scope.
    
      Sessions, modules, and nested prompts are self-contained environments,
      but they are not child scopes of the global scope in the session.
    
      ...
    
      Modules:
        ...
    
        The privacy of a module behaves like a scope, but adding a module
        to a session does not change the scope. And, the module does not have
        its own scope, although the scripts in the module, like all Windows
        PowerShell scripts, do have their own scope. 
    

    Now I understand the behavior, but it was the above and a few more experiments that led me to it:

    • If we change $message in the scriptblock to $local:message then all 3 tests have a blank space, because $message is not defined in the scriptblock’s local scope.
    • If we use $global:message, all 3 tests print outside.
    • If we use $script:message, the first 2 tests print outside and the last prints inside.

    Then I also read this in about_Scopes:

    Numbered Scopes:
        You can refer to scopes by name or by a number that
        describes the relative position of one scope to another.
        Scope 0 represents the current, or local, scope. Scope 1
        indicates the immediate parent scope. Scope 2 indicates the
        parent of the parent scope, and so on. Numbered scopes
        are useful if you have created many recursive
        scopes.
    
    • If we use $((get-variable -name message -scope 1).value) in order to attempt getting the value from the immediate parent scope, what happens? We still get outside rather than inside.

    At this point it was clear enough to me that sessions and modules have their own declaration scope or context of sorts, at least for script blocks. The script blocks act like anonymous functions in the environment in which they’re declared until you call GetNewClosure() on them, at which point they internalize copies of the variables they reference of the same name in the scope where GetNewClosure() was called (using locals first, up to globals). A quick demonstration:

    $message = 'first message'
    $sb = {write-host $message}
    &$sb
    #output: first message
    $message = 'second message'
    &$sb
    #output: second message
    $sb = $sb.getnewclosure()
    $message = 'third message'
    &$sb
    #output: second message
    

    I hope this helps.

    Addendum: Regarding design.

    JasonMArcher’s comment made me think about a design issue with the scriptblock being passed into the module. In the code of your question, even if you use the GetNewClosure() workaround, you have to know the name of the variable(s) where the scriptblock will be executed in order for it to work.

    On the other hand, if you used parameters to the scriptblock and passed $_ to it as an argument, the scriptblock does not need to know the variable name, it only needs to know that an argument of a particular type will be passed. So your module would use $props = & $Properties $_ instead of $props = & $Properties.GetNewClosure(), and your scriptblock would look more like this:

    { (param [System.IO.FileInfo]$fileinfo)
        Write-Host Creating properties for $fileinfo.FullName
        @{Name=$fileinfo.Name } # any other properties based on the file
    }
    

    See CosmosKey’s answer for further clarification.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have one question about sys.setrecursionlimit() From the python docs this function: Set the
So this was one of my very first questions here, but I have a
I have a question similar to the one here: Event handlers inside a Javascript
Here is one more newbie question: require 'tasks/rails' I saw this line in Rakefile
This is a similar question to this one here . Given a list of
This is a follow-on question from the one I asked here . Can constraints
I have a question that is very similar to this one: Setting focus to
Kind-of a crazy question here... I have a view display that's set up as
Here's another one of these LinqToSQL questions where I'm sure I must have missed
Following a question posted here about how I can increase the speed on one

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.