PowerShell: Multiple Conditions within IF Statement - powershell

Im struggling to understand why the following IF statement doesn't work...
I have a PS array:
$lunchArray = #('Pizza', 'Sushi', 'Sandwich')
However the following Foreach/IF statement doesn't work as expected.
foreach ($lunch in $lunchArray) {
if ($lunch -eq 'Pizza' -and $lunch -eq 'Sushi') {
"YAY" # not working...
}
}
What am I doing wrong here?
TIA

$lunchArray = #('Pizza', 'Sushi', 'Sandwich')
foreach ($lunch in $lunchArray) {
if ('Pizza' -eq $lunch -or 'Sushi' -eq $lunch) {
"YAY" # not working...
}
}

Related

Powershell Switch - Multiple Clauses

I'm creating a script that will be updating an Excel spreadsheet depending on conditions.
This is what I currently have:
if ($endIRs -ne $null) {
$endIRs | ForEach-Object {
try {
$classification = $_.Classification
$priority = $_.Priority
$title = $_.Title
$id = $_.Id
switch ($classification) {
{($_ -eq 'Reports') -and ($priority -eq '1')} {
$GeAppsReportSheet.Cells.Item(8,2).Interior.ColorIndex = 3
$GeAppsReportSheet.Cells.Item(8,2) = 'RED'
}
#more switch statements to go here
}
catch {#catch tickets with $classification not listed}
}
}
The $endIRs at the start holds a series of high priority 'incidents' that have been logged in the last 12 hours. If there is none, everything will be 'GREEN' which is set by default.
What I am trying to achieve with the switch statement is if (($classification -eq 'Reports') -and ($priority -eq '1')) {'change the cell colour and text'} which I can do on its own, but I need it to check if the priority is "1" or "2" and do something different against the "Reports" classification cell in the spreadsheet.
Can you do an if statement within the switch statement, or is there a better way to do it?
You can use $true as the switch condition and put the checks as scriptblock values:
switch ($true) {
{($classification -eq 'Reports') -and ($priority -eq '1')} {
...
}
# ...
# more switch statements to go here
# ...
default {
...
}
}
I never really liked this approach, though. Always looked like an ugly hack to me. I'd prefer a if..elseif..else control structure:
if ($classification -eq 'Reports' -and $priority -eq '1') {
...
} elseif (...) {
...
} elseif (...) {
...
} else {
...
}
Edit: Of course you can also use a "regular" switch statement and nest other conditionals in the action scriptblocks:
switch ($classification) {
'Reports' {
if ($priority -eq '1') {
...
} elseif ($priority -eq '2') {
...
}
}
# ...
# more switch statements to go here
# ...
default {
...
}
}

Using -notcontains to find substring within string within array

I'm trying to avoid using nested ForEach Loop as part of a larger code. To do this, I'm using the -notcontains operator. Basically, I want to see if a substring exists within a string within an array. If it exists, do nothing, if it does not exist, print "Not Found".
Here is the code...
$arr = #('"value11","value21","value31"','"value12","value22","value32"','"value13","value23","value33"')
if ($arr -notcontains "*`"value24`"*")
{
Write-Host "Not Found"
}
if ($arr -notcontains "*`"value22`"*")
{
Write-Host "Not Found 2"
}
We can see that value24 is not within any strings of the array. However, value22 is within the 2nd string in the array.
Therefor the results should output the following...
Not Found
However, instead I see the following output...
Not Found
Not Found 2
Can anyone tell me why this is happening?
-contains and -notcontains don't operate against patterns.
Luckily, -match and -like and their negative counterparts, when used with an array on the left side, return an array of the items that satisfy the condition:
'apple','ape','vape' -like '*ape'
Returns:
ape
vape
In an if statement, this still works (a 0 count result will be interpreted as $false):
$arr = #('"value11","value21","value31"','"value12","value22","value32"','"value13","value23","value33"')
if ($arr -notlike "*`"value24`"*")
{
Write-Host "Not Found"
}
My take on a solution:
($arr | foreach {$_.contains('"value24"')}) -contains $true
Using the V3 .foreach() method:
($arr.ForEach({$_.contains('"value24"')}).contains($true))
And yet another possibility:
[bool]($arr.where({$_.contains('"value24"')}))
Edit for clearer answer on what I'm looking for...
This is the only way I'm able to figure this out so far. I hope there is a much cleaner solution...
$arr = #('"value11","value21","value31"','"value12","value22","value32"','"value13","value23","value33"')
$itemNotFound = $true
ForEach ($item in $arr)
{
If ($itemNotFound)
{
If ($item -like "*`"value24`"*")
{
$itemNotFound = $false
}
}
}
if ($itemNotFound)
{
Write-Host "Not Found value24"
}
$itemNotFound = $true
ForEach ($item in $arr)
{
If ($itemNotFound)
{
If ($item -like "*`"value22`"*")
{
$itemNotFound = $false
}
}
}
if ($itemNotFound)
{
Write-Host "Not Found value22"
}
output will be:
Not Found value24

powershell string contain only number

I have an array with folder names. I want to loop thru this array and find out if an entry is only 7 in length and only contain numbers.
Can anyone please push me in the correct direction? Thanks!
One solution is while looping through the array names check if the two conditions are met like so:
foreach ($name in "test", "1234567", "test02", "001") {
if ($name.Length -eq 7 -and $name -match '^\d+$'){
Write-Host $name
}
}
As far as i understood your question :
function Is-Numeric ($Value)
{
return $Value -match "^[\d\.]+$"
}
$birds = "owl","crow","robin","wren","jay","123"
foreach ($bird in $birds) { if($bird.length -eq 3 -and (Is-Numeric $bird)) {"$bird"} }
just switch it to your case :)

Powershell foreach loop with multiple if statements

I have a script snippet that basically gets some unformated xml type output from a command.
Then in a defined filter section I'm transforming that into xml and run a search loop on each node, as from the part below.
What I'm trying to figure out is how I can make a multiple if -and loop, like
if (($CimProperty.VALUE -eq $somevariable) -and ($CimProperty.VALUE -eq $something-else))
The only problem is that since it's a foreach loop it won't take it, as it takes each property at a time and then the 'if statement -and portion' for it, which doesn't work since it's the same xml type property section.
In other words the loop doesn't go through the entire array to identify both conditions from the if statement.
PS code snippet:
filter Import-CimXml
{
$CimXml = [Xml]$_
$CimObj = New-Object -TypeName System.Object
foreach ($CimProperty in $CimXml.SelectNodes(“/INSTANCE/PROPERTY”))
{
if ($CimProperty.VALUE -eq $somevariable)
{
write-host "found it"
}
}
}
I hope the scenario is clear, thanks everyone in advance!
For just two conditions, you can make it fairly straight forward like (the untested);
filter Import-CimXml
{
$foundfirst = $false
$foundsecond = $false
$CimXml = [Xml]$_
$CimObj = New-Object -TypeName System.Object
foreach ($CimProperty in $CimXml.SelectNodes(“/INSTANCE/PROPERTY”))
{
if ($CimProperty.VALUE -eq $somevariable)
{
$foundfirst = $true
}
if ($CimProperty.VALUE -eq $someothervariable)
{
$foundsecond = $true
}
}
if ($foundfirst -and $foundsecond)
{
write-host "found it"
}
}
For more conditions, you may want to use arrays of corresponding matchwords/booleans instead.
Just extend your xpath query to do it all. It's less code and should be more efficient.
filter Import-CimXml
{
$CimXml = [Xml]$_
$CimObj = New-Object -TypeName System.Object
if($CimXml.SelectNodes(“/INSTANCE[PROPERTY='$somevariable' and PROPERTY='$someothervariable']”).Count -gt 0) {
write-host "found it"
}
}

The PowerShell -and conditional operator

Either I do not understand the documentation on MSDN or the documentation is incorrect.
if($user_sam -ne "" -and $user_case -ne "")
{
Write-Host "Waaay! Both vars have values!"
}
else
{
Write-Host "One or both of the vars are empty!"
}
I hope you understand what I am attempting to output. I want to populate $user_sam and $user_case in order to access the first statement!
You can simplify it to
if ($user_sam -and $user_case) {
...
}
because empty strings coerce to $false (and so does $null, for that matter).
Another option:
if( ![string]::IsNullOrEmpty($user_sam) -and ![string]::IsNullOrEmpty($user_case) )
{
...
}
Try like this:
if($user_sam -ne $NULL -and $user_case -ne $NULL)
Empty variables are $null and then different from "" ([string]::empty).
The code that you have shown will do what you want iff those properties equal "" when they are not filled in. If they equal $null when not filled in for example, then they will not equal "". Here is an example to prove the point that what you have will work for "":
$foo = 1
$bar = 1
$foo -eq 1 -and $bar -eq 1
True
$foo -eq 1 -and $bar -eq 2
False