PowerShell: Ctrl+space won't work in any code declared within a function

Markus Johnsson 21 Reputation points
2022-09-26T08:38:16.58+00:00

Hello, friends!

This is my first post on this forum and I am fairly new to PowerShell and have been experimenting with it on and off in the past and I have recently started doing a bit of scripting so my knowledge isn't that solid yet so, please, bare with me. (However, please know that I've read all relevant documentation I could find without finding any answers to my little problem.)

My problem is very trivial but oh so disturbing: I like the PowerShell feature Ctrl+Space and when I write scripts with parameters but where the code is not declared within a function, Ctrl+Space works just fine. However, when I wrap the code in a function body then simply nothing at all happens when I press Ctrl+Space. No parameter options show up any longer. I mean surely this should work in functions?

I take a most minimal example that works with Ctrl+Space just to make clear what works and not, while sticking to the simplest possible (almost):

param (  
    [Parameter()]  
    [string]  
    $Var = "Test"  
)  
    $ParamValue = $Var  
    $ParamValue  
  

But as soon as this snippet is wrapped in a function...

Function FunctionName {  
    param (  
        [Parameter()]  
        [string]  
        $Var = "Test"  
    )  
        $ParamValue = $Var  
        $ParamValue  
}  
FunctionName  

...Ctrl+Space will simply not show any parameters. Also, this means that my parameter variables are NOT recognized either so I can't complete or cycle through mine and the systems parameter names with TAB either, which is a horrible ordeal! :D

On Windows 10 and Server 2019 I am working with PowerShell Version 7.2.6 as my standard engine but I also use the latest Preview build and Windows PowerShell 5.1 for testing purposes. I have the same issues in all of these environments when it comes to this issue.

Have any of you experienced this behavior as well and do you know what I'm doing wrong?

I understand that this is not a significant problem but I felt it is still a feature that simply should work - no matter who wrote the script - since the feature is there for a reason, right? And it should work in any case.

I'm prepared for that, whatever the cause for this issue may be, it is most certainly located on my side but I'm at a total loss as to what it may be, but I would really like to know why this won't work and I would really appreciate any kind of helping hands here: links to or names of documents that will explain why it won't work in functions (which is extremely disturbing) or that will treat the subject so I can get some sleep tonight ; )

(note: I'm couldn't provide the tags I wanted because I was forced to choose among existing ones but sure this question must be valid even here?)

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
10,676 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,383 questions
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 45,096 Reputation points
    2022-10-04T18:56:14.16+00:00

    Well, yes, the Ctrl+Space works with a script that contains no functions. But consider this: if the SCRIPT file contains a function, the FUNCTIONS parameters aren't exposed until the function is loaded into the session. Thus, the need to use dot-sourcing unless it's you intention to use the function in the current PowerShell session.

    But if your intention is to run a script and not pollute your PowerShell sessions memory with functions that make no sense to retain (e.g., they specific the script in which they reside and are of no use outside the script), then you don't dot-source the script.

    #This using the file Get-TestBBB which contains a function  
    #  
    #  
    # When run as a script (without dot-sourcing), the parameter is passed,  
    # but within the script the function Get-TestBBB is invoked with no parameter.  
    # The result? The default value of the Test parameter (an empty string)  
    # is used.  
    PS C:\junk> .\get-testbbb.ps1 -Test "Blah"  
    It doesn't work  
    PS C:\junk>  
      
    # The same thing happens because the function is invoked with no value  
    # from within the ps1 file.  
    PS C:\junk> . .\get-testbbb.ps1 -Test "Blah"  
    It doesn't work  
      
    # But NOW, becasue the script was dot-sourced, the funtion Get-TestBBB  
    # is preserved in this session's "memory"  
      
    PS C:\junk> gci function:get-*  
      
    CommandType     Name                                               Version    Source  
    -----------     ----                                               -------    ------  
    Function        Get-Verb  
    Function        Get-FileHash                                       3.1.0.0    Microsoft.PowerShell.Utility  
    Function        Get-TestBBB  
      
    # NOW, we only have to invoke the function. The function invokation WITHIN  
    # the script isn't part of the function.  
      
    PS C:\junk> get-testbbb -test "It Works!"  
    It Works!  
      
    # And, so does Ctrl+Space  
    PS C:\junk> get-testbbb -Test  
    Test                 Debug                WarningAction        ErrorVariable        InformationVariable  OutBuffer  
    Verbose              ErrorAction          InformationAction    WarningVariable      OutVariable          PipelineVariable  
      
    [string] Test  
    

11 additional answers

