i created this script which installs chocolatey and previous in the script "selected" packages (deselection happens with the #). now i want to customize the script in a way that allows to chose the packages to install while running the script. is it possible to create kind of a menu, which allows to select/deselect the packages to be beinstalled while running the script ? maybe someone can give me a hint.
# Install Chocolatey and All Apps listed in the $Packages variable
param([switch]$Elevated)
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((Test-Admin) -eq $false) {
if ($elevated) {
# tried to elevate, did not work, aborting
} else {
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
}
exit
}
Write-Host "Running with full priviliges" -ForegroundColor Red -BackgroundColor Yellow
pause
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
choco install abaclient
choco install pdfxchangeeditor -params "'/NoUpdater /NoUpdater'"
# choco install notepadplusplus.install
choco install winrar
choco install firefox
There are of course many ways to create some kind of menu. Here's two ideas for you:
You could use Out-GridView
to select the packages to install like this
# create an array with all possible installs
$allPackages = 'winrar', 'notepadplusplus', 'abaclient','firefox' | Sort-Object
$selected = $allPackages | Out-GridView -Title 'Select Packages to install' -PassThru
if (@($selected).Count) {
$selected | ForEach-Object { choco install $_ }
}
else {
Write-Host 'Nothing selected..'
}
Or you could create a selection form of your own like the one below that makes use of a CheckedListBox control:
# create an array with all possible installs
$allPackages = 'winrar', 'notepadplusplus', 'abaclient','firefox' | Sort-Object
$selected = $null
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = [System.Windows.Forms.Form]::new()
$form.Text = 'Select Packages to install'
$form.Size = [System.Drawing.Size]::new(500,300)
$form.StartPosition = 'CenterScreen'
$form.FormBorderStyle = 'FixedDialog'
$form.TopMost = $true
# create a CheckedListBox control
$checkedListBox = [System.Windows.Forms.CheckedListBox]::new()
$checkedListBox.Location = [System.Drawing.Size]::new(20,20)
$checkedListBox.Size = [System.Drawing.Size]::new(440,200)
$checkedListBox.CheckOnClick = $true
$checkedListBox.ClearSelected()
# add the items to install to the list
foreach ($package in $allPackages) {
[void]$checkedListBox.Items.Add($package, $false)
}
$form.Controls.Add($checkedListBox)
# Add a button to the form
$okButton = [System.Windows.Forms.Button]::new()
$okButton.Text = 'OK'
$okButton.Location = [System.Drawing.Point]::new(20,230)
$okButton.Add_Click({
# capture the chosen items in a variable and close the form
$script:Selected = $checkedListBox.CheckedItems | ForEach-Object {$_.ToString()}
$form.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.Close()
})
$form.Controls.Add($okButton)
$form.AcceptButton = $okButton
# display the form
[void]$form.ShowDialog()
# and destroy it when done so it doesn't linger in memory
$form.Dispose()
if (@($selected).Count) {
$selected | ForEach-Object { choco install $_ }
}
else {
Write-Host 'Nothing selected..'
}
It seems installing with choco sometimes needs a different install string than just the name of the package. To handle that, I would create a Hashtable with the package name as key and the install string as value:
$installStrings = @{
notepadplusplus = "notepadplusplus.install"
pdfxchangeeditor = "-params '`"/NoUpdater`"'" # note the backticks to escape the embedded double-quotes
}
Then, instead of line $selected | ForEach-Object { choco install $_ }
, you do:
$selected | ForEach-Object {
if ($installStrings.ContainsKey($_)) {
choco install $($installStrings[$_])
}
else { choco install $_ }
}