selecting multiple options from the menu list - powershell

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'))
}
# Step 2) define the array of packages you are offering
$Packages = 'googlechrome',
'firefox',
'codeblocks',
'windbg',
'nasm',
'explorersuite',
'pestudio',
'vscode',
'sysinternals',
'python',
'ccleaner',
'anaconda3',
'wireshark',
'sublimetext3',
'notepadplusplus',
'Exit'
# Step 3) define the Show-Menu function
function Show-Menu
{
Clear-Host
Write-Host "**********************************************"
Write-Host "LIST OF SOFTWARES"
# write the options using the array of packages
for ($i = 0; $i -lt $Packages.Count; $i++)
{
# {0,10} means right align with spaces to max 2 characters
Write-Host ('{0,10}. {1}' -f ($i + 1), $Packages[$i])
}
Write-Host " q. Exit the script"
Write-Host "*************************************************"
Write-Host
}
# Step 4) enter an endless loop you only exit if the user enters 'q'
while ($true)
{
Show-Menu
# $UserInput = Read-Host "Enter the software number to be installed"
$UserInput = Read-Host "Select the softwares number(s) to be installed"
$ok = $UserInput -match '[123456789101112131415]+$'
if( -not $ok)
{
write-host "Invalid selection"
sleep 2
write-host ""
}
until ($ok)
switch -Regex ($UserInput)
{
"1" {googlechrome}
"2" {firefox}
"3" {codeblocks}
"4" {windbg}
"5" {nasm}
"6" {explorersuite}
"7" {pestudio}
"8" {vscode}
"9" {sysinternals}
"10" {python}
"11" {ccleaner}
"12" {anaconda3}
"13" {wireshark}
"14" {sublimetext3}
"15" {notepadplusplus}
} until ($ok)
# test if the user wants to quit and if so, break the loop
if ($UserInput -eq 'q') { break }
# test if the user entered a number between 1 and the total number of packages (inclusive)
if ([int]::TryParse($UserInput,[ref]$null) -and 1..$Packages.Count -contains [int]$UserInput)
{
# here you install the chosen package using the array index number (= user input number minus 1)
$packageIndex = [int]$UserInput - 1
Write-Host "Installing $($Packages[$packageIndex])"
# Choco install $Packages[$packageIndex] -y
Choco install $Packages[$packageIndex] -y --ignore-checksums
}
else
{
$availableOptions = 1..$Packages.Count -join ','
Write-Host "Error in selection, choose $availableOptions or q" -Foreground Color Red
}
$null = Read-Host "Press Enter to continue"
}
I have written the script which is working when the user select the number then that corresponding software will be downloaded and installed. Now instead of selecting one option the user selects multiple options from the menu list then that software's will be downloaded and installed parallely so, I have modified my script for selecting multiple options but the script is not working so, please tell me how to achieve this functionality. Thanks in Advance

I've removed the parts which (for me) made no sense or produced errors in my environment - removed the option 'Exit' from $Packages and added the foreach part. So now the user can enter several numbers space separated so that $UserInput contains e.g. 1 2. this is then split an iterated in the foreach part.
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'))
# Step 2) define the array of packages you are offering
$Packages = 'googlechrome',
'firefox',
'codeblocks',
'windbg',
'nasm',
'explorersuite',
'pestudio',
'vscode',
'sysinternals',
'python',
'ccleaner',
'anaconda3',
'wireshark',
'sublimetext3',
'notepadplusplus'
# Step 3) define the Show-Menu function
function Show-Menu
{
Clear-Host
Write-Host "**********************************************"
Write-Host "LIST OF SOFTWARES"
# write the options using the array of packages
for ($i = 0; $i -lt $Packages.Count; $i++)
{
# {0,10} means right align with spaces to max 2 characters
Write-Host ('{0,10}. {1}' -f ($i + 1), $Packages[$i])
}
Write-Host " q. Exit the script"
Write-Host "*************************************************"
Write-Host
}
# Step 4) enter an endless loop you only exit if the user enters 'q'
while ($true)
{
Show-Menu
$UserInput = Read-Host "Select the softwares number(s) to be installed (space separated)"
# test if the user wants to quit and if so, break the loop
if ($UserInput -eq 'q') { break }
foreach($input in $UserInput.Split(' ')) {
# test if the user entered a number between 1 and the total number of packages (inclusive)
if ([int]::TryParse($input,[ref]$null) -and 1..$Packages.Count -contains [int]$input)
{
# here you install the chosen package using the array index number (= user input number minus 1)
$packageIndex = [int]$input - 1
Write-Host "Installing $($Packages[$packageIndex])"
Choco install $Packages[$packageIndex] -y --ignore-checksums
} else {
$availableOptions = 1..$Packages.Count -join ','
Write-Host "Error in selection, choose $availableOptions or q" -Foreground Color Red
}
}
$null = Read-Host "Press Enter to continue"
}

