-
-
Save joeypiccola/75cd1f4fd5c2e5f429d7dc580ce6b420 to your computer and use it in GitHub Desktop.
Function New-VMDeploy { | |
[CmdletBinding()] | |
Param() | |
DynamicParam { | |
# Set the dynamic parameters' name | |
$ParamName_portgroup = 'PortGroup' | |
# Create the collection of attributes | |
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] | |
# Create and set the parameters' attributes | |
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute | |
$ParameterAttribute.Mandatory = $true | |
$ParameterAttribute.Position = 1 | |
# Add the attributes to the attributes collection | |
$AttributeCollection.Add($ParameterAttribute) | |
# Create the dictionary | |
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary | |
# Generate and set the ValidateSet | |
$arrSet = (Get-VDPortgroup | ?{$_.name -like "*VLAN*"}).name | |
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) | |
# Add the ValidateSet to the attributes collection | |
$AttributeCollection.Add($ValidateSetAttribute) | |
# Create and return the dynamic parameter | |
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParamName_portgroup, [string], $AttributeCollection) | |
$RuntimeParameterDictionary.Add($ParamName_portgroup, $RuntimeParameter) | |
# Set the dynamic parameters' name | |
$ParamName_datastore = 'Datastore' | |
# Create the collection of attributes | |
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] | |
# Create and set the parameters' attributes | |
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute | |
$ParameterAttribute.Mandatory = $true | |
$ParameterAttribute.Position = 2 | |
# Add the attributes to the attributes collection | |
$AttributeCollection.Add($ParameterAttribute) | |
# Generate and set the ValidateSet | |
$arrSet = (Get-Datastore).name | |
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) | |
# Add the ValidateSet to the attributes collection | |
$AttributeCollection.Add($ValidateSetAttribute) | |
# Create and return the dynamic parameter | |
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParamName_datastore, [string], $AttributeCollection) | |
$RuntimeParameterDictionary.Add($ParamName_datastore, $RuntimeParameter) | |
return $RuntimeParameterDictionary | |
} | |
begin{} | |
process { | |
$portgroup = $PsBoundParameters[$ParamName_portgroup] | |
$datastore = $PsBoundParameters[$ParamName_datastore] | |
} | |
end {} | |
} |
This was the golden ticket for my custom VM deployment function! I no longer have to maintain a static list inside the parameter's validateset for hundreds of VM templates, networks, portgroups, etc.
Setting the ParameterAttribute.Postition = 0 on all the dynamic params allows intelisense to work (not setting will break intelisense).
There is also considerable lag when pulling info from vCenter (we have a big environment) so I made a scheduled task to keep the info in simple txt files that the function can quickly read from. I may switch that over to a SQL DB later.
Hey Joey,
This code helped me a lot. I tried to solve the slow tab completion when enumerating information via Microsoft Graph, like getting the displayname for 3000+ users.
When the variables $TenantId, $ApplicationClientId and $CertificateThumbprint are set with the correct values, then the variable $FilterUserName will be available. I still search for a better solution. I saw that when the variable, like '$TabCompletionFunctionGetMgUsers=EnumerateWithPaging -Data ((Get-MgUser -All -Property DisplayName).DisplayName)' is set, that each time I use the tab completion it first executes the command (Get-MgUser -All...).
If hope you have a solution for this problem, like that DynamicParam only executes the variable once...this is for now the best that I could do...
[CmdLetBinding(DefaultParameterSetName="Default",
SupportsPaging
)]
Param (
[Parameter( ParameterSetName = "Default",Position = 0 , Mandatory )]$TenantId,
[Parameter( ParameterSetName = "Default",Position = 1 , Mandatory )]$ApplicationId,
[Parameter( ParameterSetName = "Default",Position = 2 , Mandatory )]$CertificateThumbprint
)
DynamicParam {
Function EnumerateWithPaging {
Param (
$Data
)
Begin {
}
Process {
}
End{
If ( $Data.count -Gt 0 ) {
$First = $PSCmdlet.PagingParameters.Skip
$Last = $First +
[Math]::Min( $PSCmdlet.PagingParameters.First, $Data.Count - $PSCmdlet.PagingParameters.Skip ) - 1
If( $Last -Le 0 ) { $Data = $Null } Else { $Data = $Data[$First..$last]
Write-Output $Data
}
}
If ( $PSCmdlet.PagingParameters.IncludeTotalCount ) {
[double]$Accuracy = 1.0
$PSCmdlet.PagingParameters.NewTotalCount( $Data.count , $Accuracy )
}
}
}
Function ConnectMgGraph {
Try {
Connect-MgGraph -TenantId $TenantId -ApplicationId $ApplicationClientId -CertificateThumbprint $CertificateThumbprint -ClientTimeout 120 -NoWelcome -ErrorAction Stop
} Catch {
EXIT
}
}
ConnectMgGraph
# TabCompletion GetMgUsers parameters
$TabCompletionNameGetMgUsers='FilterUserName'
$TabCompletionFunctionGetMgUsers=EnumerateWithPaging -Data ((Get-MgUser -All -Property DisplayName).DisplayName)
$TabCompletionPositionGetMgusers=3
$TabCompletionMandatoryGetMgusers=$False
$TabCompletionTypeGetMgUsers=[String]
$TabCompletionParameterSetNameGetMgusers='__AllParameterSets'
# Add additional TabCompletion parameters block here... (copy from above, adjust)
# Begin TabCompletion
$RuntimeParameterDictionary=New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
# TabCompletion GetMgUsers add to dictionary
$A=New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$P=New-Object System.Management.Automation.ParameterAttribute
$P.Mandatory=$TabCompletionMandatoryGetMgUsers
$P.ParameterSetName=$TabCompletionParameterSetNameGetMgusers
$P.Position=$TabCompletionPositionGetMgUsers
$A.Add($P)
$V=New-Object System.Management.Automation.ValidateSetAttribute($TabCompletionFunctionGetMgUsers)
$A.Add($V)
$R=New-Object System.Management.Automation.RuntimeDefinedParameter($TabCompletionNameGetMgUsers,$TabCompletionTypeGetMgUsers,$A)
$RuntimeParameterDictionary.Add($TabCompletionNameGetMgUsers,$R)
# Add additional TabCompletion dictionary preparation here... (copy from above, adjust)
# End TabCompletion
Return $RuntimeParameterDictionary
}
Begin {}
Process{}
End{}
This worked great, I tried
Register-ArgumentCompleter, ArgumentCompleter
but those seems working only on ISE.