forked from StartAutomating/PSDevOps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImport-ADOProxy.ps1
154 lines (136 loc) · 4.99 KB
/
Import-ADOProxy.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
function Import-ADOProxy
{
<#
.Synopsis
Imports an Azure DevOps Proxy
.Description
Imports a Proxy Module for Azure DevOps or TFS.
A Proxy module will wrap all commands, but will always provide one or more default parameters.
.Example
Import-ADOProxy -Organization StartAutomating
.Example
Import-ADOProxy -Organization StartAutomating -Prefix SA
.Example
Import-ADOProxy -Organization StartAutomating -Project PSDevOps -IncludeCommand *Build* -Prefix SADO
.Link
Connect-ADO
.Link
Disconnect-ADO
#>
[OutputType([Nullable],[Management.Automation.PSModuleInfo])]
param(
# The Organization.
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[string]
$Organization,
# The project.
[Parameter(ValueFromPipelineByPropertyName)]
[string]
$Project,
# The server. This can be used to provide a TFS instance
[Parameter(ValueFromPipelineByPropertyName)]
[uri]
$Server,
# The prefix for all commands in the proxy module.
# If not provided, this will be the -Server + -Organization + -Project.
[Parameter(ValueFromPipelineByPropertyName)]
[string]
$Prefix,
# A list of command wildcards to include. By default, all applicable commands.
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]
$IncludeCommand = '*',
# A list of commands to exclude.
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]
$ExcludeCommand,
# If set, will return the imported module.
[switch]
$PassThru,
# If set, will unload a previously loaded copy of the module.
[switch]
$Force
)
begin {
$myModuleCommands =
@(if ($MyInvocation.MyCommand.ScriptBlock.Module) {
$MyInvocation.MyCommand.ScriptBlock.Module.ExportedCommands.Values
})
}
process {
if (-not $Prefix) {
if ($Server) {
$Prefix = $Server.DnsSafeHost -replace '\W',''
}
$Prefix+= $Organization -replace '\W',''
if ($Project) {
$Prefix += $Project -replace '\W', ''
}
}
$alreadyLoaded = Get-Module -Name $Prefix
if ($alreadyLoaded -and -not $force) {
if ($PassThru) { $alreadyLoaded }
return
} elseif ($alreadyLoaded -and $force) {
$alreadyLoaded | Remove-Module
}
#region Filter Commands
$filteredCommands =
@(:nextCommand foreach ($cmd in $myModuleCommands) {
if ($cmd.Noun -eq $MyInvocation.MyCommand.Noun) { continue }
if (-not $cmd.Parameters.Organization) { continue }
$shouldInclude = $false
foreach ($Inclusion in $IncludeCommand) {
$shouldInclude = $cmd -like $Inclusion
if ($shouldInclude) { break }
}
if (-not $shouldInclude) { continue }
foreach ($ex in $ExcludeCommand) {
if ($cmd -like $ex) { continue nextCommand }
}
$cmd
})
#endregion Filter Commands
$override = @{Organization=$Organization}
if ($Project) { $override += @{Project=$Project} }
if ($Server) { $override += @{Server =$Server } }
$overrideJson = $(ConvertTo-Json $override -Depth 100)
#region Generate Proxy Commands
$proxyCommands =
@(foreach ($cmd in $filteredCommands) {
$cmdMd = [Management.Automation.CommandMetaData]$cmd
foreach ($ok in $override.Keys) {
$null = $cmdMd.Parameters.Remove($ok)
}
$proxy = [Management.Automation.ProxyCommand]::Create($cmdMd)
$insertDefaultsAt = $proxy.IndexOf('$scriptCmd')
$proxy = $proxy.Insert($insertDefaultsAt, @"
`$defaults = @'
$overrideJson
'@ | ConvertFrom-JSON
foreach (`$prop in `$defaults.psobject.properties) {
if (`$wrappedCmd.Parameters.(`$prop.Name)) {
`$null = `$psBoundParameters.Remove(`$prop.Name)
`$psBoundParameters[`$prop.Name] = `$prop.Value
}
}
"@ + [Environment]::NewLine + ' ' * 8)
$insertDynamicParamsAt = $proxy.IndexOf('begin' + [Environment]::NewLine)
$proxy = $proxy.Insert($insertDynamicParamsAt, @"
dynamicParam {
. {$($GetInvokeParameters.ScriptBlock)} -DynamicParameter
}
"@)
@(
"function $($cmdMd.Name -replace 'ADO', $prefix) {"
$proxy
'}'
) -join [Environment]::NewLine
})
#region Generate Proxy Commands
#region Create and import module
New-Module -Name $Prefix -ScriptBlock ([ScriptBlock]::Create($proxyCommands -join [Environment]::NewLine)) |
Import-Module -Global -PassThru:$passThru
#endregion Create and import module
}
}