samples/configure/configure.ps1
<#
.PARAMETER porcelain If set, the output will be a dPowerShell object that can be used in scripts (i.e.: `$result = ./configure.ps1 get -porcelain`). Otherwise, a nicely formatted, human-readable will be displayed. .PARAMETER validate If set, will check if current configuration is valid (i.e. if all required services are running, correct azure subscription is active, etc.). Similar to `./configure.ps1 validate` #> [CmdletBinding()] param( [ValidateSet("get", "set", "options", "list", "validate", "help")] $command = "get", [ArgumentCompleter({ param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) . "$PSScriptRoot/.configuration.map.ps1" $keys = @() foreach ($kvp in $modules.GetEnumerator()) { $module = $kvp.value if ($module.list) { $moduleKeys = Invoke-Command -ScriptBlock $module.list $keys += $moduleKeys | % { "$($kvp.key)/$_" } } else { $keys += $kvp.key } } return $keys | ? { $_.startswith($wordToComplete) } })] $module = $null, [ArgumentCompleter({ param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) . $PSScriptRoot/.configuration.map.ps1 if (!$fakeBoundParameters.ContainsKey("module")) { return @("__BAD__") } $moduleAndPath = $fakeBoundParameters["module"] $splits = $moduleAndPath.Split("/") $moduleName = $splits[0] $path = $splits[1] $module = $modules.$moduleName $options = Invoke-Command -ScriptBlock $module.options -ArgumentList @($path) return $options.Keys | ? { $_.startswith($wordToComplete) } })] $value = $null, [switch][bool]$validate = $false, [switch][bool]$porcelain = $false, [object]$options = $null ) . $PSScriptRoot/.configuration.map.ps1 function write-help() { write-host "" write-host "Use ./configure.ps1 script to set advanced configuration options." write-host "Here are your current settings:" $result = ./configure.ps1 $result | Format-Table | out-string | Write-Host -ForegroundColor Yellow write-host -NoNewline "You can change above options, using: '" write-host -NoNewline -ForegroundColor Blue "./configure.ps1 set {name} {value}" write-host "'." write-host "" write-host "For example, to set event-grid to local, run:" write-host "./configure.ps1 set event-grid local" write-host "" write-host "To get current configuration, run:" write-host "./configure.ps1 get" } function invoke-modulecommand($moduleAndPath, $command, [object] $additionalOpts) { if ($command -eq "validate") { $command = "get" $validate = $true } $splits = $moduleAndPath.Split("/") $moduleName = $splits[0] $path = $splits[1] $module = $modules.$moduleName $moduleCommand = $module.$command if (!$moduleCommand) { throw "Command $m.$command not found" } switch ($command) { "set" { $options = Invoke-Command -ScriptBlock $module.options -ArgumentList @($path) if (!$options) { throw "module $moduleName does not support options[$path]" } if (!$value) { $current = invoke-modulecommand $moduleAndPath "get" $value = $current.Active } if (!$options.containskey($value)) { throw "Option $value not found for module $module" } $optionvalue = $options.$value Write-Verbose "setting $moduleAndPath = '$value' ('$optionvalue')" $r = Invoke-Command -ScriptBlock $moduleCommand -ArgumentList @($path, $optionvalue, $value, $additionalOpts) return invoke-modulecommand $moduleAndPath "validate" } { $_ -in ("get", "validate") } { if ($path -eq $null -and $module.list) { $path = Invoke-Command -ScriptBlock $module.list } if ($path -eq $null) { $path = "" } foreach ($subPath in @($path)) { Write-Verbose "getting $moduleName/$subPath" $options = Invoke-Command -ScriptBlock $module.options -ArgumentList @($path) $value = Invoke-Command -ScriptBlock $moduleCommand -ArgumentList @($subPath, $options) $result = $null if ($value -is [Hashtable]) { $hash = @{ Path = "$moduleName/$subPath" } $hash += $value $result = $hash } else { $result = @{ Path = "$moduleName/$subPath"; Value = $value } } $options = invoke-modulecommand "$moduleName/$subPath" -command "options" $additionalOpts if (!$result.Active) { $result.Active = $options.keys | where { $options.$_ -eq $value } } $result.Options = $options.keys $isvalid = "?" if ($validate -and $module.validate) { if (!$result.Active) { write-host "no active option found for $moduleName/$subPath" $isvalid = $null } else { $optionvalue = $options.$($result.Active) $isvalid = Invoke-Command $module.validate -ArgumentList @($path, $optionvalue, $result.Active) } } $result = [PSCustomObject]@{ Path = $result.Path Value = $result.Value Active = $result.Active Options = $result.Options IsValid = $isvalid } # if ($isvalid -ne "?") { # $result | Add-Member -MemberType NoteProperty -Name IsValid -Value $isvalid # } $result | Write-Output } } Default { Write-Verbose "Running $m.$command" Invoke-Command -ScriptBlock $moduleCommand -ArgumentList @($path) } } } function get-checkmark($status) { if ($status -eq $true) { return "✅" } elseif ($status -eq $false) { return "❌" } else { return "❓" } } if ($command -eq "help") { write-help return } if ($module -eq $null) { $module = $modules.keys } $result = @() foreach ($m in @($module)) { if (!$module) { throw "Module $m not found" } $status = invoke-modulecommand -moduleAndPath $m -command $command -additionalOpts $options foreach ($substatus in @($status)) { $result += $substatus } } if ($porcelain) { return $result } else { $result | % { [PSCustomObject]@{ Path = $_.Path Active = $_.Active Options = $_.Options IsValid = get-checkmark $_.IsValid } } | Format-Table } |