Hi im having diffeculties to get my script working:
It keeps failing on the first write output, even when the powershell version is higher then 4. It only works when I remove And $winver -eq $os1 -or $os2 -or $os3.
Otherwise it keeps telling me my powershell version needs to be upgraded. Im on V5 currently and $PSVersionTable.PSVersion.Major does says it 5 indeed.
What am i doing wrong?
$winver = (Get-WmiObject -class Win32_OperatingSystem).Caption
$powershellversion = $PSVersionTable.PSVersion.Major
$os1 = "Microsoft Windows 7 Professional"
$os2 = "Microsoft Windows 10 Pro"
$os3 = "Microsoft Windows 10 Enterprise"
if($winver -ne ($os1, $os2, $os3) -contains $winver){
Write-Host "Bitlocker not supported on $winver"
Exit 0
}
if($powershellversion -lt 4){
Write-Host "Upgrade Powershell Version"
Exit 1010
}
else
{
$bitlockerkey = (Get-BitLockerVolume -MountPoint C).KeyProtector.RecoveryPassword
$pcsystemtype = (Get-WmiObject -Class Win32_ComputerSystem).PCSystemType
if ($pcsystemtype -eq "2"){
$setsystemtype = "Laptop"
}
else {
$setsystemtype = "Desktop"
}
if ($setsystemtype -eq "laptop" -And $bitlockerkey -eq $null -and ($os1, $os2, $os3) -contains $winver){
Write-Host "$setsystemtype without bitlocker"
Exit 1010
}
if ($setsystemtype -eq "desktop" -And $bitlockerkey -eq $null -and ($os1, $os2, $os3) -contains $winver){
Write-Host "$setsystemtype without bitlocker"
Exit 0
}
if ($winver -eq ($os1, $os2, $os3) -contains $winver){
Write-Host "$bitlockerkey"
Exit 0
}
}
Let's see what this actually does:
if ($powershellversion -lt 4 -And $winver -eq $os1 -or $os2 -or $os3) { ... }
If your powershell version is less than 4, and Win version is equal
to os1, then proceed
If os2 has a value, then proceed
If os3 has a value, then proceed
The topic here is Operator Precedence, specifically, what happens first when evaluating a line of code, what happens second, third, and so on. Just like in algebra math, adding parens around part of the formula changes the order in whcih you read it.
So, you can mess around with parens to get your logic to work:
if($powershellversion -lt 4 -and ( ($winver -eq $os1) -or ($winver -eq $os2) -or ($winver -eq $os3) ))
In other words
evaluate if PS version is < 4 ($powershellversion -lt 4), -and
evaluate if winver is either os1, os2 or os3: ( ($winver -eq $os1) -or ($winver -eq $os2) -or ($winver -eq $os3) ).
Or, you can rearrange your logic a bit by putting your os variables into an array, and seeing if $winver is in there:
if($powershellversion -lt 4 -and $winver -in ($os1, $os2, $os3)) { ... }
Edit: Or
if($powershellversion -lt 4 -and ($os1, $os2, $os3) -contains $winver) { ... }
for backwards compatibility with v2.0.
Related
After reading many of the posted solutions here, none fully applies mine.
This works (returns expected number of instancesNames based on criteria):
$response.result | Where-Object {$_.targetType -eq "webserver" -and ($_.agentHostName -eq "ServerA" -or $_.agentHostName -eq "ServerB")} | select-Object "instanceName"
However, since n number of servers may be found, I created a loop to dynamically create this query:
[System.Text.StringBuilder]$clause = " {`$_.targetType -eq ""webserver"" -and ("
$i = 1;
foreach ($server in $serversArray) {
if ( $i -eq $serversArray.Count ) {
$clause.Append("`$_.agentHostName -eq ""${server}"")}")
} else {
$clause.Append( "`$_.agentHostName -eq ""${server}"" -or ")
}
$i++
}
$clause.Append(" | select-Object ""instanceName""")
$filter = [scriptblock]::Create($clause)
$instances = $response.result | where-object $filter
debugging:
the $clause variable contains:
{$_.targetType -eq "webserver" -and ($_.agentHostName -eq "serverA" -or $_.agentHostName -eq "serverB")} | select-Object "instanceName"
However, it returns all instanceNames (not filtered) instead of the ones that meet the criteria. What am I doing wrong here?
The -in operator would simplify your code. For example:
$response.result |
Where-Object {($_.targetType -eq 'webserver') -and ($_.agentHostName -in $serversArray)} |
Select-Object 'instanceName'
What is wrong with my formatting. the code runs when only one condition is in there. When I add the -or with the second condition to check it appears to not check either.
while(($TempLog.id -ne "18") -or ($TempLog.id -ne "32"))
{
$TempLog = Get-WinEvent -computername F9P8NW2-5300 -LogName 'Microsoft-Windows-RemoteAssistance/Operational'-MaxEvents 1
}
enter code here
I'm currently using Powershell, and i'm trying to sort data in my variable that i'm pulling from another system. At the moment i'm trying to use one -and statement and -or statements after an -eq sign. So I was wondering what's the correct way I need to make the syntax in my where statement.
$DLPList | Select Node.NodeName, Properties.OSType, PropsView.version, Node.NodeTextPath2 | where PropsView.version -ne '1.4.706.172' -and (Properties.OSType -eq $win7 -or $win8 -or $win81 -or $win10)
I know there's multiple other stuff on this, but everything i've tried so far doesn't work. Thanks for the help.
Yes, you have to use the script block version of where-object. Also note that -and and -or have EQUAL PRECEDENCE in powershell, which is very unusual in a language.
Alright, what I figured out for this is that you cannot just add use -or. Instead you must do Properties.ostype for each one. Here is the code that I came up with to get it to work. Also a little tip is to do Where-Object before Select-Object to save computing power.
$DLPList = $list1 | Where-Object{ $_.'UDLP.prodversion' -lt '9.5.704.112' -and ($_.'Properties.OSType' -ne 'Windows XP') -and ($_.'EPOComputerProperties.OSType' -ne 'Windows Vista') -and ($_.'EPOComputerProperties.OSType' -ne 'Windows 2003') -and ($_.'Properties.OSType' -ne 'Windows 2003 R2') -and ($_.'EPOComputerProperties.OSType' -ne 'Windows 2008') -and ($_.'Properties.OSType' -ne 'Windows 2008 R2') -and ($_.'Properties.OSType' -ne 'Windows Server 2012' -and ($_.'Properties.OSType' -ne 'Windows Server 2012 R2') -and ($_.'Properties.OSType' -ne 'Windows Server 2016')) } | Select-Object Node.NodeName, Properties.OSType, UDLP.productversion, Node.NodeText | Sort-Object -Property Node.NodeText -Descending
Try adding brackets and replacing the chained boolean operators with a regular expression "-match" operator condition:
$DLPList | Select Node.NodeName, Properties.OSType, PropsView.version, Node.NodeTextPath2 | where { $_.'PropsView.version' -ne '1.4.706.172' -and ($_.'Properties.OSType' -match "($win7|$win8|$win81|$win10)") }
Here's sample code that works for me:
$DLPList = #(2, 4, 6, 7)
$DLPList | where { ($_ -ne 7) -and ($_ -lt 10) -and ($_ -gt 0) }
2
4
6
$DLPList | where { ($_ -ne 7) -and ($_ -match "(4|5|11)" -and ($_ -gt 0)) }
4
Can someone explain me this syntax? I think it didn't work, so if you can help me to find another syntax.
$fichesAEnvoyer = #($fiches | where {($_.TypeFiche -eq '2') -and (($_.Causes -eq '') -or ($_.Causes -eq $null) -or ($_.Causes.Count -eq 0) -or ($_.ActionCorrective -eq '') -or ($_.ActionCorrective -eq $null) -or ($_.DateActionCorrective -eq '') -or ($_.DateActionCorrective -eq $null) -or ($_.ActionPreventive -eq '') -or ($_.ActionPreventive -eq $null) -or ($_.DateActionPreventive -eq '') -or ($_.DateActionPreventive -eq $null) )})
I don't understand why there is $_ instead of $fiches
$_ is a variable that the where cmdlet creates to represent the current object in the pipeline. For example, if you do:
1,2,3 | where {$_ -ge 2} | Write-Host
Then $_ will be set to 1 followed by 2, followed by 3.
The if condition works until I try to add the last portion of the line in there. I want it to look at the value of the operating system and if it is equal to 5.* then proceed with the statement. Otherwise fail.
$OS = Get-WmiObject Win32_OperatingSystem -computer $Machine
$OSVER = $OS.VERSION
if (($IEVersion -like '8*') -and (($Machine -like '[NCI]*') -or ($Machine -like '[RXPC]*') -or ($Machine -like '[RXCO]*') -or ($Machine -like '[MW]*') -or ($Machine -like '[SMPC]*') -or ($Machine -like '[MTPC]*')) -and ($OSVER -like '5.*'))
{
Write-Host "Do something here"
}
else
{
Write-Host "Do nothing on the machine"
}
All I did was put the WMI call outside of the IF statement. All works as expected. I have updated the code above.