SeeminglyScience / EditorServicesCommandSuite

Collection of editor commands for use in PowerShell Editor Services.
Other
151 stars 13 forks source link

Splat Expressions giving weird results? #50

Closed PrzemyslawKlys closed 4 years ago

PrzemyslawKlys commented 4 years ago

Hi @SeeminglyScience

So I have this:

image

I choose splat expression.. and:

  1. If the cursor is inside Filter it will do this:

image

  1. If the cursor is on Get-ADUser it will do this:

image

$UsersActiveDirectory = $getADUserSplat = @{
    Filter = { Enabled -eq $true }
    SearchBase = $SearchBase
    Properties = 'ProxyAddresses', 'EmailAddress', 'DistinguishedName', 'Enabled', 'GivenName', 'Name', 'SamAccountName', 'SID', 'ObjectGUID'
}
Get-ADUser @getADUserSplat

Something is wrong or I am just doing it wrong :-) Also in some other situation it was doing this:

image

I picked all parameters instead of just simple splat

                    $newHTMLStatusItemSplat = @{
                        Icon = 'Bad'
                        Percentage = '30%'
                        ServiceName = $stringServiceName
                        ServiceStatus = $stringServiceStatus
                        Name = 'Twitter'
                        Status = 'Who knows?!'
                    }
                    New-HTMLStatusItem @newHTMLStatusItemSplat

But actually Name = ServiceName, ServiceStatus = Status now and it's just aliased.

image

But after I've rebuilt the module it was working ok, yet it was picking up both ServiceName and Name at the same time from somewhere.

I have a feeling it wasn't working like that before. Now it's a bit unpredictable. But maybe I wasn't using it enough ;)

SeeminglyScience commented 4 years ago

So the first part is working as expected. From the perspective of static analysis, Enabled is a command and -eq is a parameter name. Really Get-ADUser's -Filter parameter isn't typed as a ScriptBlock. Instead it's converted to a string and the command internally does some hacky string scanning to look for variables. Most folks (including myself) will recommend rather strongly against using the psuedo scriptblock style (even if documentation uses it). There are tons of scenarios where it just straight up doesn't work like a scriptblock.

For the second example, did you have version of the module without that parameter alias in your module path? I ran a little test:

function Test-Command {
    [CmdletBinding()]
    param(
        [Parameter()]
        [Alias('what')]
        [string] $Hi
    )
}

Test-Command -what 'eyy'

If I highlight the function and F8 then it correctly resolves what to Hi. If I remove the Alias and run that, it shows how you describe. If I don't have the command defined at all, it doesn't work (as expected).

This feature relies heavily on command discovery, so whatever gets resolved first will win. The engine doesn't have support for generating a CommandInfo purely from an AST, and manually building parameter set information from the AST isn't super feasible.

So really the solution to the latter is to import the module you're working on when you make changes like that. If you manually load the command, it won't pull from module path.

PrzemyslawKlys commented 4 years ago

What about this conversion?

$DomainControllers = Get-WinADDomainControllers -TestAvailability

To

$DomainControllers = $getWinADDomainControllersSplat = @{
    TestAvailability = $true
}
Get-WinADDomainControllers @getWinADDomainControllersSplat

It's behaving like that now. $DomainControllers should be elsewhere...

SeeminglyScience commented 4 years ago

Yeah that's wrong for sure 🙂

Working on it now, thanks!

SeeminglyScience commented 4 years ago

Fixed with v1.0.0-beta1

Install-Module EditorServicesCommandSuite -Scope CurrentUser -AllowPrerelease -Force