Dynamic input array Powershell - powershell

once again I contact you because I am once again having problems with a Powershell script assignment.
My current assignement is to make a script that lets a user put in 1-10 values. The values have to be positive numbers. After that I have to calculate an average of an array.
My idea in this was the following:
clear-host
$averageArray = #()
Write-Host "How many numbers do you want to put in?" -for yellow
Write-Warning "Maximum is 10!"
Write-Host "Press the Enter key to continue."
$amountValues = Read-host
while($amountVAlues -notmatch "^([1-9]|[1][0])$") {
$amountValues = Read-Host "Please enter a number between 1 and 10"
if($amountVAlues -notmatch "^([1-9]|[1][0])$") {Write-host "Error! Please enter a number between 1 and 10!"}
}
$value1 = read-host "Enter number one"
while($value1 -notmatch '^\d+$') {
$value1 = Read-Host
if($value1 -notmatch '^\d+$') {Write-host "Error! Please enter a positive number!"}
}
$value2 = read-host "Enter number two"
while($value2 -notmatch '^\d+$') {
$value2 = Read-Host
if($value2 -notmatch '^\d+$') {Write-host "Error! Please enter a positive number!"}
}
$averageArray = $averageArray + $value1
write-host "$averageArray"
read-host
I created an array, and made the user input a number between 1-10 for the amount of total $values they want in the array. After that I wanted to loop the input of a $value, and input it in the array. I wanted to loop it as many times as the $amountValues variable.
Problem with doing this is that if I would loop it, $variable1 would get overwritten an 'x' amount of times.
Is there any way to input the values via a loop into the array?

I'ld do it like this:
while ( (1..10) -notcontains $g)
{
$g = read-host "How many numbers do you want to put in? (value from 1 to 10) "
}
$ar=#()
for ($i=0; $i -lt $g; $i++)
{
$ar += read-host "Enter value $($i+1)"
}
$averageArray = ($ar | Measure-Object -Average).average
write-host "Average is : $averageArray"

Related

Increase Substring length dynamically

I am new to the community and need some help in Powershell.
I want the following code to dynamically check if the specific $sAMAccountName exists in an array or not.
If it exists, keep increasing the substring length by 1 and check the array again.
Instead of defining more variables like $sAMAccountName1 and $sAMaccountName2 (and so on) manualy.
$Nachname = "Nachname"
$Vorname = "Vorname"
$sAMAccountName = $Nachname+$Vorname.Substring(0,1)
$sAMAccountName1 = $Nachname+$Vorname.Substring(0,2)
$sAMAccountName2 = $Nachname+$Vorname.Substring(0,3)
$Array = #('NachnameV','NachnameVo','NachnameVor')
if($sAMAccountName -notin $Array){
Write-Host "$sAMAccountname does not exist :-)"
}
elseif($sAMAccountName1 -notin $Array){
Write-Host "$sAMAccountName1 does not exist :-)"
}
elseif($sAMAccountName2 -notin $Array){
Write-Host "$sAMAccountName2 does not exist :-)"
}
else{
Write-Host "$sAMAccountName2 does exist :-("
}
Thank you for your help.
Greetings,
PalimPalim
This may do what you need :
$Nachname = "Nachname"
$Vorname = "Vorname"
#$sAMAccountName = $Nachname+$Vorname
$Array = #('NachnameV','NachnameVo','NachnameVor')
$i = 0
do {
$i++
$sAMAccountName = $Nachname+$Vorname.Substring(0,$i)
write-host "i = $i"
write-host "account name = $sAMAccountName"
if($sAMAccountName -in $Array){
Write-Host "$sAMAccountName found"
}
} until ($sAMAccountName -notin $array)
Write-Host "$($Nachname+$Vorname.Substring(0,$i)) not found"
Where $i is used as an index which increases by 1 within the do until loop until the name being searched for no longer shows up in the array.
The write-host lines for i=$i and the account name aren't needed, but just let you see what the script is doing on each iteration round the loop, and can be removed.

Build an interactive menu using powershell

