To complement Santiago Squarzon's helpful answer with an optimization:
# Prompt until a valid service status identifier is entered.
do {
try {
[System.ServiceProcess.ServiceControllerStatus] $sStatus =
Read-Host "Please specify the desired service status (e.g., Running or Stopped)"
break # A valid value was entered, exit the loop
} catch { }
Write-Warning "Unknown status; please specify one of: $([Enum]::GetNames([System.ServiceProcess.ServiceControllerStatus]))"
} while ($true)
# Now output the names of all services that are in the specified state, if any:
(Get-Service | Where-Object Status -eq $sStatus).Name
Casting the user input (which is always a string) to type [System.ServiceProcess.ServiceControllerStatus] (the type of the .Status property of the objects returned by Get-Service) is used to ensure that a valid service-status identifier was entered.
As for what you tried:
Leaving the inefficiency of calling Get-Service twice aside, your primary problem was the use of the .Contains() .NET array method (implemented via the IList interface):
.Contains() performs no on-demand type conversions, so looking for a string ($sstatuss) in your array of [System.ServiceProcess.ServiceControllerStatus] values ($statusbank) never succeeds.
By contrast, PowerShell's -contains operator does perform on-demand type conversions (as PowerShell generally does) and is notably also case-insensitive (as PowerShell generally is). The same applies to functionally equivalent, but operands-reversed -in operator.
To illustrate the difference:
# Sample array with [System.ServiceProcess.ServiceControllerStatus] elements.
$array = [System.ServiceProcess.ServiceControllerStatus]::Running,
[System.ServiceProcess.ServiceControllerStatus]::Stopped
# WRONG.
$array.Contains('running') # !! always $false with a [string] as input
# OK.
$array -contains 'running' # -> $true - on-demand type conversion
# from string to [System.ServiceProcess.ServiceControllerStatus]
In a nutshell: -contains is in effect using the -eq operator against each element behind the scenes, so the latter's automatic type conversions and case-insensitivity apply. See the bottom section of this answer for more information about -contains and -in.
Pitfall: Due to having the same name, there's potential for confusion with the .Contains() string method, which functions differently, however: it performs literal substring matching, and there is no direct operator equivalent in PowerShell for that - see this answer.
Also:
Format-* cmdlets output objects whose sole purpose is to provide formatting instructions to PowerShell's output-formatting system - see this answer. In short: only ever use Format-* cmdlets to format data for display, never for subsequent programmatic processing.
Write-Host is typically the wrong tool to use, unless the intent is to write to the display only, bypassing the success output stream and with it the ability to send output to other commands, capture it in a variable, or redirect it to a file. To output a value, use it by itself; e.g., $value instead of Write-Host $value (or use Write-Output $value, though that is rarely needed); see this answer