I have working Import-Csv statement that uses Where-Object
Import-Csv D:\Script\my.csv | Where-Object {$_.SourceIP -Like '10.251.22.11*' -Or $_.SourceIP -Like '10.251.22.*' -Or $_.DestinationIP -Like '10.251.22.11*' -Or $_.DestinationIP -Like '10.251.22.*'}
If I try to simplify the statement, it doesn't work
Import-Csv D:\Script\my.csv | Where-Object {($_.SourceIP -Like ('10.251.22.11*' -Or '10.251.22.*')) -Or ($_.DestinationIP -like ('10.251.22.11*' -Or '10.251.22.*'))}
Google is not helping :-(
Instead of -like, use -match in this case.
Import-Csv D:\Script\my.csv | Where-Object {$_.SourceIP -match '^10\.251\.22\.*' -or $_.DestinationIP -match '^10\.251\.22\.*'}
Also, 10.251.22.* will match 10.251.22.11*, so you can combine them.
Related
Using PowerCLI to filter a list of virtual machines:
Get-VM | Where-Object {$_.Name -ne 'VM1001' -and $_.Name -ne 'VM2002' -and $_.Name -ne 'VM3003' -and $_.Name -ne 'VM4004'} | Select_Object ...
Is there a cleaner/better way to filter results? This would improve script readability.
Thanks
Like #JosefZ commented, using the -notin is good for PowerShell version 3 and later:
Get-VM | Where-Object { $_.Name -notin #('VM1001','VM2002','VM3003','VM4004') }
On PowerShell version 2, you can still can use the -notcontains comparison operator:
$Excluded = #('VM1001','VM2002','VM3003','VM4004')
Get-VM | Where-Object { $Excluded -notcontains $_.Name }
I'm using the following in a do-until block to loop until a specified Exchange Online migration status is present:
(Get-Migrationbatch -Identity $MigrationBatchName | Where {$_.Status -like "Completed" -or "CompletedWithErrors" -or "Corrupted" -or "Failed" -or "Stopped"})
However, the above still returns a job with the status of "Syncing" and so continues the script regardless.
I've tried -match, -eq but still the same.
What am I missing?
You have to write it like this:
(Get-Migrationbatch -Identity $MigrationBatchName | Where {($_.Status -like "Completed") -or ($_.Status -like "CompletedWithErrors") -or ($_.Status -like "Corrupted") -or ($_.Status -like "Failed") -or ($_.Status -like "Stopped")})
Here's another way to do it:
$valuesToLookFor = #(
'Completed',
'CompletedWithErrors',
'Corrupted',
'Failed',
'Stopped')
(Get-Migrationbatch -Identity $MigrationBatchName |
Where-Object { $valuesToLookFor -contains $_.Status })
It would be simpler using -in operator, given that you are not using wildcards:
(Get-Migrationbatch -Identity $MigrationBatchName | Where Status -in "Completed","CompletedWithErrors","Corrupted","Failed","Stopped")
another option convert filter array to regex string...
$filter_status = #("Completed", "CompletedWithErrors","Curropted","Failed", "Stopped")
(Get-Migrationbatch -Identity $MigrationBatchName | Where Status -Match ($filter_status -Join "|")
Forgive me in advance as I may not be defining things correctly here:
I have a script that queries Active Directory for users in a specific OU while excluding a dozen or so OUs within that OU. The script works, but it's kind of messy as I'm declaring 13 variables representing the various OUs and referencing them in where-object. There's also an existing foreach loop as I'm querying more than one domain. I'd like to find a way to reference all the OU's I'm excluding from the query in a single collection or array or whatever and loop through it in my where-object to avoid having to reference 13 variables in the where-object. Can anyone point me in the right direction? (Code below excludes the OU variable defintions)
Existing Code:
(Get-ADForest).domains | foreach {
Get-ADUser -filter {Enabled -eq $True} -properties * -SearchBase "OU=Accounts,$((Get-ADDomain -Server $_).DistinguishedName)" -Server $_ |
where-object {$_.Title -notmatch "Volunteer" -and $_.DistinguishedName -notmatch $excludeOU1 -and $_.DistinguishedName -notmatch $excludeOU1 -and $_.DistinguishedName -notmatch $excludeOU2 -and
$_.DistinguishedName -notmatch $excludeOU3 -and $_.DistinguishedName -notmatch $excludeOU4 -and $_.DistinguishedName -notmatch $excludeOU5 -and $_.DistinguishedName -notmatch $excludeOU6 -and
$_.DistinguishedName -notmatch $excludeOU7 -and $_.DistinguishedName -notmatch $excludeOU8 -and $_.DistinguishedName -notmatch $excludeOU9 -and $_.DistinguishedName -notmatch $excludeOU10 -and
$_.DistinguishedName -notmatch $excludeOU11 -and $_.DistinguishedName -notmatch $excludeOU12 -and $_.DistinguishedName -notmatch $excludeOU13 }
}
Thanks!
You could use a regex to use with notmatch.
[regex]$excluderegex = "^(excludeOU1|excludeOU2|excludeOU3)$"
(Get-ADForest).domains | foreach {
Get-ADUser -filter {Enabled -eq $True} -properties * -SearchBase "OU=Accounts,$((Get-ADDomain -Server $_).DistinguishedName)" -Server $_ |
where-object {$_.Title -notmatch "Volunteer" -and $_.DistinguishedName -notmatch $excluderegex}
}
You can put anything you like inside the Where filter expression:
$excludes = $excludeOU1,$excludeOU2,$excludeOU3,$excludeOU4,$excludeOU5,$excludeOU6,$excludeOU7,$excludeOU8,$excludeOU9,$excludeOU10,$excludeOU11,$excludeOU12,$excludeOU13
Get-ADUser -Filter {Enabled -eq $true} -Properties * -SearchBase "OU=Accounts,$((Get-ADDomain -Server $_).DistinguishedName)" -Server $_ | Where-Object {
$_.Title -notmatch 'Volunteer' -and $(&{
foreach($exclude in $excludes)
{
if($_.DistinguishedName -match $exclude)
{
return $false
}
}
return $true
})
}
You could use the Select-Object cmdlet in your pipeline to add a new "calculated property" to your Get-ADUser data that holds just the OU of the user. The Where-Object call could then simply use a -notin operator.
In my opinion, this would make the code a little more readable. More info here:
Select-Object Calculated Properties
Notin Operator
I need to filter out 4 machines prior to exporting to a csv file. I have no clue how to filter them out. I tried the IF clause but this produced nothing. Please help.
$old = (Get-Date).AddDays(-90) # Modify the -90 to match your threshold
$oldComputers = Get-ADComputer -SearchBase "OU=Workstations,DC=Corporate,DC=Local" -SearchScope 2 -Filter { PasswordLastSet -le $old } -Properties *
$oldComputers
if ($_.name -notlike "1919DD" -or $_.name -notlike "1919SMAHESHWARE" -or $_.name -notlike "1919IETEST" -or $_.name -notlike "1920BPASCERITB") {
Export-Csv c:\temp\Over90DaysMachines.csv -NoTypeInformation -Force -Append
}
For one thing, to be able to use the current object variable ($_) you need a pipeline context. Simply putting an if statement after echoing a variable doesn't automagically feed the echoed value(s) into the if statement. You need to change this:
$oldComputers
if ($_.Name -notlike "1919DD" -or ...) {
Export-Csv c:\temp\Over90DaysMachines.csv -NoTypeInformation -Force -Append
}
into something like this:
$oldComputers | Where-Object {
$_.Name -notlike "1919DD" -or ...
} | Export-Csv c:\temp\Over90DaysMachines.csv -NoType -Force
However, even with that change your filter won't work correctly, because you connected the -notlike clauses via -or when you should have used -and. You obviously meant to process objects only if their name doesn't match any of the given values. But for your logical expression to evaluate to $false the name would have to match all of the reference value at the same time. Which clearly isn't possible, thus your expression always evaluates to $true.
Example:
Assume that you have a variable $v that should not be equal to either A, B, or C. Applying your logic, the expression would look somewhat like this in PowerShell:
($v -notlike 'A') -or ($v -notlike 'B') -or ($v -notlike 'C')
If $v takes for instance the value A that expression becomes
('A' -notlike 'A') -or ('A' -notlike 'B') -or ('A' -notlike 'C')
⇔ ($false) -or ($true) -or ($true)
⇔ $true
To check if a give value equals neither of the reference values you need to connect the clauses via -and:
('A' -notlike 'A') -and ('A' -notlike 'B') -and ('A' -notlike 'C')
⇔ ($false) -and ($true) -and ($true)
⇔ $false
$oldComputers | Where-Object {
$_.Name -notlike "1919DD" -and
$_.Name -notlike "1919SMAHESHWARE" -and
$_.Name -notlike "1919IETEST" -and
$_.Name -notlike "1920BPASCERITB"
} | Export-Csv c:\temp\Over90DaysMachines.csv -NoType -Force
Note BTW, that the -notlike operator behaves exactly like the -ne operator when the reference string doesn't contain wildcard characters. If you're not doing fuzzy matches anyway you could simplify your expression by checking if the given name is (not) found in an array of names instead of doing multiple checks for (in)equality:
$excludes = '1919DD', '1919SMAHESHWARE', '1919IETEST', '1920BPASCERITB'
$oldComputers | Where-Object {
$excludes -notcontains $_.Name
} | Export-Csv c:\temp\Over90DaysMachines.csv -NoType -Force
Another option would be a regular expression (non-)match:
$oldComputers | Where-Object {
$_.Name -notmatch '^1919DD|1919SMAHESHWARE|1919IETEST|1920BPASCERITB$'
} | Export-Csv c:\temp\Over90DaysMachines.csv -NoType -Force
I'm guessing the code in the OP is a fragment from a larger script. Presumably it is the body or part of the body of a ForEach-Object. (If not then $_ doesn't make sense in this context). However a ForEach-Object isn't necessary. You can filter out the unwanted computers as follows:
$old = (Get-Date).AddDays(-90) # Modify the -90 to match your threshold
$oldComputers = Get-ADComputer -SearchBase "OU=Workstations,DC=Corporate,DC=Local" -SearchScope 2 -Filter { PasswordLastSet -le $old } -Properties *
$oldComputers | Where-Object {
$_.name -notin "1919SMAHESHWARE","1919IETEST", "1920BPASCERITB"
} | Export-Csv c:\temp\Over90DaysMachines.csv -NoTypeInformation -Force -Append
This assumes that $oldComputers is an array of object where each object has a property name and the value of name is a string like "server1", "server2", etc. The script in the OP outputs $oldComputers so verify it looks like a set of objects, with a name property consisting of a string where the servers to be excluded are spelled exactly as listed in the OP.
Please try below code
$old = (Get-Date).AddDays(-90) # Modify the -90 to match your threshold
$oldComputers = Get-ADComputer -searchbase "OU=Workstations,DC=Corporate,DC=Local" -SearchScope 2 -Filter { PasswordLastSet -le $old } -Properties *
$oldComputers = $oldComputers | where {$_.name -notlike "1919DD"
` -or $_.name -notlike "1919SMAHESHWARE"
` -or $_.name -notlike "1919IETEST"
` -or $_.name -notlike "1920BPASCERITB"}
Export-Csv c:\temp\Over90DaysMachines.csv -NoTypeInformation -force -append
I'm trying to filter out some junk on a simple where-object of services but the -notlike is going to get long, I've tried but can't get it working but is there a way to remove the duplicate -notlike into one for example -notlike 'Softw*','Applic*','this*','that*'
Where-Object { $_.StartMode -eq 'Auto' -and $_.State -ne 'Running' -and $_.Displayname -notlike '*.NET*' -and $_.Displayname -notlike 'Softw*'-and $_.Displayname -notlike 'Applic*'}
You could use -notmatch:
$_.Displayname -notmatch "(\.NET|Softw|Applic)"