Related

Powershell script for software automation

function show-menu
{
Clear-Host
write-host "**********************************************"
write-host "LIST OF SOFTWARES"
write-host " 1. googlechrome"
write-host " 2. firebox"
write-host " 3. CodeBlocks"
write-host " 4. windbg"
write-host " 5. nasm"
write-host " 6. explorer suite"
write-host " 7.pestudio"
write-host " 8.vscode"
write-host " 9. sysinternals"
write-host " 10. python"
write-host " q. Exit the script"
write-host " ************************************************"
}
do
{
show-menu
$UserInput = read-host "Enter the software number to be installed "
switch($UserInput)
{
1 {googlechrome;
pause
}
2 {firefox;pause}
3 {codeblocks;pause}
4 {windbg;pause}
5 {nasm;pause}
6 {explorersuite;pause}
7 {pestudio;pause}
8 {vscode;pause}
9{sysinternals;pause}
10{python;pause}
q {break}
default {write-host "Error in selection, choose 1,2,3,4,5,6,7,8,9,10 or q";pause}
}
}
while ($UserInput -ne 'q')
$Packages = 'googlechrome',
'firefox',
'codeblocks',
'windbg',
'nasm',
'explorersuite',
'pestudio',
'vscode',
'sysinternals',
'python'
If(Test-Path -Path "$env:ProgramData\Chocolatey")
{
### Installing Packagers
ForEach($PackageName in $Packages)
{
choco install $PackageName -y
}
}
Else
{
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]:: SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
###### package install stuff ###############
ForEach($PackageName in $Packages)
{
Choco install $PackageName -Y
}
}
The script is not working properly. when i enter any number the software is not downloading but when i quit the software is downloding if anything is wrong in my script please tell me how to do it and in my system already some of the softwares are already installed but the script is downloading that software but during installing the script is giving message that the software is already installed. I need to put some condition in my script that if the software is already installed in the pc the script should not download the software it simply should give message like the software is already installed.
please help me in accomplishing my task
Thanking you
Thanking you
enter code here
do
{
show-menu
$Packages = 'googlechrome','firefox','codeblocks', 'windbg','nasm','explorersuite','pestudio','vscode','sysinternals','python'
$UserInput = read-host "Enter the software number to be installed "
switch($UserInput)
{
case1: {googlechrome;pause}
If(Test-Path -Path "$env:ProgramData\Chocolatey")
{
### Installing Packagers
ForEach($PackageName in $Packages)
{
choco install $PackageName -y
}
}
Else
{
############### INSTALLING CHOCOLATEY ####################################################################################
########### Before Executing the script type the command in the powershell terminal to get the admin rights ##############
########## Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass ##################################################
Set-ExexutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]:: SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
###### package install stuff ###############
ForEach($PackageName in $Packages)
{
choco install $PackageName -Y
}
}
case2: {firefox;pause}
If(Test-Path -Path "$env:ProgramData\Chocolatey")
{
### Installing Packagers
ForEach($PackageName in $Packages)
{
choco install $PackageName -y
}
}
Sir is it correct way iam getting missing statement block in switch statement clause
Ok, I would change the script to do this:
# Step 1) install Chocolatey when needed
if (-not (Test-Path -Path "$env:ProgramData\Chocolatey\choco.exe" -PathType Leaf)) {
# from https://chocolatey.org/install
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
# Step 2) define the array of packages you are offering
$Packages = 'googlechrome','firefox','codeblocks','windbg','nasm',
'explorersuite','pestudio','vscode','sysinternals','python'
# Step 3) define the Show-Menu function
function Show-Menu {
Clear-Host
Write-Host "**********************************************"
Write-Host "LIST OF SOFTWARES"
# write the options using the array of packages
for ($i = 0; $i -lt $Packages.Count; $i++) {
# {0,2} means right align with spaces to max 2 characters
Write-Host ('{0,2}. {1}' -f ($i + 1), $Packages[$i])
}
Write-Host " q. Exit the script"
Write-Host "*************************************************"
Write-Host
}
# Step 4) enter an endless loop you only exit if the user enters 'q'
while ($true) {
Show-Menu
$UserInput = Read-Host "Enter the software number to be installed"
# test if the user wants to quit and if so, break the loop
if ($UserInput -eq 'q') { break }
# test if the user entered a number between 1 and the total number of packages (inclusive)
if ([int]::TryParse($UserInput,[ref]$null) -and 1..$Packages.Count -contains [int]$UserInput) {
# here you install the chosen package using the array index number (= user input number minus 1)
$packageIndex = [int]$UserInput - 1
Write-Host "Installing $($Packages[$packageIndex])"
choco install $Packages[$packageIndex] -y
}
else {
$availableOptions = 1..$Packages.Count -join ','
Write-Host "Error in selection, choose $availableOptions or q" -ForegroundColor Red
}
$null = Read-Host "Press Enter to continue"
}

Do-Until loop ask twice value

The problem is with loop DoUntil.
The script must take the URL, than ask what to do with him and gave the result after the user pick the number(1-4)
and with output give the menu again, and user can pick another number if he want or finish the script typing 'X'.
But this script works in a different way, it is ask for URL, after I will pick the number, and after this it asks again the URL and again the number and after this(if for example I will pick twice the same number) it will bring me the value of 2 URLs together.
Please, advice, what I'm doing wrong.
write-host ""
write-host "Past URL that you need to check"
write-host ""
write-host -nonewline "Type your URL and press Enter: "
$URLok = read-host
write-host ""
if ($URLok.Length -lt 1) {
write-host "Invalid selection"
}
do {
write-host "What do you want to do with this URL?"
write-host ""
write-host "DNS - Selection 1"
write-host " MX - Selection 2"
write-host " NS - Selection 3"
write-host "TXT - Selection 4"
write-host ""
write-host "X - Exit"
write-host ""
write-host -nonewline "Type your choice and press Enter: "
$choice = read-host
$ok = $choice -match '^[1234x]+$'
if ( -not $ok) {
write-host "Invalid selection"
}
switch -Regex ( $choice ) {
"1"
{
[System.Net.Dns]::resolve($URLok)
}
"2"
{
Resolve-DnsName -Name $URLok -Type MX -DnsOnly | select Name,Type,NameExchange
}
"3"
{
Resolve-DnsName -Name '888ladies.com' -Type NS -DnsOnly | select Name,Type,NameHost,PrimaryServer
}
"4"
{
Resolve-DnsName -Name $URLok -Type TXT | select Name,Type,Strings
}
"5"
{
write-host ""
write-host "Past URL that you need to check"
write-host ""
write-host -nonewline "Type your URL and press Enter: "
$URLok = read-host
write-host ""
}
}
} while($choice -ne "X")
P.s. And Little remark, in the 2-3-4 options I have 'Resolve-DNSName' but this script wouldn't show it on the console before the loop doUntil finished. So I can see the result only if I pick 'X' and finish the loop
The answer was with the pip Format-Table and it's work!
For Example:
Resolve-DnsName -Name $URLok -Type NS -DnsOnly | select Name,Type,NameHost,PrimaryServer| Format-Table

Powershell scripting check and change location help needed

I have written the following script:
clear-host
## Step 1 (Creating 2 command line variables)
##########################################################################################################################
Clear-Host
$WorkingDirectory = $ARGS[0]
$DirectoryName = $ARGS[1]
##Step 2 (Check if variables are empty and get user input if necessary)
##########################################################################################################################
if ("$WorkingDirectory" -eq "")
{
Write-Warning "Parameter Required"
$WorkingDirectory = Read-Host "Enter the absolute path to working directory "
}
if ("$DirectoryName" -eq "")
{
Write-Warning "Paramater Required"
$DirectoryName = Read-Host "Enter a directory name to search for in $WorkingDirectory "
}
for ($i=0; $i -le 2; $i++) {write-host ""} # to print 2 blank lines using for loop
##Step 3 (Test to see if PWD is equal to $WorkingDirectory and if not move the location )
##########################################################################################################################
if ("$PWD" -ne "$WorkinDirectory")
{
write-host "You are not in the < $WorkingDirectory > . Do you wish to move? Press CTRL+C to exit or wait"
write-host ""
pause
Set-Location -Path $WorkingDirectory
}
##Step 4 (Test to see the directory exists in the working directory or not )
##########################################################################################################################
if((Test-Path $DirectoryName) -ne "True")
{
write-host "Directory $DirectoryName does not exist"
}
The problem I am facing at step 3. It should check my present location with the $WorkingDirectory variable, if they are not same then the location will be changed. But the problem is even if I am at the same location as the $WorkingDirectory it is still giving me the warning message. how to solve that

Jumping to another section in a PowerShell script

I want to jump from one section in the script to another section in the same PowerShell script. My script is only going from top to bottom right now, but I have several tasks. e.g. I want to be able to choose from a task list in the beginning of the script and go to task number 2 skip task 1.
I hope this makes any sense for you. Take a look at my script:
Write-Host -ForegroundColor Yellow "welcome to my powershell script..."
""
""
""
Start-Sleep -Seconds 1
Write-Host -ForegroundColor Yellow "Choose a task:"
""
""
Write-Host -ForegroundColor Yellow "1. Clean up"
Write-Host -ForegroundColor Yellow "2. Uninstall Pre-Installed Apps"
Write-Host -ForegroundColor Yellow "3. Something should be written here"
""
""
""
While ($Valg -ne "1" -or $Valg -ne "2" -or $Valg -ne "3") {
$Valg = Read-Host "Choose a number from the task list"
If ($Valg –eq "1") { Break }
If ($Valg –eq "2") { Break }
If ($Valg –eq "3") { Break }
if ($Valg -ne "1" -or $Valg -ne "2" -or $Valg -ne "3") {
""
Write-Host -ForegroundColor Red "Ups. Try again..."
}
}
#### 1. First task should come here (clean up)
#some code here for the "cleaning up" task
#### 2. Second task here
#some code here for the "Uninstall Pre-Installed Apps" task
#### 3. Third task there
#Some code for the third task here
#### And so on...
Here is a generic solution which uses an array of PSCustomObject that represents the task (message and the function to invoke). It doesn't need a switch, you can simply add new Tasks to the array (and implement the desired function) without modifying the remaining script:
# define a task list with the messages to display and the functions to invoke:
$taskList = #(
[PSCustomObject]#{Message = 'Clean up'; Task = { Cleanup }}
[PSCustomObject]#{Message = 'Uninstall Pre-Installed Apps'; Task = { Uninstall }}
[PSCustomObject]#{Message = 'Something should be written here'; Task = { Print }}
)
# define the functions:
function Cleanup()
{
Write-Host "Cleanup"
}
function Uninstall()
{
Write-Host "Uninstall"
}
function Print()
{
Write-Host "Print"
}
# let the user pick a task:
Write-Host -ForegroundColor Yellow "Choose a task:"
$taskList | foreach -Begin { $i = 1;} -Process {
Write-Host -ForegroundColor Yellow ('{0}. {1}' -f ($i++), $_.Message)
}
do
{
$value = Read-Host 'Choose a number from the task list'
}
while($value -match '\D+' -or $value -le 0 -or $value -gt $taskList.Count)
# invoke the task:
& $taskList[$value-1].Task
I am updating answer to complete script based on inputs by "bluuf" and "majkinator".
Use the Switch-Case construct along with Functions like below. This is complete working solution.
#region Function Definitions. These come first before calling them
function FirstTask
(
[string] $inputVariable
)
{
"write any scipt for First task here without quotes. Input is: " + $inputVariable
}
function SecondTask
{
"write any scipt for Second task here without quotes"
}
function ThirdTask
{
"write any scipt for Third task here without quotes"
}
#endregion
#region Showing Options
Write-Host -ForegroundColor Yellow "welcome to my powershell script..."
""
""
""
Start-Sleep -Seconds 1
Write-Host -ForegroundColor Yellow "Choose a task:"
""
""
Write-Host -ForegroundColor Yellow "1. Clean up"
Write-Host -ForegroundColor Yellow "2. Uninstall Pre-Installed Apps"
Write-Host -ForegroundColor Yellow "3. Something should be written here"
Write-Host -ForegroundColor Yellow "0. Exit"
""
""
""
#endregion
#region Getting input
While ($true) {
$Valg = Read-Host "Choose a number from the task list"
If ($Valg –eq "0")
{
"Thanks for using my utility";
Break;
}
If (($Valg -ne "1") -and ($Valg -ne "2") -and ($Valg -ne "3") -and ($Valg -ne "0")) {
""
Write-Host -ForegroundColor Red "Ups. Try again..."
}
#region Main Code
switch ($Valg)
{
1{
FirstTask("sending input");
}
2 {
SecondTask;
}
3 {
ThirdTask;
}
default { "Please select a correct option."}
}
#endregion
}
#endregion

How do I allow for multiple selections in a numbered menu?

This is related to my previous question about FTP time stamps. I'm working on a script to help make my job, and hopefully others, better by making PC setups easier. As it is right now everything works perfectly, except I'd like to make it more automated. Right now it only allows for one thing at a time. I'd like to be able to choose multiple numbers and have it run them all one after the other.
This needs to work in Windows 7 without importing any extra modules.
Here's what I have so far:
echo ""
$answer = read-host "Select a number"
echo ""
if ($answer -eq 1){uninstall}
if ($answer -eq 2){flashjava}
if ($answer -eq 3){reader}
if ($answer -eq 4){firefox}
if ($answer -eq 5){chrome}
if ($answer -eq 6){office}
if ($answer -eq 7){reader}
if ($answer -eq 8){updates}
if ($answer -eq 9){exit}
else {write-host -ForegroundColor red "Invalid Selection"
sleep 2
mainmenu
}
echo ""
Instead of choosing option 2 (for example), letting that go, then hitting option 3, and so on I'd like to type "2,3" (no quotes) and have it hit both functions one after the other.
I've looked into foreach loops, but can't get it to work.
echo ""
$num = read-host "Select a number"
echo ""
$num.split(",")
ForEach($answer in $num){
if ($answer -eq 1){uninstall}
if ($answer -eq 2){flashjava}
if ($answer -eq 3){reader}
if ($answer -eq 4){firefox}
if ($answer -eq 5){chrome}
if ($answer -eq 6){office}
if ($answer -eq 7){reader}
if ($answer -eq 8){updates}
if ($answer -eq 9){exit}
}
else {write-host -ForegroundColor red "Invalid Selection"
sleep 2
mainmenu
}
echo ""
I'm aware the Else statement would catch anything other than a single 1-9. I've tried commenting that section out, still nothing. It works if I choose a single number, but not multiples. I've also tried putting the numbers in the if statements in quotes. It also displays the number(s) I've chosen before it either runs the function or quits. I'd like to not display any output.
Thanks!
UPDATE: After looking around I found the switch parameter. Seems to work great!
do {
do {
cls
write-host ""
write-host "****************************"
write-host "** Main Menu **"
write-host "****************************"
write-host ""
write-host "1 - Uninstall Bundled Apps"
write-host "2 - Install Flash & Java"
write-host "3 - Install Adobe Reader"
write-host "4 - Install Firefox"
write-host "5 - Install Chrome"
write-host "6 - Install Office 365"
write-host "7 - Install All"
write-host ""
write-host "8 - Check for Installer Updates"
write-host ""
write-host "9 - Exit"
write-host ""
$answer = read-host "Select number(s)"
$ok = $answer -match '[123456789]+$'
if ( -not $ok) {write-host "Invalid selection"
sleep 2
write-host ""
}
} until ($ok)
switch -Regex ( $answer ) {
"1" {uninstall}
"2" {flashjava}
"3" {reader}
"4" {firefox}
"5" {chrome}
"6" {o365}
"7" {uninstall}
"8" {updates}
}
} until ( $answer -match "9" )
}
You were really close actually. The main problem is that $num.Split() returns the array, but does not modify $num, so when you then use $num in your foreach() loop, you are using the original value. Have a look at the change here:
echo ""
$num = read-host "Select a number"
echo ""
$nums = $num.split(",")
ForEach($answer in $nums){
if ($answer -eq 1){uninstall}
if ($answer -eq 2){flashjava}
if ($answer -eq 3){reader}
if ($answer -eq 4){firefox}
if ($answer -eq 5){chrome}
if ($answer -eq 6){office}
if ($answer -eq 7){reader}
if ($answer -eq 8){updates}
if ($answer -eq 9){exit}
}
# else {write-host -ForegroundColor red "Invalid Selection"
# sleep 2
# mainmenu
# }
# commented out because this else no longer corresponds to anything
echo ""
Now just to clean this up a bit, let's look at it with switch:
echo ""
$num = read-host "Select a number"
echo ""
$nums = $num.split(",")
ForEach($answer in $nums){
switch ($answer) {
1 {uninstall}
2 {flashjava}
3 {reader}
4 {firefox}
5 {chrome}
6 {office}
7 {reader}
8 {updates}
9 {exit}
default {
write-host -ForegroundColor red "Invalid Selection"
sleep 2
mainmenu
}
}
}
echo ""