amps.psm1
Set-StrictMode -Version Latest <# .SYNOPSIS Enter-Object destructures an object and makes its properties available as variables in a new scope. .DESCRIPTION Enter-Object makes available as variables the properties of an object, or the items of a hashtable, within a new scope without needing to refer to the object itself. It has an alias of 'with' to provide a shorthand version that makes it feel like a built-in language construct. The most common anticipated use of this function is to perform splatting operations on a nested object's properties or nested hashtable's items without having to perform temporary variable assignments to refer to the nested properties/items. Enter-Object removes the use of temporary variables and becomes more concise when dealing with complex configuration objects where multiple splatting operations are needed. .EXAMPLE > $loginResult = @{ Success = $false Reason = 'Expired' Message = @{ Object = "Your password has expired, please reset your password." BackgroundColor = "Red" ForegroundColor = "Yellow" } } Enter-Object $loginResult { Write-Host @Message } This example shows how a nested hashtable can be splatted directly without having to assign it to a new temporary variable as would normally be needed as follows: $message = $loginResult.Message Write-Host @message .EXAMPLE > with $loginResult { Write-Host @Message } Building upon the first example, this shows the use of the 'with' alias which makes this feel like a built-in keyword. The 'with' alias was chosen because it's a keyword found in the VB.NET language that performs the same purpose. .OUTPUTS Any objects written to the output stream will be returned. #> function Enter-Object { [CmdletBinding()] [Alias("with")] param ( # The object or hashtable to destructure and make available as variables within the script block. # When supplying an object the properties will be exposed as the variables. # When supplying a hashtable the items will be exposed as the variables. # Only the first-level of properties/items from the input object are converted into variables. [Parameter(Mandatory,ValueFromPipeline)] [ValidateNotNull()] [Object[]] $InputObject, # The script block with commands to execute in a new nested scope with access to the variables # from the decomposed input object. [Parameter(Mandatory)] [ValidateNotNull()] [ScriptBlock] $ScriptBlock ) process { foreach($io in $InputObject) { Write-Verbose "InputObject type: $($io.GetType().FullName)" $variables = if($io -is [Hashtable]) { $io.Keys | ForEach-Object { [PSVariable]::new($_,$io.Item($_)) } } else { $io.PSObject.Properties | ForEach-Object { [PSVariable]::new($_.Name,$_.Value) } } Write-Verbose "ScriptBlock variables: $($variables.Name -join ',')" # functions, variables, arguments $ScriptBlock.InvokeWithContext($null,[PSVariable[]]$variables,$null) } } } <# .SYNOPSIS Invoke-Splat invokes a command by splatting the provided hashtable or array. .DESCRIPTION Invoke-Splat invokes a command and splats the provided hashtable or array. It has an alias of 'iat' to provide a shorthand version named after the At symbol (@), by 'Invoking At'. The anticipated use of this function is to perform splatting operations on a nested object's properties or nested hashtable's items without having to perform temporary variable assignments to refer to the nested properties/items. Invoke-Splat removes the need to use of temporary variables and provides a concise syntax when splatting items located within nested objects and hash tables. .EXAMPLE > This example shows how a nested hashtable can be splatted directly without having to assign it to a new temporary variable. Given the following hash table: $loginResult = @{ Success = $false Reason = 'Expired' Message = @{ Object = "Your password has expired, please reset your password." BackgroundColor = "Red" } } Splatting the nested $loginResult.Message hash table normally requires an assignment to a new temporary variable followed by splatting the hash table variable to the command: $message = $loginResult.Message Write-Host @message With Invoke-Splat, the nested hash table can be splatted directly against the command: Invoke-Splat Write-Host $loginResult.Message .EXAMPLE iat Write-Host $loginResult.Message Building upon the data structure from the previous example, this example shows the use of the 'iat' alias. .EXAMPLE iat {Write-Host -ForegroundColor Yellow} $loginResult.Message Building upon the data structure from the previous example, this shows how to invoke a command with additional parameters to those in the InputObject parameter, by placing the command and its parameters in a script block. .EXAMPLE $loginResult.Message | iat Write-Host Building upon the data structure from the previous example, this shows how to pipe a hash table to be splatted. .OUTPUTS Any objects returned by the supplied command will be returned. #> function Invoke-Splat { [CmdletBinding()] [Alias("iat")] param ( # The command to execute. [string] $Command, # The hash table or array to splat. See about_Splatting for usage. [Parameter(Mandatory,ValueFromPipeline)] [object] $InputObject ) # perform parameter validation here because [ValidateScript] doesn't work with [array] if(-not ($InputObject -is [hashtable] -or $InputObject -is [array])) { throw "Invoke-Splat: InputObject parameter type must a [hashtable] or [Array]" } Invoke-Expression -Command "$Command @InputObject" } |