PowerShell Variable IF Statement from windows form - powershell

I'm trying to so write a PowerShell script that performs a task based on the input from a windows form.
If ($ComboBoxOffice.Text -eq 'Norwich', $CheckBoxNoEquipment.Checked -eq 'False' )
I can get it to work with just the following code:
If ($ComboBoxOffice.Text -eq 'Norwich')
Any ideas on how would go about only actioning the IF statement based on the input from the first code?

Assuming you only want to proceed when BOTH conditions are satisfied, use the -and operator:
if($ComboBoxOffice.Text -eq 'Norwich' -and $CheckBoxNoEquipment.Checked -eq $false){
# ...
}
If you want to proceed when either condition is satisfied, use -or:
if($ComboBoxOffice.Text -eq 'Norwich' -or $CheckBoxNoEquipment.Checked -eq $false){
# ...
}
Notice that I'm using the special boolean variable $false rather than the string 'False', to avoid type confusion bugs

Related

How to check if PowerShell result contains these words

I'm doing an IF statement in PowerShell and at some point I do this:
(Get-BitlockerVolume -MountPoint "C:").KeyProtector.keyprotectortype
which gives me the results in this format, on top of each other
I want to write my IF statement to check whether the output of the command above contains both "TpmPin" and "RecoveryPassword" but not sure what the correct syntax is.
I tried something like this but it doesn't work as expected, the result is always true even if it should be false.
if ((Get-BitlockerVolume -MountPoint "C:").KeyProtector.keyprotectortype -contains "tpmpin" && "RecoveryPassword")
this doesn't work either:
if ((Get-BitlockerVolume -MountPoint "C:").KeyProtector.keyprotectortype -contains "tpmpinRecoveryPassword")
p.s I don't want to do nested IF statements because I'm already doing multiple of them.
Make the call to Get-BitLockerVolume before the if statement, store the result in a variable, then use the -and operator to ensure both are found:
$KeyProtectors = Get-BitlockerVolume -MountPoint "C:" |ForEach-Object KeyProtector
if($KeyProtectors.KeyProtectorType -contains 'TpmPin' -and $KeyProtectors.KeyProtectorType -contains 'RecoveryPassword'){
# ... both types were present
}
If you have an arbitrary number of values you want to test the presence of, another way to approach this is to test that none of them are absent:
$KeyProtectors = Get-BitlockerVolume -MountPoint "C:" |ForEach-Object KeyProtector
$mustBePresent = #('TpmPin', 'RecoveryPassword')
if($mustBePresent.Where({$KeyProtectors.KeyProtectorType -notcontains $_}, 'First').Count -eq 0){
# ... all types were present
}
you can write a powershell if check like given below:
if((((Get-BitlockerVolume -MountPoint "C:").KeyProtector.keyprotectortype) -join ",") -eq "Tpm,RecoveryPassword")
{
write-host "matches"
}
else
{
write-host "does not match"
}
matches
Caveat: As told by #MathiasR.Jessen, this solution assumes the order of the values. So, if the values order changes, above solution will not work. We need to follow the solution provided by #MathiasR.Jessen

Powershell executing If Statement when condition is not met

