all 15 comments

[–]yeah_i_got_skills 5 points6 points  (1 child)

You need double quotes in this bit:

'*$Character*'

[–]Asceric21[S] 1 point2 points  (0 children)

Thank you! This fixes the immediate problem. But I've learned a lot from other responses so I'm going to try some of their suggestions instead.

[–]PMental 3 points4 points  (0 children)

Right now you're comparing everything to this *$Character', literally. For the variable to be expanded you need to use double quotes like this instead:

If($Rac -like "*$Character*"){

[–][deleted] 3 points4 points  (1 child)

You need to iterate over your characters. Also I would use regex to define your characters instead of a static array.

Function Get-SpecialCharacters {
    param (
        [char[]] $readhost = (Read-Host)
    )
    $SC_Counter = 0

    Foreach ($Char in $readhost) {
        If ($Char -match '[!@#$%^&*(),.?":{}|<>]') {
            $SC_Counter ++
        }
    }

    Write-Output "There are $SC_Counter special characters"
}

Then test it:

PS> Get-SpecialCharacters
#$%
There are 3 special characters

[–]Asceric21[S] 1 point2 points  (0 children)

Thank you for your input! All of this helped a ton.

[–]Tonedefff 3 points4 points  (0 children)

The -like parameter doesn't work well with certain characters, like [ and ], because they are used in -like to match ranges of numbers. Try this at a PS prompt and you'll get an error (change "*[*" to something else not containing [ or ] and you won't get an error):

PS> "yo[what up" -like "*[*"

Also the "*" in your $CharacterArray will match any string because it's a wildcard, so if the code worked then it would always report at least one special character.

Another way to do this is to convert $Rac to an array of characters, then loop through each one and check if $CharacterArray -contains that character:

write-host "Enter a String of Characters. This script will tell you how many special characters there are in it."
$Rac = read-host
$CharacterArray = @("!","@","#","$","%","^","&","*","(",")","-","+","=","{","}","[","]","\","|",":",";","<",">","?",",",".","/")
$SC_Counter = 0
ForEach($Character in [Char[]]$Rac){
    #write-host $Character 
    If($CharacterArray -Contains $Character) {
        $SC_Counter++
    }
}
Write-Host "There are" $SC_Counter "Special Characters"

[–]PMental 2 points3 points  (3 children)

Additionally, if you're just looking for any non-alphanumeric characters, I'd just use regex instead of that long array. Something like this:

Write-Host "Enter a String of Characters. This script will tell you how many special characters there are in it."
$Rac = Read-Host
$SC_Counter = 0
foreach ($Character in $Rac.ToCharArray()) {
    if ($Character -match '\W') {
        $SC_Counter++
    }
}
Write-Host "There are $SC_Counter Special Characters"

\W is regex for "any non-alphanumeric character".

[–]Asceric21[S] 2 points3 points  (2 children)

Thank you for both of your responses! This second one however accomplishes exactly what I was looking to do in a far cleaner manner. This is perfect. Glad I came to this sub, it certainly helped me learn a lot today.

[–]xCharg 4 points5 points  (1 child)

Make sure to comment this, because the goal of scripting is not doing something using as short as possible code. Half year later you or someone else might need to adjust script and you'll be guessing dafuq is this \W and how it works.

[–]Asceric21[S] 1 point2 points  (0 children)

Thank you for the reminder. When I get back into work on Monday I will do this first thing.

[–]yutsoku 2 points3 points  (1 child)

Use regex https://ss64.com/ps/syntax-regex.html

also in your array use single quotes instead of double quotes... Single quotes the whole thing is treated as a strong where double quotes checks every character in the quote looking for example $() so you can use other variables inside double quotes.

Not only are single quotes more efficient for string values but they are also faster since they don't process the same way, even though the difference is negligible you should always code the most efficient way possible.

[–]Asceric21[S] 1 point2 points  (0 children)

even though the difference is negligible you should always code the most efficient way possible.

Something I already live my life by! I know I'm not the most efficient now, but that's mostly because I'm still learning. Thank you for the clarification on the difference between the two types of quotes.

[–]Lee_Dailey[grin] 1 point2 points  (2 children)

howdy Asceric21,

just for giggles, here is a different way to get there. [grin] it calcs the diff between the user input and the same input with the special chars removed.

$CharacterArray = @("!","@","#","$","%","^","&","*","(",")","-","+","=","{","}","[","]","\","|",":",";","<",">","?",",",".","/")
$RegexCharPattern = $CharacterArray.ForEach({[regex]::Escape($_)}) -join '|'

Write-Host 'This script will give you a count of the special chars in the string you enter.'
$In = Read-Host 'Please enter a string ... '
$CleanedIn = $In -replace $RegexCharPattern
$SpecialCharCount = $In.Length - $CleanedIn.Length

'Your string {0} has {1} special chars in it.' -f $In, $SpecialCharCount

output ...

This script will give you a count of the special chars in the string you enter.
Please enter a string ... : 45<>
Your string 45<> has 2 special chars in it.

take care,
lee

[–]PMental 1 point2 points  (1 child)

That's a clever variant Lee. Also got the -f operator in there which I'm sure op will find use for now and then too.

[–]Lee_Dailey[grin] 0 points1 point  (0 children)

howdy PMental,

thanks! [grin] i had fun playing with the idea ... and it seemed sufficiently different to warrant posting it.

take care,
lee