Skip to content

Commit 0e20f34

Browse files
committed
Draft
1 parent 837e1a0 commit 0e20f34

File tree

2 files changed

+34
-233
lines changed

2 files changed

+34
-233
lines changed

1-Draft/.vscode/spellchecker.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"language": "en_US",
3+
"ignoreWordsList": [
4+
"PowerShell",
5+
"cmdlet",
6+
"WSMan",
7+
"remoting",
8+
"SSHRemoting",
9+
"seperate",
10+
"TestConnection",
11+
"ICMP"
12+
],
13+
"documentTypes": [
14+
"markdown",
15+
"latex",
16+
"plaintext"
17+
],
18+
"ignoreRegExp": [],
19+
"ignoreFileExtensions": [],
20+
"checkInterval": 5000
21+
}
Lines changed: 13 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -1,251 +1,31 @@
11
---
2-
RFC: 0002
3-
Author: Jason Shirk
2+
RFC:
3+
Author: Jody Whitlock
44
Status: Draft
5-
Area: Splatting
6-
Comments Due: 3/31/2016
5+
Area: Commands
6+
Comments Due:
77
---
88

9-
# Generalized Splatting
9+
# Get-TestConnection cmdlet for non-Windows Systems
1010

11-
Splatting was introduced in PowerShell v2
12-
as a way of passing named arguments to a command
13-
using an expression (e.g. `@PSBoundParameters`)
14-
instead of explicit parameter syntax (e.g. `-Param1 $value`).
15-
The expression syntax introduced was limited
16-
to variable references and is more restrictive than necessary.
11+
Test-Connection, introduced in PowerShell 2.0 under the Microsoft.PowerShell.Management class provided a mechanism for sending ICMP echo requests within the PowerShell language and have the results returned as a PowerShell object that could be manipulated as such.
1712

18-
Proxy functions are much easier to write using splatting.
19-
A proxy function might add or remove parameters to another command,
20-
but might not care about all of the parameters to the proxied command.
21-
The proxy still needs to pass those parameters through to the proxy,
22-
and it does this with splatting.
23-
24-
Scripters have found splatting useful beyond proxy functions,
25-
but the current syntax limits broader use of splatting.
13+
While it's true that Test-Connection has evolved very little over the years and versions of PowerShell, on only need to look at the legacy that this cmdlet builds on, the ping command. This simple command has mostly remained unchanged for as long as the ICMP protocol has existed. It's a very simplistic function that while simplistic fills a massive void in network troubleshooting and validation of communication capabilities.
2614

2715
## Motivation
2816

