lib/core/installer/tools/ShowInstallerMenu.psm1
function Show-IcingaForWindowsInstallerMenu() { param ( [string]$Header, [array]$Entries, [array]$DefaultValues = @(), [string]$DefaultIndex = $null, [string]$ParentConfig = $null, [switch]$AddConfig = $FALSE, [switch]$PasswordInput = $FALSE, [switch]$ContinueFirstValue = $FALSE, [switch]$MandatoryValue = $FALSE, [int]$ConfigLimit = -1, [switch]$JumpToSummary = $FALSE, [string]$ContinueFunction = $null, [switch]$ConfigElement = $FALSE, [switch]$HiddenConfigElement = $FALSE, [switch]$ReadOnly = $FALSE, [switch]$Automated = $FALSE, [switch]$Advanced = $FALSE, [switch]$PlainTextOutput = $FALSE, [switch]$NoConfigSwap = $FALSE ); if ((Test-IcingaForWindowsInstallationHeaderPrint) -eq $FALSE -And (Get-IcingaFrameworkDebugMode) -eq $FALSE) { Clear-Host; } $PSCallStack = Get-PSCallStack; $LastArguments = $null; $LastCommand = $null; if ($PSCallStack.Count -gt 1) { $LastCommand = $PSCallStack[1].Command; $LastArguments = $PSCallStack[1].InvocationInfo.BoundParameters; # Only keep internal values as long as we are navigating within the same menu if ($global:Icinga.InstallWizard.Menu -ne $LastCommand) { $global:Icinga.InstallWizard.LastValues = @(); } # Prevent from adding ourself because of stack calls. # This should always be the "real" last command if ($LastCommand -ne 'Show-IcingaForWindowsInstallerMenu') { $global:Icinga.InstallWizard.Menu = $LastCommand; } else { $LastCommand = Get-IcingaForWindowsManagementConsoleMenu; } } $SelectionForCurrentMenu = Get-IcingaForWindowsInstallerStepSelection -InstallerStep (Get-IcingaForWindowsManagementConsoleMenu); [bool]$EntryModified = $FALSE; [int]$EntryIndex = 0; [hashtable]$KnownIndexes = @{ }; $LastParent = Get-IcingaForWindowsInstallerLastParent; [array]$StoredValues = (Get-IcingaForWindowsInstallerValuesFromStep); $global:Icinga.InstallWizard.ParentConfig = $ParentConfig; $global:Icinga.InstallWizard.LastInput = $null; if ($LastParent -eq (Get-IcingaForWindowsManagementConsoleAlias -Command $LastCommand)) { Remove-IcingaForWindowsInstallerLastParent; $LastParent = Get-IcingaForWindowsInstallerLastParent; } if (Test-IcingaForWindowsInstallationJumpToSummary) { $SelectionForCurrentMenu = $null; } if (($StoredValues.Count -eq 0 -And $DefaultValues.Count -ne 0) -Or $Automated) { $StoredValues = $DefaultValues; } if ($global:Icinga.InstallWizard.DeleteValues) { $StoredValues = @(); $global:Icinga.InstallWizard.DeleteValues = $FALSE; } if ((Test-IcingaForWindowsInstallationHeaderPrint) -eq $FALSE) { $ConsoleHeaderLines = @( 'Icinga for Windows Management Console', 'Copyright $Copyright', 'User environment $UserDomain\$Username', 'Icinga PowerShell Framework $FrameworkVersion' ); if ($global:Icinga.InstallWizard.AdminShell -eq $FALSE) { $ConsoleHeaderLines += '[Warning]: Run this shell with administrative privileges to unlock all features' } if ($PSVersionTable.PSVersion -lt '5.0.0.0') { $ConsoleHeaderLines += ([string]::Format('[Warning]: Update to PowerShell version >=5.0 from currently {0} to unlock all features (like JEA)', $PSVersionTable.PSVersion.ToString(2))); } Write-IcingaConsoleHeader -HeaderLines $ConsoleHeaderLines; Write-IcingaConsolePlain ''; Write-IcingaConsolePlain $Header; Write-IcingaConsolePlain ''; } foreach ($entry in $Entries) { if ([string]::IsNullOrEmpty($entry.Caption) -eq $FALSE) { [string]$CaptionIndention = ''; if ($Entries.Count -ge 10 -And $EntryIndex -lt 10) { $CaptionIndention = ' '; } $Header = ([string]::Format('{0}[{1}] {2}', $CaptionIndention, $EntryIndex, $entry.Caption)); $FontColor = 'Default'; if ((Test-IcingaForWindowsInstallationHeaderPrint) -eq $FALSE) { # Highlight the default index in a different color if ($DefaultIndex -eq $EntryIndex) { $FontColor = 'Cyan'; } # In case a entry is disabled, highlight it differently if ($null -ne $entry.Disabled -And $entry.Disabled -eq $TRUE) { $FontColor = 'DarkGray'; } # Mark our previous selection in another color for better highlighting if ($null -ne $SelectionForCurrentMenu -And $SelectionForCurrentMenu -eq $EntryIndex) { $FontColor = 'Green'; } Write-IcingaConsolePlain $Header -ForeColor $FontColor; if ($global:Icinga.InstallWizard.ShowCommand) { Write-IcingaManagementConsoleCommand -Entry $entry -Values $StoredValues; } if ($global:Icinga.InstallWizard.ShowHelp -And ([string]::IsNullOrEmpty($entry.Help)) -eq $FALSE) { Write-IcingaConsolePlain ''; Write-IcingaConsolePlain $entry.Help -ForeColor Magenta; Write-IcingaConsolePlain ''; } } else { if ((Get-IcingaForWindowsInstallationHeaderSelection) -eq $EntryIndex) { $global:Icinga.InstallWizard.HeaderPreview = $entry.Caption; return; } } } $KnownIndexes.Add([string]$EntryIndex, $TRUE); $EntryIndex += 1; } if ((Test-IcingaForWindowsInstallationHeaderPrint)) { return; } if ($StoredValues.Count -ne 0) { if ($PlainTextOutput) { Write-IcingaConsolePlain (ConvertFrom-IcingaArrayToString -Array $StoredValues) -ForeColor Cyan; } else { if ($PasswordInput -eq $FALSE) { Write-IcingaConsolePlain ([string]::Format(' {0}', (ConvertFrom-IcingaArrayToString -Array $StoredValues -AddQuotes))) -ForeColor Cyan; } else { Write-IcingaConsolePlain ([string]::Format(' {0}', (ConvertFrom-IcingaArrayToString -Array $StoredValues -AddQuotes -SecureContent))) -ForeColor Cyan; } } } if ($AddConfig) { if ($global:Icinga.InstallWizard.ShowCommand) { Write-IcingaManagementConsoleCommand -Entry $Entries[0] -Values $StoredValues; } if ($global:Icinga.InstallWizard.ShowHelp -And ([string]::IsNullOrEmpty($Entries[0].Help)) -eq $FALSE) { Write-IcingaConsolePlain ''; Write-IcingaConsolePlain $entry.Help -ForeColor Magenta; } } Write-IcingaConsolePlain ''; Write-IcingaConsolePlain '[x] Exit' -NoNewLine; if ($global:Icinga.InstallWizard.DisplayAdvanced) { if ($global:Icinga.InstallWizard.ShowAdvanced -eq $FALSE) { Write-IcingaConsolePlain ' [a] Advanced' -NoNewLine; } else { Write-IcingaConsolePlain ' [a] Hide Advanced' -NoNewLine -ForeColor Green; } } Write-IcingaConsolePlain ' [c] Continue' -NoNewLine; if ($AddConfig -And $ReadOnly -eq $FALSE) { Write-IcingaConsolePlain ' [d] Delete' -NoNewLine; } if ($global:Icinga.InstallWizard.ShowHelp -eq $FALSE) { Write-IcingaConsolePlain ' [h] Help' -NoNewLine; } else { Write-IcingaConsolePlain ' [h] Hide Help' -NoNewLine -ForeColor Green; } if ($global:Icinga.InstallWizard.ShowCommand -eq $FALSE) { Write-IcingaConsolePlain ' [l] Commands' -NoNewLine; } else { Write-IcingaConsolePlain ' [l] Hide Commands' -NoNewLine -ForeColor Green; } Write-IcingaConsolePlain ' [m] Main' -NoNewLine; if ([string]::IsNullOrEmpty($LastParent) -eq $FALSE -Or $global:Icinga.InstallWizard.LastParent.Count -gt 1) { Write-IcingaConsolePlain ' [p] Previous'; } else { Write-IcingaConsolePlain ''; } $Prompt = 'Input'; $CountPrompt = ([string]::Format('({0}/{1})', $StoredValues.Count, $ConfigLimit)); if ($ConfigLimit -eq -1) { $CountPrompt = ([string]::Format('({0} values)', $StoredValues.Count)); } if ($AddConfig) { $Prompt = ([string]::Format('Input {0}', $CountPrompt)); # In case we reached the maximum entries, set c as default input for easier handling if (($ConfigLimit -le $StoredValues.Count) -Or ($ContinueFirstValue -eq $TRUE -And $StoredValues.Count -ge 1)) { $DefaultIndex = 'c'; } } if ([string]::IsNullOrEmpty($DefaultIndex) -eq $FALSE) { if ((Test-Numeric $DefaultIndex)) { $Prompt = [string]::Format('Input (Default {0} and c)', $DefaultIndex); } else { $Prompt = [string]::Format('Input (Default {0})', $DefaultIndex); } if ($AddConfig) { $Prompt = [string]::Format('{0} {1}', $Prompt, $CountPrompt); } } Write-IcingaConsolePlain ''; if ([string]::IsNullOrEmpty($global:Icinga.InstallWizard.LastError) -eq $FALSE) { Write-IcingaConsoleError ($global:Icinga.InstallWizard.LastError); $global:Icinga.InstallWizard.LastError = ''; Write-IcingaConsolePlain ''; } if ([string]::IsNullOrEmpty($global:Icinga.InstallWizard.LastNotice) -eq $FALSE) { Write-IcingaConsoleNotice ($global:Icinga.InstallWizard.LastNotice); $global:Icinga.InstallWizard.LastNotice = ''; Write-IcingaConsolePlain ''; } if ($Automated -eq $FALSE) { $Result = Read-Host -Prompt $Prompt -AsSecureString:$PasswordInput; # Translate the value back to check what we used for input. We are not going to share # the content however if ($PasswordInput) { $Result = ConvertFrom-IcingaSecureString -SecureString $Result; } if ([string]::IsNullOrEmpty($Result) -And [string]::IsNullOrEmpty($DefaultIndex) -eq $FALSE) { $Result = $DefaultIndex; } } else { if ([string]::IsNullOrEmpty($DefaultIndex) -eq $FALSE) { $Result = $DefaultIndex; } } $global:Icinga.InstallWizard.NextCommand = $LastCommand; $global:Icinga.InstallWizard.NextArguments = $LastArguments; $global:Icinga.InstallWizard.LastInput = $Result; switch ($Result) { 'x' { Clear-Host; $global:Icinga.InstallWizard.Closing = $TRUE; return; }; 'a' { $global:Icinga.InstallWizard.ShowAdvanced = (-Not ($global:Icinga.InstallWizard.ShowAdvanced)); return; }; 'h' { $global:Icinga.InstallWizard.ShowHelp = (-Not ($global:Icinga.InstallWizard.ShowHelp)); return; }; 'l' { $global:Icinga.InstallWizard.ShowCommand = (-Not ($global:Icinga.InstallWizard.ShowCommand)); return; } 'm' { $global:Icinga.InstallWizard.NextCommand = $null; $global:Icinga.InstallWizard.NextArguments = $null; return; } 'p' { if ([string]::IsNullOrEmpty($LastParent) -eq $FALSE) { Remove-IcingaForWindowsInstallerLastParent; $global:Icinga.InstallWizard.NextCommand = $LastParent; $global:Icinga.InstallWizard.NextArguments = $null; return; } $global:Icinga.InstallWizard.LastError = 'You cannot move to the previous menu from here.'; if ($global:Icinga.InstallWizard.LastParent.Count -eq 0) { $global:Icinga.InstallWizard.NextCommand = $null; $global:Icinga.InstallWizard.NextArguments = $null; return; } return; }; 'd' { if ($ReadOnly -eq $FALSE) { $StoredValues = @(); Clear-IcingaForWindowsInstallerValuesFromStep $global:Icinga.InstallWizard.DeleteValues = $TRUE; $global:Icinga.InstallWizard.LastValues = @(); } return; }; 'c' { if ($MandatoryValue -And $StoredValues.Count -eq 0) { $global:Icinga.InstallWizard.LastError = 'You need to add at least one value!'; return; } if ($AddConfig -eq $FALSE) { $Result = $DefaultIndex; $global:Icinga.InstallWizard.LastInput = $Result; } $global:Icinga.InstallWizard.LastValues = $StoredValues; break; }; default { if ($AddConfig) { if ($ConfigLimit -eq -1 -Or $ConfigLimit -gt $StoredValues.Count) { if ([string]::IsNullOrEmpty($Result) -eq $FALSE) { $StoredValues += $Result; if ($ConfigElement) { Add-IcingaForWindowsInstallerConfigEntry -Values $StoredValues -Hidden:$HiddenConfigElement -PasswordInput:$PasswordInput -Advanced:$Advanced; } $global:Icinga.InstallWizard.LastValues = $StoredValues; } else { if ($DefaultValues.Count -ne 0) { $global:Icinga.InstallWizard.LastNotice = 'Empty values are not allowed! Resetting to default.'; } else { $global:Icinga.InstallWizard.LastError = 'You cannot add an empty value!'; } } } else { $global:Icinga.InstallWizard.LastError = [string]::Format('You can only add {0} value(s)', $ConfigLimit); } return; } if ((Test-Numeric $Result) -eq $FALSE -Or $KnownIndexes.ContainsKey([string]$Result) -eq $FALSE) { $global:Icinga.InstallWizard.LastError = [string]::Format('Invalid selection has been made: {0}', $Result); return; } break; }; } [bool]$DisabledMenu = $FALSE; [string]$DisabledReason = ''; $NextMenu = $null; $NextArguments = @{ }; $ActionCmd = $null; $ActionArgs = $null; if ([string]::IsNullOrEmpty($Result) -eq $FALSE) { if ($Result -eq 'c') { if ([string]::IsNullOrEmpty($ContinueFunction) -eq $FALSE) { $NextMenu = $ContinueFunction; } else { $NextMenu = $Entries[0].Command; if ($null -ne $Entries[0].Disabled) { $DisabledMenu = $Entries[0].Disabled; if ($null -ne $Entries[0].DisabledReason) { $DisabledReason = $Entries[0].DisabledReason; } } } $ActionCmd = $Entries[0].Action.Command; $ActionArgs = $Entries[0].Action.Arguments; } else { $NextMenu = $Entries[$Result].Command; if ($null -ne $Entries[$Result].Disabled) { $DisabledMenu = $Entries[$Result].Disabled; if ($null -ne $Entries[0].DisabledReason) { $DisabledReason = $Entries[0].DisabledReason; } } if ($Entries[$Result].ContainsKey('Arguments')) { $NextArguments = $Entries[$Result].Arguments; } $ActionCmd = $Entries[$Result].Action.Command; $ActionArgs = $Entries[$Result].Action.Arguments; } } if ($DisabledMenu) { if ([string]::IsNullOrEmpty($DisabledReason) -eq $FALSE) { $DisabledReason = [string]::Format(' => Reason: {0}', $DisabledReason); } $global:Icinga.InstallWizard.LastNotice = [string]::Format('This menu is not enabled: {0}{1}', $Result, $DisabledReason); return; } if ([string]::IsNullOrEmpty($NextMenu)) { $global:Icinga.InstallWizard.LastNotice = [string]::Format('This menu is not yet implemented: {0}', $Result); return; } if ($Advanced -eq $FALSE) { Add-IcingaForWindowsManagementConsoleLastParent; } if ($JumpToSummary) { $NextMenu = 'Show-IcingaForWindowsInstallerConfigurationSummary'; } if ($ConfigElement) { Add-IcingaForWindowsInstallerConfigEntry ` -InstallerStep (Get-IcingaForWindowsManagementConsoleMenu) ` -Selection $Result ` -Values $StoredValues ` -Hidden:$HiddenConfigElement ` -PasswordInput:$PasswordInput ` -Advanced:$Advanced ` -NoConfigSwap:$NoConfigSwap; } # Reset Help View $global:Icinga.InstallWizard.ShowHelp = $FALSE; $global:Icinga.InstallWizard.ShowCommand = $FALSE; if ($NextMenu -eq 'break') { return; } $global:Icinga.InstallWizard.NextCommand = $NextMenu; $global:Icinga.InstallWizard.NextArguments = $NextArguments; if ($Automated) { return; } # In case a action is defined, execute the given action if ([string]::IsNullOrEmpty($ActionCmd) -eq $FALSE) { if ($null -eq $ActionArgs -Or $ActionArgs.Count -eq 0) { $ActionArgs = @{ }; } else { while ($TRUE) { [bool]$ModifiedAllArgs = $TRUE; foreach ($entry in $ActionArgs.Keys) { if ($ActionArgs[$entry].GetType().Name -ne 'Boolean' -And $ActionArgs[$entry] -eq '$DefaultValues$') { $ActionArgs[$entry] = $StoredValues; $ModifiedAllArgs = $FALSE; break; } } if ($ModifiedAllArgs) { break; } } } & $ActionCmd @ActionArgs | Out-Null; } } |