I am having an issue with my If/Else statement where it will successfully prompt the user until either a "Y/y" or an "N/n" are entered and will store the proper response in the $input variable outside of the Do/Until loop but will execute the first block of code in the following If Statement whether $input is equal to "Y/y" or "N/n"
How can I make it so the If Statement will only execute when $input is equal to "Y/y" and otherwise if it's "N/n" just execute the empty else and move on to the next $program in $InstallList?
I've tried using an ElseIf and checking for "N/n" but it still only executes the first If Statement.
I've also put Write-Host for $input as a check after it leaves the Do/Until loop and it is the correct input but all falls apart when it moves on to executing the If/Else Statement.
Please help.
foreach($program in $InstallList){
if($program -notin $Installed){
$input = ""
do {
$input = Read-Host -Prompt "$($Program) is not installed would you like to install now? (y/n)"
}
until(($input -eq "y") -or ($input -eq "n"))
if($input -eq "y")
{
Write-ProgressHelper -Message "Installing $($Program)" -StepNumber ($stepCounter++)
Start-Sleep -Seconds 3
Start-Process $Software.$program -Wait
Write-Host "$($Software) installed`n"
}
else {}
else{}
}
Abraham Zinala correctly states that use of $input as a custom variable should be avoided, because it is an automatic variable whose value is managed by PowerShell itself, namely to reflect pipeline input.
It is unfortunate that PowerShell even lets you assign a value, which is a problem that affects other automatic variables too - see this answer.
Technically, as long as you stay within the same scope, you can get away with using $input for custom purposes - though it should still be avoided.
Since this constraint is fulfilled in your code, use of $input is not the source of your problem; there is no obvious problem with your code.
Here's version of your code that avoids use of $input and streamlines ensuring that the user input is valid via the -in operator:
foreach ($program in $InstallList) {
if ($program -notin $Installed) {
do {
$response = Read-Host -Prompt "$($Program) is not installed would you like to install now? (y/n)"
} until ($response -in 'y', 'n')
if ($response -eq 'y') {
'yes' # ... install
}
}
}

How to logical OR multiple variables in Powershell [duplicate]

This question already has answers here:
PowerShell's parsing modes: argument (command) mode vs. expression mode
(2 answers)
Closed 1 year ago.
I thought this was simple. And I'm sure it is. But, I can't seem to crack it.
I have 3 functions that return a true or false value.
In a later if evaluation I am trying to logical or the 3 results together.
Something like this:
if (Fnc1 -or Fnc2 -or Fnc3) { write-host "Yes" }
Not only is Powershell highlighting the syntax differently for the first Fnc1 from the others, it's only returning true or false based on the value of Fnc1 from what I can tell.
I know this works:
if ((Fnc1 -eq $true) -or (Fnc2 -eq $true) -or (Fnc3 -eq $true)) { write-host "Yes" }
But, that seems like overkill and un-necessary.
What am I missing?
PowerShell attempts to parse the -or token as a function parameter when you place it after a function name like that. Surround each function call in ():
if ((Fnc1) -or (Fnc2) -or (Fnc3)) { write-host "Yes" }
another way to get that is to use the -contains collection operator. lookee ...
function Get-True {$True}
function Get-False {$False}
#((Get-True), (Get-False), (Get-True)) -contains $True
output = True
if all those were Get-False, the result would be False.
note that this method requires that all the function calls be run before the -contains operator can test anything. that means the -or solution would be more efficient since that would run each function call in sequence and stop when the -or was satisfied.
the -or solution can be much more efficient if the function calls take any significant amount of time or resources.
thanks to #SagePourpre for pointing that out. [grin]

PowerShell return multiple values from if condition

I have a Powershell script returning data from an API which works fine as long as I only attempt to return one $device.realm, but I need multiple realms. I'm a newb to PS.
Any help here is really appreciated
Here is my code
$Output = forEach ($device in $devices) {
if ($device.realmName -eq 'Archive') {
[PSCustomObject]#{
HostName = $device.name
IPAddress = $device.primaryInterfaceAddress
Realm = $device.realmName
SerialNumbers = (($device.dynamicFields | where { $_.name -EQ "serial number" } | Select-Object -ExpandProperty values) -join "," | out-string).TrimEnd()
}| Select-Object Hostname,IPAddress,Realm,SerialNumbers | Export-csv C:\temp\Archive.csv -notype -Append
}
I need to return multiple $device.realms as in
if ($device.realmName -eq 'Archive' -and 'Default' -and 'Farms')
Once I add the additional -and's every realm is returned instead of just the one's I need to return.
I believe the issue at hand here is that the statement within the If block that you're querying as ($device.realmName -eq 'Archive' -and 'Default' -and 'Farms')
is not, when evaluated logically "Evaluate true if the device realmname is Archive, Default, or Farms." It is evaluating whether device.realmname is archive, and then just interpreting the two -ands in your example as true, as they are not querying a comparison, but just the presence of a non-null string. Not sure what is leading it to return everything, I'd have to see some more direct examples to be sure, but in my experience that is most common when you include an -or in a comparison pointing to a nonnull string, which will make the entire statement true.
What I would suggest is as follows: Use the regex operators built in to powershell for cases like this. You could use
if($device.realmname -eq 'Archive' -or $Device.realmname -eq 'farm' -or $device.realmname -eq 'Default')
which would, I believe, return what you are looking for, but I find it a bit complex. More complicated queries on a single property, I find, are easiest to do via -match, through something invoking the -match operator, which allows you to build a regex query statement that can include Or's or And's with a bit simpler of a synatax, like so:
if($Device.realmName -match 'Archive|Farm|Default')

Error in IF statement powershell

I think there's a problem with this if statement.
Function Get-IsFirewallProfileEnabled([string]$profile)
{
Return [bool](Get-NetFirewallProfile -name "Domain" | Where Enabled -eq "False")
}
# If the firewall for some of the 3 profiles is not enabled
if ( ((Get-IsFirewallProfileEnabled("Domain")) -or (Get-IsFirewallProfileEnabled("Private")) -or (Get-IsFirewallProfileEnabled("Public"))) -eq "False")
{
Write-Output "Enabling..."
# Enable Windows firewall for for all (the 3 profiles)
Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled True
}
Whether I have activated a firewall or not, this script always does nothing. What's happening?
SOLUTION
# Now this function is dynamic
Function Get-IsFirewallProfileEnabled([string]$profile)
{
Return [bool](Get-NetFirewallProfile -name $profile | Where Enabled -eq "True")
}
# If the firewall for some of the 3 profiles is not enabled
if ( -not(Get-IsFirewallProfileEnabled("Domain")) -or -not(Get-IsFirewallProfileEnabled("Private")) -or -not(Get-IsFirewallProfileEnabled("Public")) )
{
Write-Output "Enabling..."
# Enable Windows firewall for for all (the 3 profiles)
Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled True
}
As Robert mentioned, you are using the string False, not the Boolean $false in your if statement.
But the logic in your if statement isn't working as expected:
if(((Boolean) -or (Boolean) -or (Boolean)) -eq $false)
will not produce the desired result in Powershell (it will only execute if all of the values are $false). Since if always executes on $true, you can achieve desired results by simply -not-ing the values from Get-IsFirewallProfileEnabled like so:
if((-not(Get-IsFirewallProfileEnabled("Domain")) -or (-not(Get-IsFirewallProfileEnabled("Private")) -or (-not(Get-IsFirewallProfileEnabled("Public")))
This will execute the if block when any of the values are $false.
You want to use $false not "False".
"False" is a string literal and will never match if the boolean value returned by the condition ((Get-IsFirewallProfileEnabled("Domain")) -or (Get-IsFirewallProfileEnabled("Private")) -or (Get-IsFirewallProfileEnabled("Public"))) is false.
For example:
if ("False") { write-host "true" }
The line above will always write "true" to the host. This is because a non-empty string literal equates to $true.
The line below will never write "true" to the host.
if ($false) { write-host "yes" }