Sort by: Newest
  1. Markus Johnsson 21 Reputation points
    2022-10-04T10:08:01.27+00:00

    [Yet again the reply function won't take my post. Sorry about that]

    Alright, I get the dot-sourcing thing now but it still doesn't solve my original issue. Please, let me try to show how my system works ( or doesn't work ) with some simple code and pictures a bit more graphic this time. I hope it will make things clearer.

    I will run two scripts, one with its code outside any function, and another which has the same code as the first but that has its code wrapped inside a function. The first will take my parameters but the second will not (and consequently it will show or not show the Ctrl + Space menu.) The code is awkward but it will show you my problem clearly. Here we go:

    # Get-TestAAA - NO FUNCTION  
    [CmdletBinding()]  
        param (  
                [string]$Test = ""  
            )  
      
        If ($Test -eq "") {  
            Write-host "It doesn't work"  
        }  
        else {  
            Write-host $Test  
        }  
    

    And here are the results when I feed it a parameter value. (And just for the sake of it and since you mentioned it, I will dot-source the scripts when I run them even if it won't affect the situation for me in this case. I realize that the functions will be available in memory of the session when I dot-source.)

    First, you see that Ctrl + Space works fine here:

    247240-testaaa-ctrlspace.jpg

    Then I run the script with a parameter value:

    247337-testaaa.jpg

    Then we have the second script - the one that is contained inside a function:

    # Get-TestBBB - NO FUNCTION  
    Function Get-TestBBB {  
        [CmdletBinding()]  
        param (  
                [string]$Test = ""  
            )  
      
        If ($Test -eq "") {  
            Write-host "It doesn't work"  
        }  
        else {  
            Write-host $Test  
        }  
    } Get-TestBBB  
    

    And Ctrl + Space won't work here:

    247289-testbbb-ctrlspace.jpg

    And the results of running the script with parameter value:

    247268-testbbb.jpg

    This is as clear as I can make it. It shows what my problem has been all along.

    BUT, I can apparntly write other functions and successfully call them within my scripts, I noticed yesterday. I've been so wrapped up in why it won't work when I wrap the Param()-statements inside a function that I didn't think to mention that other functions work but not when I contain [CmdletBinding] Param() inside a function. It should work, shouldn't it? Or can you see any obvious mega-mistake on my behalf?

    I'm so grateful for all the feedback you have provided me with so far and just for sticking with me and trying to make me understand but I feel stupid here now. Why won't it work? I want it to be an error but I am not able to locate any myself. This will be my last shot on this subject, I suppose, because I can't be much more explicit than this. Hope you'll notice something obvious that I am missing.

    Thanks again for tagging along on this little trip, RichMatheisen-8856 : ) I'm much obliged.

    0 comments No comments

  2. Markus Johnsson 21 Reputation points
    2022-10-03T08:46:15.173+00:00

    (Reply still won't work!!)

    Thanks yet again, RichMatheisen-8856,

    but honestly, I don't really care much whether Ctrl + Space works in VS Code or not, even though it's handy (and all the other functions work the way they should there.) I just want the same functionality that you get when you write a function and are able to run the script from a console window and feed the function's parameter values through the command line while containing the code inside a Function! i.e. .\script.ps1 -Param1 Value1 -Param2 Value2

    That's all I really need to work and it seems to me that it should work right out of the box, without any special fixing of any sort. (Not that I mind doing some fixing. I'd do anything!) Having that working is what is most important to me but the two go hand in hand because if Ctrl + Space won't work then nor will my parameters work from the command line in any host on any of my two computers - and all because I wrote Function FunctionName { #Code here }? I mean, you are not dot-sourcing or anything in order to make it play for you, right? It just works. Ctrl + Space is more of a flag to me indicating that "Hey! NOW your parameters will work!" or the total opposite when Ctrl + Space won't work.

    So I constantly go back to square one just to end up having to write everything without the use of functions, which is a pain. I don't know whether the good old Filter Name { } works like a function internally or not but that works for me with parameters and Ctrl + Space but not Function, oh no. I sit literally doomed here and it's all darkness around me, haha :D

    Any other thoughts on why this might be?


  3. Rich Matheisen 45,096 Reputation points
    2022-10-02T21:30:48.567+00:00

    If you're trying to use Ctrl+Space from VS Code's Terminal there' no need to dot-source your function. All you need to do is place the cursor in the Editor (where the code for your function should be) and use Ctrl+F5.

    You only need to dot-source the function if you're loading the script that contains your function into a PWSH session.

    Dot-Source your function's .ps1 file into a PWSH session and then type in "get-physicaladapter -<Ctrl+Space>" -- that should work.

    However, in order to do the same thing in VS Code's Terminal, you'll have to install the PSReadline module, version 2.2.6, and then exit and reload VS Code (to have stand-alone PWSH use the new version you'll have to exit any PWSH sessions and restart them, too).

    Install-Module psreadline -Force  
    

    If you're asked to trust the repository, answer "Y".

    0 comments No comments

  4. Markus Johnsson 21 Reputation points
    2022-10-02T10:09:24.067+00:00

    (For some reason, the forum doesn't allow me to directly reply to your reply any longer so I wrote here)

    Thank you for your explanation. Much appreciated.

    However, I tried dot-sourcing and it didn't work either :( It is the exact same result - no list from Ctrl + Space and no parameters that will work as long as a function is defined.

    When you use VS Code, are you using PWSH or PowerShell in the "Terminal"?

    In VC Code, I use PWSH and the PowerShell Extension terminal. Both terminals act the same as the external shells do when it comes to my problem.

    Keep in mind that you're running PWSH or PowerShell from a different host (VS Code) and, if I remember correctly, VS Code is using some sort of terminal emulation that may have a different use for the Ctrl-Space.

    I don't know anything about the terminal emulation but what I do know is that the VS Code terminals act exactly the same as the standard "console hosts" (the windows standard PowerShell console window) with PWSH or PowerShell. Ctrl + Space works perfectly in VS Code too when the code isn't in a function. I also have a second computer where I have no profile on my PWSH and PowerShell hosts and the problem is exactly the same on that computer.

    I'm assuming you meant that you're using Notepad*++* and not Microsoft's "Notepad". :-)

    Hehe, your assumption was wrong. I meant Microsoft Notepad. That boring old junkpad. But I don't normally use it for scripting. I have been using it while debugging this issue of mine with some simple code I switch back and forth between the hosts and editors just to see that there isn't anything bound to the editor in itself. But I could never actually code in Notepad. Too tedious and too easy to make typos. : )

    0 comments No comments