I am wanting to validate a user's input of special characters and if the characters are not correct, I want it to loop back to the read-host statement. I am unsure what loop type I should use and how to do this. Any and all help would be greatly appreciated.
For example
$Example = Read-Host “Input one of the following symbols
Addition (+)
Subtraction (-)
Multiplication (*)
Division (/)"
Something like this should suit your needs.
do {
$Symbol = Read-Host 'Symbol'
if ($Symbol -match '^(\+|-|\*|/)$'){
$Valid = $true
} else {
Write-Host "'$($Symbol)' is not a valid input, please choose one of +,-,* or /"
$Valid = $false
}
} while (!$Valid)
Related
im trying to make a powershell code generator what i want is for
$input = read-host ""
to be used to compare to $Alpha = "a","B" etc
then output to
write-host
the equal form from $Beta = "T","C" etc
the thought is that im trying to create a digital version of something like a decoder ring but in powershell
I am having trouble understanding your exact requirements but you said in your comments you are looking to encode and decode messages in PowerShell.
The below will convert the users input into Base64 and then decode it again.
$UserInput = Read-Host
$EncodedText = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($UserInput))
"This is the encoded text: $($EncodedText)" | Write-Host
$DecodedText = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($EncodedText))
"This is the decoded text: $($DecodedText)" | Write-Host
Agree with Drew, but tweaking his helpful answer a bit:
If all you are doing is sending the text to the screen, always, then for this the use case you don't need Write-Host at all. You can use PowerShell Variabel Squeezing. Get input and assign it to the variable and output to screen at the same time. Like the Pipe '|' the double colon is a natural line continuation option (as are many including comparison operators). Though not commonly used this way.
"This is the encoded text: $(($EncodedText = [Convert]::
ToBase64String([System.Text.Encoding]::
Unicode.GetBytes($(Read-Host -Prompt 'Enter a string')))))"
"This is the decoded text: $([System.Text.Encoding]::
Unicode.GetString([System.Convert]::
FromBase64String($EncodedText)))"
# Results
<#
Enter a string: test
This is the encoded text: dABlAHMAdAA=
This is the decoded text: test
#>
Hi im currently working on a script to monitor back to an RMM tool, seem to be having issues converting my objects to match a "known string" inside my script.
ideally i'd like to poll the local computers local admin group then inline compare that with a string i've predefined, i was hoping to get the value, then just write a multi-lined string to match, then do some if statements to compare the 2.
$test3 = Get-LocalGroupMember -SID "S-1-5-32-544" | select -ExpandProperty Name | out-string
$test =#"
PC\Administrator
PC\test
"#
this is a little snippet, so the first one pulls the local ad group then saves it to a varible, and $test is my defined variable.
Both appear identical when outputted to console.
thanks so much in advance.
Instead of a predefined multiline string, Use either a string array or a hashtable to compare against.
The way you try to do it can fail the comparison simply because the items returned can be in a different order as in your predefined string.
Option 1: use an array
$testUsers = 'PC\Administrator', 'PC\test'
# this gets the users that are mentioned in the $testUsers array.
# if you want the opposite (users in the group, but NOT in the $testUsers array),
# change '-contains' into '-notcontains'
(Get-LocalGroupMember -SID "S-1-5-32-544").Name | Where-Object { $testUsers -contains $_ }
Option 2: use a Hashtable (a bit more work to set up, but extremely fast)
$testusers = #{
'PC\Administrator' = $true # the Values will not be used, so anything can go in here
'PC\test' = $true
}
# this gets the users that are mentioned in the $testUsers Hashtable.
# if you want the opposite (users in the group, but NOT in the $testUsers Hashtable),
# change '$testUsers.ContainsKey($_)' into '!$testUsers.ContainsKey($_)'
(Get-LocalGroupMember -SID "S-1-5-32-544").Name | Where-Object { $testUsers.ContainsKey($_) }
It's a bug in Windows where orphaned SIDs are left in the group. Try this instead:
$adminGroup = [ADSI]::new("WinNT://$env:COMPUTERNAME/$((Get-LocalGroup -SID S-1-5-32-544).Name)")
$adminGroupMembers = $adminGroup.Invoke('Members') |% {([ADSI]$_).Path.Replace('WinNT://', '')}
$adminGroupMembers | Out-String
You'll need to manipulate the output as required.
I have the following code that works well for validating length...
DO {
$NewID = Read-Host -Prompt " NEW ID NAME of object (8-15 chars) "
} UNTIL ($NewID.Length -gt 7 -and $WS_NewName.Length -lt 16)
How can I include code that ensures input contains either an ALPHA or ALPHANUMERIC string, but NOT a purely NUMERIC one?
This can be easily doable using regular expressions like that:
($NewID -match '^[A-z0-9]*$') -and ($NewID -notmatch '^[0-9]*$')
Short explanation: first expression looks for alpha/alphanumeric string and the second discards purely numeric entries.
By the way, in your example you use $NewID and then $WS_NewName in Until expression, that might be confusing (however, I assume you just forgot to change it while pasting here)
I am trying to figure out how to test for mixed case or change the user input to mixed case.
Currently my code consists of:
$Type = Read-Host 'Enter MY, OLD, NEWTest, Old_Tests'
However, I need to validate that the user entered in the exact case, and if they didn't change the case to the correct case. I have reviewed so many different questions on here and other websites, but none seem to really talk about validating mixed case in a way I can understand.
Validate User Entry
Regex to match mixed case words
Validating String User Entry
How to check if a string is all upper case (lower case) characters?
Learn Powershell | Achieve More
How To Validate Parameters in PowerShell
$args in powershell
I am not asking anyone to write code for me. I am asking for some sample code that I can gain an understanding on how to validate and change the entries.
PowerShell performs case-insensitive comparisons by default, so to answer the first part of your question you need to do a case-sensitive comparison which is -ceq.
$Type = Read-Host 'Enter MY, OLD, NEWTest, Old_Tests'
($Type -ceq 'MY' -or $Type -ceq 'OLD' -or $Type -ceq 'NEWTest' -or $Type -ceq 'Old_Tests')
Although a simpler solution to that is to use case-sensitive contains -ccontains:
('MY', 'OLD', 'NEWTest', 'Old_Tests' -ccontains $Type)
Here's one way you might correct the case:
$Type = Read-Host 'Enter MY, OLD, NEWTest, Old_Tests'
If ('MY', 'OLD', 'NEWTest', 'Old_Tests' -cnotcontains $Type){
If ('MY', 'OLD', 'NEWTest', 'Old_Tests' -contains $Type){
$TextInfo = (Get-Culture).TextInfo
$Type = Switch ($Type) {
{$_ -in 'MY','OLD'} { $Type.ToUpper() }
'NEWTest' { $Type.Substring(0,4).ToUpper() + $Type.Substring(4,3).ToLower() }
'Old_Tests' { $TextInfo.ToTitleCase($Type) }
}
} Else {
Write-Warning 'You didnt enter one of: MY, OLD, NEWTest, Old_Tests'
}
}
Write-Output $Type
Explanation:
First we test if the case is correct for the four permitted words (-cnotcontains Case Sensitive Not Contains), if it is we do nothing. If the case is not correct, then we test the text is correct (without caring about case sensitivity -contains).
If the text is correct then we use Switch statement to deal with the different scenarios that we want to adapt the case for:
The first switch test matches the first two words and simply uppercases them with the ToUpper() string method.
The second switch test uses the string method SubString to get a subset of the string starting from the first character (0) and taking 4 characters in length. We uppercase this with ToUpper then we add on the next 3 characters of the string, starting at the 4th character, which we force in to lower case with ToLower().
The final switch test we handle with a .NET method taken from the get-culture cmdlet which allows us to Title Case a string (make the first letter of each word uppercase).
If the inputted text didn't match one of the options we use write-warning (may require PowerShell 4 or above, if you don't have this change it to write-host) to print a warning to the console.
Finally whatever was entered we send to stdout with Write-Output.
I've seen the # symbol used in PowerShell to initialise arrays.
What exactly does the # symbol denote and where can I read more about it?
In PowerShell V2, # is also the Splat operator.
PS> # First use it to create a hashtable of parameters:
PS> $params = #{path = "c:\temp"; Recurse= $true}
PS> # Then use it to SPLAT the parameters - which is to say to expand a hash table
PS> # into a set of command line parameters.
PS> dir #params
PS> # That was the equivalent of:
PS> dir -Path c:\temp -Recurse:$true
PowerShell will actually treat any comma-separated list as an array:
"server1","server2"
So the # is optional in those cases. However, for associative arrays, the # is required:
#{"Key"="Value";"Key2"="Value2"}
Officially, # is the "array operator." You can read more about it in the documentation that installed along with PowerShell, or in a book like "Windows PowerShell: TFM," which I co-authored.
While the above responses provide most of the answer it is useful--even this late to the question--to provide the full answer, to wit:
Array sub-expression (see about_arrays)
Forces the value to be an array, even if a singleton or a null, e.g. $a = #(ps | where name -like 'foo')
Hash initializer (see about_hash_tables)
Initializes a hash table with key-value pairs, e.g.
$HashArguments = #{ Path = "test.txt"; Destination = "test2.txt"; WhatIf = $true }
Splatting (see about_splatting)
Let's you invoke a cmdlet with parameters from an array or a hash-table rather than the more customary individually enumerated parameters, e.g. using the hash table just above, Copy-Item #HashArguments
Here strings (see about_quoting_rules)
Let's you create strings with easily embedded quotes, typically used for multi-line strings, e.g.:
$data = #"
line one
line two
something "quoted" here
"#
Because this type of question (what does 'x' notation mean in PowerShell?) is so common here on StackOverflow as well as in many reader comments, I put together a lexicon of PowerShell punctuation, just published on Simple-Talk.com. Read all about # as well as % and # and $_ and ? and more at The Complete Guide to PowerShell Punctuation. Attached to the article is this wallchart that gives you everything on a single sheet:
You can also wrap the output of a cmdlet (or pipeline) in #() to ensure that what you get back is an array rather than a single item.
For instance, dir usually returns a list, but depending on the options, it might return a single object. If you are planning on iterating through the results with a foreach-object, you need to make sure you get a list back. Here's a contrived example:
$results = #( dir c:\autoexec.bat)
One more thing... an empty array (like to initialize a variable) is denoted #().
The Splatting Operator
To create an array, we create a variable and assign the array. Arrays are noted by the "#" symbol. Let's take the discussion above and use an array to connect to multiple remote computers:
$strComputers = #("Server1", "Server2", "Server3")<enter>
They are used for arrays and hashes.
PowerShell Tutorial 7: Accumulate, Recall, and Modify Data
Array Literals In PowerShell
I hope this helps to understand it a bit better.
You can store "values" within a key and return that value to do something.
In this case I have just provided #{a="";b="";c="";} and if not in the options i.e "keys" (a, b or c) then don't return a value
$array = #{
a = "test1";
b = "test2";
c = "test3"
}
foreach($elem in $array.GetEnumerator()){
if ($elem.key -eq "a"){
$key = $elem.key
$value = $elem.value
}
elseif ($elem.key -eq "b"){
$key = $elem.key
$value = $elem.value
}
elseif ($elem.key -eq "c"){
$key = $elem.key
$value = $elem.value
}
else{
Write-Host "No other value"
}
Write-Host "Key: " $key "Value: " $value
}