29-
One common use of splatting is to provide an alternate syntax for calling a command with many parameters.
30-
For example, consider a command like the following
31-
32-
```PowerShell
33-
Update-TypeData -TypeName MyCustomType `
34-
-MemberName MyCustomProperty `
35-
-MemberType NoteProperty `
36-
-Value 42
37-
```
38-
39-
In the above example, note the use of backticks at the end of every line.
40-
Those backticks are difficult to read and easy to forget.
41-
Splatting can help some here:
17+
The motivation for this RFC is as simple as the ping command itself; provide a Test-Connection cmdlet that can run on any platform that PowerShell can. This means stripping out some of the WSMan specific remoting capabilities that have been added to allow for distributed execution and removing WMI based methods and classes in favor of pure C# code.
4218

43-
```PowerShell
44-
$addTypeParams = @{
45-
TypeName = 'MyCustomType'
46-
MemberName = 'MyCustomProperty'
47-
MemberType = 'NoteProperty'
48-
Value = 42
49-
}
50-
Update-TypeData @addTypeParams
51-
```
19+
This could also be back-ported into the Windows implementation, which while immediately removing the remoting capability would increase the performance of the cmdlet by not requiring WMI accessors and allow for tighter integration between multiple platforms that this cmdlet could run on.
5220

53-
This works, but feels a bit messy because of the need for a variable,
54-
when the hashtable could start on the same line as the command name.
21+
It would also serve as a framework for further enhancement, such as using SSHRemoting to enable the distributed approach to performing a distributed ping, while allowing for some built in governor mechanism to prevent abuse of the distributed nature.
5522

56-
Another common use of splatting is to remove a specific parameter when splatting:
57-
58-
```PowerShell
59-
$PSBoundParameters.Remove('SomeExtraParam')
60-
Command @PSBoundParameters
61-
```
62-
63-
This proposal suggesst a syntax that improves this scenario as well.
23+
Lastly, and most importantly, while the current Test-Connection cmdlet in the Windows invocation of PowerShell is limited, it is used extensively to check for the existence and responsiveness of remote systems. By not providing a non-Windows specific implementation that is as close in parameter set and return types then existing code must be re-written to overcome this limitation, or adoption of PowerShell on non-Windows platforms may be barred by the lack of this simple but widely used functionality.
6424

6525
## Specification
6626

67-
This RFC proposes a more generalized syntax for splatting to support:
68-
69-
- Splatting general expressions (as opposed to simple variables)
70-
- Splatting in method invocations
71-
- Splatting in switch cases
72-
73-
Today, the syntax for splatting is a sigil used on a variable name.
74-
This proposal expands the use of the sigil to be allowed on an expression.
75-
For example:
76-
77-
```PowerShell
78-
# Existing usage:
79-
command @PSBoundParameters
80-
81-
# Equivalent - but splatting an expression (the value of a variable)
82-
command @$PSBoundParameters
83-
84-
# Splat another expression - a hashtable
85-
Update-TypeData @@{
86-
TypeName = 'MyCustomType'
87-
MemberName = 'MyCustomProperty'
88-
MemberType = 'NoteProperty'
89-
Value = 42
90-
}
91-
```
92-
93-
Note the two '@' characters in the hashtable example above.
94-
If the second '@' was omitted, the example would pass a hashtable (no splatting)
95-
in all versions of PowerShell, even V1, which means splatting without the second '@'
96-
would be a breaking change.
97-
98-
We can use more general expressions as well:
99-
100-
```PowerShell
101-
# Call a command that returns a hashtable or array to splat
102-
Get-ChildItem @$(Get-ChildItemArgs)
103-
104-
# a method that returns a hashtable or array to splat
105-
Invoke-Something @$($obj.GetInvokerArgs())
106-
```
107-
108-
### Relaxed splatting
109-
110-
In some cases, it is desirable to splat only the arguments that are available,
111-
and ignore the others.
112-
We will call this relaxed splatting.
113-
For example:
114-
115-
```PowerShell
116-
$myArgs = @{ Path = $pwd; ExtraStuff = 1234 }
117-
Get-ChildItem @$myArgs
118-
```
119-
120-
The above example would fail with a "parameter not found" because of the 'ExtraStuff' key.
121-
Here is a possible syntax to allow the above without resulting in an error:
122-
123-
```PowerShell
124-
$myArgs = @{ Path = $pwd; ExtraStuff = 1234 }
125-
Get-ChildItem @?$myArgs
126-
```
127-
128-
We can think of '@?' as the 'relaxed splatting' operator.
129-
If '@' is the splatting operator,
130-
adding the '?' is suggestive of being more permissive,
131-
much like the C# '?.' member access operator.
132-
133-
### Splatting in method invocations
134-
135-
Today, named arguments are only supported when calling commands,
136-
named arguments do not work when calling methods.
137-
PowerShell could adopt a C# like syntax to name arguments,
138-
but splatting provides a similar capability with some additional flexibility.
139-
The obvious syntax would mirror command invocation:
140-
141-
```PowerShell
142-
# Splat a hashtable defined outside the method call
143-
$subStringArgs = @{startIndex = 2}
144-
$str.SubString(@$subStringArgs)
145-
146-
# Splat a hashtable defined inline in the method call
147-
$str.SubString(@@{startIndex = 2; length=2})
148-
```
149-
150-
Mixing splatting and positional arguments is supported.
151-
152-
```PowerShell
153-
$str.SubString(2, @@{length=2})
154-
```
155-
156-
A runtime check (or parse time if possible) is necessary to make sure an argument is not specified positionally
157-
and via splatting in the same invocation:
158-
159-
```PowerShell
160-
# Must be an error, parse time or runtime, because startIndex
161-
# is specified positionally and via splatting.
162-
$subStringArgs = @{startIndex = 2}
163-
$str.SubString(2, @$subStringArgs)
164-
```
165-
166-
Multiple splatted arguments are not allowed:
167-
168-
```PowerShell
169-
# Error, multiple splatted arguments
170-
$str.SubString(@@{startIndex = 2}, @@{length=2})
171-
```
172-
173-
The splatted argument must be last.
174-
175-
```PowerShell
176-
# Error, splatted argument is not last
177-
$str.SubString(@@{length=2}, 2)
178-
```
179-
180-
### Splatting in switch cases
181-
182-
It can be awkward to match multiple conditions with a single switch statement.
183-
For example:
184-
185-
```PowerShell
186-
switch ($color) {
187-
{ $_ -eq 'Red' -or $_ -eq 'Blue' -or $_ -eq 'Green' } { $true }
188-
default { $false }
189-
}
190-
```
191-
192-
With splatting, this can be simplified:
193-
194-
```PowerShell
195-
switch ($color) {
196-
@@('Red','Blue','Green') { $true }
197-
default { $false }
198-
}
199-
```
200-
201-
### Modifying hashtables for splatting
202-
203-
Sometimes it is useful to provide a 'slice' of a hashtable,
204-
e.g. you want to remove or include specific keys.
205-
The Add/Remove methods on a hashtable work, but can be verbose.
206-
This proposal suggests overloading the '+' and '-' operators to provide a hashtable 'slice':
207-
208-
```PowerShell
209-
Get-ChildItem @$($PSBoundParameters - 'Force') # Splat all parameters but 'Force'
210-
Get-ChildItem @$($PSBoundParameters - 'Force','WhatIf') # Splat all parameters but 'Force' and 'WhatIf'
211-
Get-ChildItem @$($PSBOundParameters + 'LiteralPath','Path') # Only splat 'LiteralPath' and 'Path'
212-
```
213-
214-
Today, PowerShell supports "adding" two hashtables with the '+' operator,
215-
the result is a new hashtable with all of the key value pairs from both hashtables.
216-
It is an error for a key to be specified in both operands.
217-
218-
This proposal adds semantics for adding and subtracting other values.
219-
If the value is enumerable, the effect is to treat each value in the collection as a key,
220-
otherwise the value is treated as a single key.
221-
The result is always a new hashtable,
222-
the left hashtable operand is unmodified.
223-
224-
When using '+', the result will only include keys found in the right hand side.
225-
When using '-', the result will exclude all keys from the right hand side.
226-
227-
In either case,
228-
it is not an error to specify a key in the right hand side operand that is not present in the left hand side.
229-
23027
## Alternate Proposals and Considerations
23128

232-
### Slicing operators
233-
234-
The suggested use of '+' and '-' is perhaps surprising
235-
even though they correspond to Add and Remove, respectively.
236-
The actual operation is also similar to a union or intersection,
237-
so other operators should be considered, perhaps bitwise operators
238-
like '-bnot' and '-bor', or maybe new general purpose set operators.
239-
240-
### Postfix operator
241-
242-
The use of a sigil is not always well received.
243-
This proposal nearly considers '@' a prefix unary operator,
244-
but it doesn't quite specify it as such.
29+
An alternate proposal is to not implement Test-Connection but rather build a new cmdlet from the ground up to replace Test-Connection entirely. This would be similar in impact to not implementing Test-Connection cross-platform by requiring an unknown amount of code changes to occur before adoption on non-Windows platforms can occur.
24530

246-
A postfix operator is another possiblity and would look less like a sigil.
247-
This idea was rejected because, when reading a command invocation from left to right,
248-
it's important to understand how a hash literal is to be used.
249-
The sigil makes it clear a hash literal is really specifying command arguments.
250-
Furthermore, the sigil simplifies the analysis required for good parameter completion,
251-
and does not require a complete expression to begin providing parameter name completion.
31+
This may also lend to those that require this functionality to create seperate code-bases and modules to fill the gap, leading to many custom solutions and suffering from the lack of standards and community collaboration.

0 commit comments

Comments
 (0)