Below script will display the menu and prompt for a selection.However this doesn't give the option to reselect if the selection is made wrong.
I would like to re write in such a way that , it should give the option to confirm the selection and if the selection is made wrong, should give an option to re select from the menu. Is it possible using "do until" loop? Any help is high appreciated
write-host ""
Write-host -ForegroundColor yellow "Choose which Cluster you want to gather ratios on:"
write-host "(it may take a few seconds to build the list)"
write-host ""
$ICLUSTER = get-cluster -server $VIServer | Select-Object Name | Sort-object Name
if ($null -eq $ICLUSTER)
{
Update-log "Unable to find Cluster Information.Please verify the cluster status before proceed `n"
break
}
else
{
$i = 1
$ICLUSTER | %{Write-Host $i":" $_.Name; $i++}
$HCLUSTER = Read-host "Choose the name of cluster you want to select on by entering corresponding number:"
$SCLUSTER = $ICLUSTER[$HCLUSTER -1].Name
Update-log "You have selected $($SCLUSTER). `n"
start-sleep -s 3
}
A loop & couple additional if statements should get you there:
# break the loop by setting $x not equal to 1
$x = 1
While ($x -eq 1){
$ICLUSTER = get-cluster -server $VIServer | Select-Object Name | Sort-object Name
if ($null -eq $ICLUSTER){
Update-log "Unable to find Cluster Information. Please verify the cluster status before proceed `n"
$x = 2
}
else{
$i = 1
$ICLUSTER | %{Write-Host $i":" $_.Name; $i++}
$HCLUSTER = Read-host "Choose the name of cluster you want to select on by entering corresponding number:"
$SCLUSTER = $ICLUSTER[$HCLUSTER -1].Name
if ($SCLUSTER -in $ICLUSTER.Name){
Write-Host "You have selected $($SCLUSTER), do you want to continue?"
$yesno = Read-host "Please type 'Y' to continue or 'N' to quit"
if ($yesno -eq "Y"){
$x = 1
}
else {Write-Host "Quitting"
$x = 2
}
Write-Host "Performing commands"
# Add commands here, to do the work & complete the task
$x = 2
}
elseif (-not($SCLUSTER -in $ICLUSTER.Name)){
Write-Host "Your selection was not found, Would you like to try again?"
$yesno = Read-host "Please type 'Y' to try again or 'N' to quit"
if ($yesno -eq "Y"){
Write-Host "Trying this again"
$x = 1
}
else {Write-Host "Quitting"
$x = 2
}
}
start-sleep -s 3
}
}

My if loop is taking effect even when it should not

I am making a random number guessing program where users try to guess a number between 1 and 100 while receiving whether they were higher or lower. one of the stipulations was that there must be a function to quit the program upon the user entering Q or q so I formatted my loop as such:
$RandomNumber = Get-Random -Minimum 1 -Maximum 101
write-output $RandomNumber
$GuessNumber = 0
While ($RandomNumber -ne $Guess)
{
$Guess = Read-Host -Prompt 'Guess a number between 1 and 100 Or enter Q to quit'
if ($Guess -eq 'q' -or 'Q')
{
Write-output "Thank you for playing"
BREAK
}
if ($Guess -gt 100 -or $Guess -le 1)
{
Write-Output 'Invalid Input please enter a number between 1 and 100'
}
if ($Guess -le $RandomNumber)
{
Write-output 'Your number is lower than the hidden number please guess again'
$GuessNumber = $GuessNumber +1
}
if ($Guess -gt $RandomNumber)
{
Write-output 'Your number is higher than the hidden number please guess again'
$GuessNumber = $GuessNumber +1
}
if ($Guess -eq $RandomNumber)
{
$GuessNumber = $GuessNumber +1
Write-output 'Congratulations you guessed the number in' $GuessNumber 'tries'
}
}
the issue I run into is even when the input is equal to 10 for example it still outputs "Thank you for playing" meaning that if loop has taken effect. I am not sure why this occurs as I'm new to powershell and a reasoning for this happening would be helpful
Replace
if ($Guess -eq 'q' -or 'Q')
with
if ($Guess -eq 'q' -or $Guess -eq 'Q')
Your error partially comes from -or 'Q' which evaluates to $true always:
$false -or 'somestring' # => True
And it's also worth noting, -eq is case insensitive ('q' -eq 'Q' is $true).The other error comes from comparing a string with an integer. The output from Read-Host is System.String in this case:
'50' -gt 100 # => True
'50' -lt 100 # => False
On the other hand, you could make your code more readable using a switch statement. For input validation you could use a recursive script block to make sure its always right (between 1 and 100 or Q). To break the outer while loop you can use a labeled break.
$RandomNumber = Get-Random -Minimum 1 -Maximum 101
$validation = {
$choice = Read-Host 'Guess a number between 1 and 100 Or enter Q to quit'
if($choice -notmatch '^([1-9][0-9]?|100|q)$') {
Write-Warning 'Invalid Input, try again.'
return & $validation
}
$choice
}
$attempts = 0
:outer while($true) {
$choice = & $validation
if($choice -eq 'q') {
# End the Game
'Thanks for Playing'
break
}
$attempts++
switch([int]$choice) {
{$_ -gt $RandomNumber} {
"$_ was greater than hidden number"
break
}
{$_ -lt $RandomNumber} {
"$_ was lower than hidden number"
break
}
default {
"You guessed right after $attempts tries, Congratulations!"
break outer
}
}
}
The condition is wrong. $Guess -eq 'q' -or 'Q' returns true always, it should be $Guess -eq 'q' -or $Guess -eq 'Q'.

