PowerShell Menus ($Host.UI.PromptForChoice) – Defined or… Dynamic!

Sometimes, we want to interact with the user who runned a script. The main purpose of this interaction is that the script can do different actions.
Ok, if we know the list, we can use parameters (inline or in a .ini file but for our most mentally challenged fellow, a menu with the different possible choices could be a good option.
So, we won’t reinvent the wheel here and only post the example from Microsoft in the Windows PowerShell Tip: Adding a Simple Menu to a Windows PowerShell Script

$title = "Delete Files"
$message = "Do you want to delete the remaining files in the folder?"

$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
    "Deletes all the files in the folder."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
    "Retains all the files in the folder."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0) 

switch ($result)
    {
        0 {"You selected Yes."}
        1 {"You selected No."}
    }

 
Ok. And now, what about the case in which we don’t know the options we’ll offer to the script’s user?
I mean, sometimes, we’ll need to ask to the user to choose between options the script has just retrieved. For example, I used that one in the Create-Website script to get the IP addresses defined on the server, and offer to the user to choose on what IP address the “to be created” website will listen on.
Enough chit-chat, let see the example

function Read-Choice {     
	Param(
		[System.String]$Message, 
		
		[Parameter(Mandatory = $true)]
		[ValidateNotNullOrEmpty()]
		[System.String[]]$Choices, 
		
		[System.Int32]$DefaultChoice = 1, 
		
		[System.String]$Title = [string]::Empty 
	)        
	[System.Management.Automation.Host.ChoiceDescription[]]$Poss = $Choices | ForEach-Object {            
		New-Object System.Management.Automation.Host.ChoiceDescription "&$($_)", "Sets $_ as an answer."       
	}       
	$Host.UI.PromptForChoice( $Title, $Message, $Poss, $DefaultChoice )     
}

Function Select-IPAddress {
	[cmdletbinding()]
	Param(
		[System.String]$ComputerName = 'localhost'
	)
	$IPs = Get-WmiObject -ComputerName $ComputerName -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" | ForEach-Object {
		$_.IPAddress
	} | Where-Object { 
		$_ -match "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" 
	}
	Write-Log $IPs
	if($IPs -is [array]){
		Write-Host "`nServer $ComputerName uses those IP addresses:`n"
		$IPs | ForEach-Object { $Id = 0 } { Write-Host "$Id : $_"; $Id++ }
		$IPs[(Read-Choice -Message "`nChoose IPAddress" -Choices (0..($ID-1)) -DefaultChoice 0)]	
	}
	else{
		$IPs
	}
}
Select-IPAddress

Leave a Reply

Scroll to Top