Splatting with dot notation.

Hello there!

I have some configuration as below…

[pre]

$Config = @{
AParam = @{
Key1 = ‘Value1’
Key2 = ‘Value2’
}
BParam = @{
Key3 = ‘Value4’
Key4 = ‘Value4’
}
}

[/pre]

And I want to make use of splatting for two different cmdlets like this…

 

[pre]

Get-Something @(Config.AParam)
Do-Something @(Config.BParam)

[/pre]

But I don’t want to use any temporary variable in between…

[pre]

$AParam = $Config.AParam
Get-Something @AParam

[/pre]

This works, but I am just wondering any other possible ways? I have tried the combinations as below, but still no luck…

[pre]

@Config.AParam
@($Config.AParam)

[/pre]

 

Any idea, please…?

 

Thank you,

Kiran P.

If the key is not unique, it would be ignored by the other functions\cmdlets assuming it’s using ValueFromPipelineByPropertyName:

function Test-It {
    
    param (
        $FirstName,
        $LastName
    )
    begin {}
    process {
        $PSBoundParameters
    }
    end {}
}

function Test-That {
    param (
        $Color,
        $Hobby
    )  
    begin {}
    process {
        $PSBoundParameters
    }
    end {}    
}

$splat = @{
    FirstName = 'John'
    LastName = 'Smith'
    Color = 'Red'
    Hobby = 'Curling'

}

Test-It @splat
Test-That @splat

What if I have $splat like this…

[pre]

$splat = @{
    Name = @{
        FirstName = 'John'
        LastName = 'Smith'
    }
    Favorites = @{
        Color = 'Red'
        Hobby = 'Curling'
    }
}

[/pre]

There are a lot of people that have tried to do something similar and it appears it’s not possible. Some of the threads I see with search “powershell splatting nested hashtable”:

https://stackoverflow.com/questions/22692048/is-it-possible-to-use-splatting-with-a-nested-hashtable-in-powershell
https://social.technet.microsoft.com/Forums/lync/en-US/9d218d2f-ddf5-49fc-b2d8-b53acedb7475/howto-use-the-splatting-operator-on-a-nested-hashtable-within-a-foreachloop-without-a-temp-variable?forum=ITCG
https://stackoverflow.com/questions/35188172/why-do-i-need-to-splat-to-a-variable-first

Good option would be to not to use splatting, but If you can modify the function to take values from pipeline, then a complex object would do the job.

$r = [PSCustomObject]@{
      process = [PSCustomObject]@{Name='lsass'}
      path    = [PSCustomObject]@{Path = 'c:\'}
     }
$r.Process | Get-Process
$r.Path | Get-ChildItem

Wow I did not know you could do this. It’s similar to a filter hashtable, without the cmdlet having that parameter.

[pscustomobject]@{Name='lsass';Responding=$true}  | Get-Process

Very neat.

Thanks Prasoon! But still, I can’t add a new configuration/property since its an object.

Thanks Rob, even I have been searching but couldn’t be figured it out. Looks like there is no workaround for this.

Yes, it works like this…

[pre]

$r = @{
      process = [PSCustomObject]@{Name='lsass'}
      path    = [PSCustomObject]@{Path = 'c:\'}
     }
[PSCustomObject]$r.Process | Get-Process
[PSCustomObject]$r.Path | Get-ChildItem

[/pre]

Thanks, Prasoon!

You can elements add using Add-Member cmdlet

$r |  Add-Member -MemberType noteproperty -Name Invoke -Value ([PSCustomObject]@{ComputerName = 'localhost'})

$r.Invoke | Invoke-Command -ScriptBlock {hostname}

Thanks @kvprasson!

Yeah, the concept is good, but it’s not suitable for my scenario, because some of the cmdlets don’t support ValueFromPipeline attribute properties, so I have to use splatting or passing the parameters directly. So I have to use an intermediate variable.