Finding Middle Number in PowerShell

I am practicing in PowerShell and am making a user response input where one of the options is to input 3 numbers, and the program will return the middle number. I have done this a million times and it seems I cannot get it to return the middle number consistently.
For example when my numbers are 1, 23452342 and 3, it says that 3 is the middle number.
Here is my code:
if ($response -eq 1) {
$a = Read-Host "Enter a number "
$b = Read-Host "Enter a second number "
$c = Read-Host "Enter a third number "
if (($a -gt $b -and $a -lt $c) -or ($a -lt $b -and $a -gt $c)) {
Write-Host "$a is the middle number"
}
if (($b -gt $a -and $b -lt $c) -or ($b -gt $c -and $b -lt $a)) {
Write-Host "$b is the middle number"
}
if (($c -gt $a -and $c -lt $b) -or ($c -gt $b -and $c -lt $a)) {
Write-Host "$c is the middle number"
}
}
Instead of doing a number of individual comparisons simply sorting the three values and picking the second element will give you the median right away. But I suspect what's actually messing up the results for you is that Read-Host returns strings when you need them to be numeric values. Sort order of strings ("1" < "20" < "3") is different from numeric sort order (1 < 3 < 20), because characters at corresponding positions are compared rather than the whole number.
Casting the entered values to integers (or doubles if you expect floating point numbers) should resolve the issue:
if ($response -eq 1) {
[int]$a = Read-Host 'Enter a number'
[int]$b = Read-Host 'Enter a second number'
[int]$c = Read-Host 'Enter a third number'
$n = ($a, $b, $c | Sort-Object)[1]
Write-Host "$n is the median."
}
As an additional solution that would work on any array where u need the middle item you could just solve it like this:
$arr = 1..50
($arr | Sort-Object)[[int](($arr.count -1) /2)]
If your array comes in a format that does not need the sorting, just leave this part out.
edit: Obviously you would have to insert the data into an array on the first step.
Best regards

Powershell Do Until Loop

$StartID = Read-Host -Prompt "StartID"
$StopID = Read-Host -Prompt "StopID"
$i = $StartID
do {
Write-Host $startID
Write-Host $StopID
$i = ($StartId + 1)
} until ($i -gt $StopID)
The first problem is that after the statement $i = $startid + 1, the $i equals 11 and not 2.
The second problem is that even though the until statement says that it should stop when $i -gt $stop the loop continues forever.
How do I get the $i to increase by 1 and not 10 and how do I stop the loop when $i -gt $stop.
Read-Promptreturns a string per default (this stackoverflow answer explains different ways for conversion). You've to convert/cast the string to a numeric value:
[int]$start = Read-Host -Prompt "Start"
[int]$stop = Read-Host -Prompt "Stop"
do {
Write-host $start
$start++
} until ($start -ge $stop)
Hope that helps.