-Contains operator not working powershell - powershell

All I'm trying to do is to see if the user input $month is in the array $months. But it's not liking something. Help?
Write-host "The script is to collect from the user High Tempature and Low Tempature for a day in degrees F."
$months = #("January", "February","March","April","May","June","July","August","September","October","November","December")
$finished = $false
while ($finished -eq $false){
$month = read-host "Enter the month";
if ($months -Contains $month)
{
write-host "Invalid entry"
$finished = $false
}
else
{
$finished = $true
}
}

You test logic is just not the good one, just reverse youy test or reverse your actions:
Write-host "The script is to collect from the user High Tempature and Low Tempature for a day in degrees F."
$months = #("January", "February","March","April","May","June","July","August","September","October","November","December")
$finished = $false
while ($finished -eq $false){
$month = read-host "Enter the month";
if ($months -Contains $month)
{
$finished = $true
}
else
{
write-host "Invalid entry"
$finished = $false
}
}

Instead of using -Contains you should just run a RegEx match using the -Match operator. Or, as you are currently testing for a negative result, use -notmatch instead. You can use your existing code, just modify it a little by joining your months with a pipe character. Like:
Write-host "The script is to collect from the user High Tempature and Low Tempature for a day in degrees F."
$months = #("January", "February","March","April","May","June","July","August","September","October","November","December")
$finished = $false
while ($finished -eq $false){
$month = read-host "Enter the month";
if ($month -notmatch ($months -join "|"))
{
write-host "Invalid entry"
$finished = $false
}
else
{
$finished = $true
}
}
Better yet, let's get rid of the If/Else and shorten this. Move the Join to where we define $Months, and then ask for a month and if it isn't a match ask for it again until it is with a While.
$months = #("January", "February","March","April","May","June","July","August","September","October","November","December") -join '|'
$month = read-host "Enter the month"
While($month -notmatch $months){
"Invalid Entry"
$month = read-host "Enter the month"
}

Related

is there a better way for me to write a script for quiz in shell

I have been at this script for 24 hours and I am getting nowhere. I am so desperate for help.
I am trying to create a quiz and I need the switches to verify if the user's input matches the 3 options; 'Y' 'N' 'G' and if true move to the next question. If not, I need the switch to then prompt the user of the default output each time the user enter's anything else besides those 3 options.
function Test-statement ($Y,$N,$G,$YY,$NN,$GG){
$check = $Y -eq $YY
$check =$check -and ($N -eq $NN)
$check =$check -and ($G -eq $GG)
$check
}
$questions = #{
"what is the current year now" = #('2023','2023','2023')
"what is the previous year" = #('2022','2022','2022')
}
foreach ($key in $questions.keys) {
$check = $false
do{
write-host ("$key" + "?")
$Y = read-host "1"
$N = read-host "2"
$G = read-host "3"
$YY = $questions.$key[0]
$NN = $questions.$key[1]
$GG = $questions.$key[2]
$check = Test-statement $Y $N $G $YY $NN $GG
if (!($check)){write-host "not true" -ForegroundColor red}
} until ($check)
}

Function not outputting value?

I'm working on a PowerShell script for some work use, and am having trouble getting a function it's data directly to a variable. Below is the function and my test:
function validateInput {
Param(
[string]$Text = 'Put text here'
)
do {
try {
$numOk = $true
$GetMyANumber = Read-Host "$text"
if ($GetMyANumber -gt 3){
$numOK = $false
}
} catch {
$numOK = $false
}
if ($numOK -ne $true) {
cls
Write-Host "Please enter a valid number" -Foreground Red
}
} until (($GetMyANumber -ge 0 -and $GetMyANumber -le 3) -and $numOK)
}
$firstName = validateInput($firstNamePrompt)
$lastName = validateInput ($lastNamePrompt)
Write-Host "First name length is $firstname"
Write-Host "Last name length is $lastname"
My understanding is that the in the last few lines, the function SHOULD assign it's output to the variables $firstName and $lastName, but I output that, they are blank. I'm sure I'm missing something obvious here, but can anyone let me know what I'm screwing up?

power-shell birthday HTML

I am writing a script for “My Birthday is *** days away!” countdown and convert it to HTML as MyBirthday.html.
Idid this so far
function Date {
$Name = Read-Host "Please enter your name"
$BirthMonth = Read-Host "Please enter your Month of Birthday"
$BirthDay = Read-Host "Please enter your Day of Birthday"
$BirthYear = (Get-Date).Year
$NumberOfDays=(New-TimeSpan -End "$BirthYear/$BirthMonth/$BirthDay").Days
if ($NumberOfDays -eq 0) {
Write-Host "Happy Birthday $Name. Today is your Birthday! Yeah!"
}
else {
Write-Host "Hello $Name, there are $NumberOfDays days to your Birthday!"
}
}
Out-File Date > C:\Users\Desktop\Date.html
Ideally you want to keep everything as an object (in this case a DateTime object) as it's much easier to manipulate.
I would do it as follows - I've annotated with comments, but if you have any questions ask.
function Date ($Name,$BirthMonth,$BirthDay)
{
#Create a datetime object
$Date = Get-Date -day $BirthDay -month $BirthMonth -year ((Get-Date).Year)
#Check if the entered date is before today
if($Date -lt (Get-Date))
{
#If so add 1 year
$Date = $Date.AddYears(1)
}
$NumberOfDays = New-Timespan -Start (Get-Date) -End $date
if ($NumberOfDays.Days -eq 0)
{
$result = "Happy Birthday $Name. Today is your Birthday! Yeah!"
}
else
{
$result = "Hello $Name, there are $($NumberOfDays.Days) days to your Birthday!"
}
#Create an object to return (Objects are easier and more flexible to work with down the pipeline)
$return = New-Object PSObject -Property #{
'Days Remaining' = $result
}
#Return the object
$return
}
#User input outside of the function (makes the function re-usable)
$Name = Read-Host "Please enter your name"
$BirthMonth = Read-Host "Please enter your Month of Birthday"
$BirthDay = Read-Host "Please enter your Day of Birthday"
#Call the function, pass the input and pipe the output
Date $Name $BirthMonth $BirthDay | ConvertTo-HTML > C:\users\jacob\desktop\date.html
#Demonstration of the returned object
Date $Name $BirthMonth $BirthDay

