-
Notifications
You must be signed in to change notification settings - Fork 5
/
Write-ScriptCmdlet.ps1
158 lines (147 loc) · 9.68 KB
/
Write-ScriptCmdlet.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
function Write-ScriptCmdlet
{
<#
.Synopsis
Creates a new script cmdlet
.Description
Creates a new script cmdlet automatically
.Example
Write-ScriptCmdlet New-FooBar
.Example
Write-ScriptCmdlet -Name Start-ProcessAsAdministrator -FromCommand (Get-Command Start-Process) -RemoveParameter Verb -ProcessBlock {
$null = $psBoundParameters.Verb = "RunAs"
Start-Process @psBoundParameters
}
.Example
Write-ScriptCmdlet -Name -FromCommand (Get-Command Get-Process) -RemoveParameter Verb
.Example
Write-ScriptCmdlet -Name Get-Process -ProxyCommand (Get-Command Get-Process)
#>
[CmdletBinding(DefaultParameterSetName="Name")]
param(
# Creates a proxy command from a given command.
# Proxy commands are a special form of Powershell command that is used
# to restrict the set of parameters for a given cmdlet.
[Parameter(Mandatory=$true,
ParameterSetName="ProxyCommand",
ValueFromPipeline=$true,
Position=1)]
[Management.Automation.CommandInfo]
[Alias('Proxy')]
$ProxyCommand,
# The name of the command to generate
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
[String]
$Name,
# The parameter block to embed in the command
[Parameter(ParameterSetName="Name")]
[String]
$ParameterBlock,
# FromCommand allows you to create a command based off an existing command.
# This command wil not run the command, but it will share the same parameter
# signature for the command.
[Parameter(ParameterSetName="FromCommand",
Mandatory=$true,
ValueFromPipelineByPropertyName=$true
)]
[Management.Automation.CommandInfo]
$FromCommand,
# Any additional parameters to add to the command.
[Parameter(ParameterSetName="FromCommand",
ValueFromPipelineByPropertyName=$true)]
[Management.Automation.ParameterMetaData[]]
$AdditionalParameter,
# Any parameters to remove from the command.
[Parameter(ParameterSetName="FromCommand",
ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName="ProxyCommand",
ValueFromPipelineByPropertyName=$true)]
[string[]]
$RemoveParameter,
# The content of the begin block
[Parameter(ParameterSetName="Name")]
[Parameter(ParameterSetName="FromCommand")]
[String]
$BeginBlock,
# The content of the process block
[Parameter(ParameterSetName="Name")]
[Parameter(ParameterSetName="FromCommand")]
[String]
$ProcessBlock,
# The content of the end block
[Parameter(ParameterSetName="Name")]
[Parameter(ParameterSetName="FromCommand")]
[string]
$EndBlock,
# The content of the help block.
[Parameter(ParameterSetName="Name")]
[Parameter(ParameterSetName="FromCommand")]
[String]
$HelpBlock
)
Process
{
Switch ($psCmdlet.ParameterSetName) {
Name {[ScriptBlock]::Create("
function $name {
$HelpBlock
param(
$ParameterBlock
)
begin {
$BeginBlock
}
process {
$ProcessBlock
}
end {
$EndBlock
}
}")
}
ProxyCommand {
$MetaData = New-Object Management.Automation.CommandMetaData $ProxyCommand
foreach ($rp in $removeParameter) {
if (-not $rp) { continue }
$null = $MetaData.Parameters.Remove($rp)
}
foreach ($ap in $additionalParameter) {
if (-not $ap) { continue }
$null = $MetaData.Parameters.Add($ap.Name, $ap)
}
[ScriptBlock]::Create("
function $Name {
$([Management.Automation.ProxyCommand]::Create($MetaData))
}")
}
FromCommand {
$MetaData = New-Object Management.Automation.CommandMetaData $FromCommand
foreach ($rp in $removeParameter) {
if (-not $rp) { continue }
$null = $MetaData.Parameters.Remove($rp)
}
foreach ($ap in $additionalParameter) {
if (-not $ap) { continue }
$null = $MetaData.Parameters.Add($ap.Name, $ap)
}
[ScriptBlock]::Create("
function $Name {
$HelpBlock
$([Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($metaData))
param(
$([Management.Automation.ProxyCommand]::GetParamBlock($metaData))
)
begin {
$BeginBlock
}
process {
$ProcessBlock
}
end {
$EndBlock
}
}")
}
}
}
}