Guessing a number with if-else statement

I have write a short powershell script for a guessing number game. This looks like following:
clear-host
$Guess = "11"
$response=read-host "Enter your guess"
if ($response -eq $guess)
{
write-host "Congratulations"
}
else {
write-host "Try again"
}
Now, if I want to do in such way that after a certain number of times wrong guessing for example, 3 times wrong guessing the program will exit. How I can do this? Can you please shade some light on that issue?
Here is a solution with a while loop
$count = 0
$answered = $false
while ($count -lt 3 -and $answered -eq $false) {
clear-host
$Guess = "11"
$response=read-host "Enter your guess"
if ($response -eq $guess)
{
$answered = $true
write-host "Congratulations"
}
else {
write-host "Try again"
}
$count++
}

Is there a way to pre-fill out Read-Host in Powershell?

I have a script that helps a user find if a file hash exists in a folder. After the user has entered the hash I determine what type of hash it is and if it is not supported or if the user missed a letter it will return to asking for a hash. For ease of use I want to be able to pre-fill out what the user had type in the previously so they do not need to start over.
while (1)
{
$hashToFind = Read-Host -Prompt "Enter hash to find or type 'file' for multiple hashes"
# Check if user wants to use text file
if ($hashToFind -eq "file" )
{
Write-Host "Be aware program will only support one has type at a time. Type is determined by the first hash in the file." -ForegroundColor Yellow
Start-Sleep -Seconds 3
$hashPath = New-Object system.windows.forms.openfiledialog
$hashPath.InitialDirectory = “c:\”
$hashPath.MultiSelect = $false
if($hashPath.showdialog() -ne "OK")
{
echo "No file was selected. Exiting program."
Return
}
$hashToFind = Get-Content $hashPath.filename
}
# Changes string to array
if ( $hashToFind.GetTypeCode() -eq "String")
{
$hashToFind+= " a"
$hashToFind = $hashToFind.Split(" ")
}
if ($hashToFind[0].Length -eq 40){$hashType = "SHA1"; break}
elseif ($hashToFind[0].Length -eq 64){$hashType = "SHA256"; break}
elseif ($hashToFind[0].Length -eq 96){$hashType = "SHA384"; break}
elseif ($hashToFind[0].Length -eq 128){$hashType = "SHA512"; break}
elseif ($hashToFind[0].Length -eq 32){$hashType = "MD5"; break}
else {echo "Hash length is not of supported hash type."}
}
I am newer to PowerShell so if there are any other comments they are welcome!
From Super User:
[System.Windows.Forms.SendKeys]::SendWait("yes")
Read-Host "Your answer"
I have came up with solution like this:
while (1)
{
$hashToFind = Read-Host -Prompt "Enter hash to find or type 'file' for multiple hashes. Enter 'R' for reply input"
if ($hashToFind -eq 'R' -and $PreviousInput)
{
$handle = (Get-Process -Id $PID).MainWindowHandle
$code = {
param($handle,$PreviousInput)
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"#
[void][Tricks]::SetForegroundWindow($handle)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait($PreviousInput)
}
$ps = [PowerShell]::Create()
[void]$ps.AddScript($code).AddArgument($handle).AddArgument($PreviousInput)
[void]$ps.BeginInvoke()
}
$PreviousInput = $hashToFind
# Check if user wants to use text file
if ($hashToFind -eq "file" )
{
$PreviousInput = $null
Write-Host "Be aware program will only support one has type at a time. Type is determined by the first hash in the file." -ForegroundColor Yellow
Start-Sleep -Seconds 3
$hashPath = New-Object system.windows.forms.openfiledialog
$hashPath.InitialDirectory = “c:\”
$hashPath.MultiSelect = $false
if($hashPath.showdialog() -ne "OK")
{
echo "No file was selected. Exiting program."
Return
}
$hashToFind = Get-Content $hashPath.filename
}
# Changes string to array
if ( $hashToFind.GetTypeCode() -eq "String")
{
$hashToFind+= " a"
$hashToFind = $hashToFind.Split(" ")
}
if ($hashToFind[0].Length -eq 40){$hashType = "SHA1"; break}
elseif ($hashToFind[0].Length -eq 64){$hashType = "SHA256"; break}
elseif ($hashToFind[0].Length -eq 96){$hashType = "SHA384"; break}
elseif ($hashToFind[0].Length -eq 128){$hashType = "SHA512"; break}
elseif ($hashToFind[0].Length -eq 32){$hashType = "MD5"; break}
else {echo "Hash length is not of supported hash type."}
}