Clarification of syntax used - powershell

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.

Related

Where object as variable

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'

Adding multiple -and and -or statements in WHERE clause in Powershell

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

Filtering get-adobject with Powershell

Could some one tell me the issues with the query.
I want to pull back all the users that are not in a number of specific OU, I thought the following query would work, but as you can see it pulls back a user with "ou=staff" in the DN (extracted from all of the output).
I am trying to say if non of the following appear in the DN attribute.
$NotinDirectory = Get-ADObject -LDAPFilter "objectClass=person" -SearchBase "OU=Accounts,DC=Company,DC=ac,DC=uk" -Properties ou |? {($_.DistinguishedName -notlike "*Agency*" -and "*Contractors*" -and "*Fellows*" -and "*Visitors*" -and "*ou=Staff*" -and "*Contacts*")}
CN=jo blogs,OU=Staff,OU=Accounts,DC=compnay,DC=ac,DC=uk
UPDATE
so I tried this based on comments bellow
$NotinDirectory = Get-ADObject -LDAPFilter "objectClass=person" -SearchBase "OU=Accounts,OU=iah,DC=iah,DC=ac,DC=uk" | ? {($_DistinguishedName -notlike "*Agency*" -and $_DistinguishedName -notlike "*Contractors*" -and $_DistinguishedName -notlike "*Fellows*" ) -and ($_DistinguishedName -notlike"*Visitors*") -and ($_DistinguishedName -notlike"*OU=Staff*" -and $_DistinguishedName -notlike"*Contacts*")}
foreach ($test in $NotinDirectory){ Write-Host $test.DistinguishedName}
but i still get
CN=xxx xxxxx,OU=Staff,OU=Accounts,DC=company,DC=ac,DC=uk
In your Where-Object filter:
($_.DistinguishedName -notlike "*Agency*" -and "*Contractors*" -and "*Fellows*" -and "*Visitors*" -and "*ou=Staff*" -and "*Contacts*")
you only compare $_.DistinguishedName to a string once, the first time (-notlike "*Agency*").
It will be parsed as follows:
(($_.DistinguishedName -notlike "*Agency*") -and ("*Contractors*") -and ("*Fellows*") -and ("*Visitors*") -and ("*ou=Staff*") -and ("*Contacts*"))
(($_.DistinguishedName -notlike "*Agency*") -and $true -and $true -and $true -and $true -and $true)
($_.DistinguishedName -notlike "*Agency*")
You'll have to do:
Get-ADObject | Where-Object {($_.DistinguishedName -notlike "*Agency*" -and
$_.DistinguishedName -notlike "*Contractors*" -and
$_.DistinguishedName -notlike "*Fellows*" -and
$_.DistinguishedName -notlike "*Visitors*" -and
$_.DistinguishedName -notlike "*ou=Staff*" -and
$_.DistinguishedName -notlike "*Contacts*")}
in order to test for all 6 strings.
If you have a variable number of strings you want to exclude, you can use ForEach-Object inside Where-Object:
$Excludes = "*Agency*","*Contractors*","*Fellows*","*Visitors*","*ou=Staff*","*Contacts*"
Get-ADObject |Where-Object {
$ADObj = $_
#($Excludes |ForEach-Object {
$ADObj.DistinguishedName -notlike $_
}) -notcontains $false
}

Filter a long list in Powershell

If you wanted to filter names that contain the first letter w and are followed by 'x' amount of numbers, then how do you filter it?
for example:
w34593
w44569a
we5552
w01123
w85532
I've been starting off with
$userIDs = Get-Aduser -filter {name -like "w3*" -or name -like "w4*"} -Properties * | Select name, SurName, DisplayName
Issue is some get long where they start with w1, w2, w3, w0 and I don't want to filter each one or the code with be stupidly long.
any suggestions? Each name is usually 6 to 7 characters long so is there a range length that could help me? i tried .length but it doesn't seem to work for my version of powershell
Update:
$userIDs = Get-Aduser -filter {(name -gt "w30000*" -and name -lt "w99999*") -or (name -gt "we0000*" -and name -lt "we9999*") `
-or (name -gt "cr0000*" -and name -lt "cr9999*") -or (name -gt "ac0000**" -and name -lt "ac9999*")`
-or (name -gt "cm0000*" -and name -lt "cm9999*") -or (name -gt "do0000*" -and name -lt "do9999*") `
-or (name -gt "ec0000*" -and name -lt "ec9999*") -or (name -gt "ev0000*" -and name -lt "ev9999*") `
-or (name -gt "fm0000*" -and name -lt "fm9999*") -or (name -gt "ia0000*" -and name -lt "ia9999*") `
-or (name -gt "in0000*" -and name -lt "in9999*") -or (name -gt "le0000*" -and name -lt "le9999*") `
-or (name -gt "md0000*" -and name -lt "md9999*") -or (name -gt "mk0000*" -and name -lt "mk9999*") `
-or (name -gt "np0000*" -and name -lt "np9999*") -or (name -gt "pb0000*" -and name -lt "pb9999*") `
-or (name -gt "ps0000*" -and name -lt "ps9999*") -or (name -gt "re0000*" -and name -lt "re9999*") `
-or (name -gt "sf0000*" -and name -lt "sf9999*") -or (name -gt "so0000*" -and name -lt "so9999*") `
-or (name -gt "tr0000*" -and name -lt "tr9999*") -or (name -gt "wn0000*" -and name -lt "wn9999*") } `
-Properties * | Select name, SurName, DisplayName, enabled
ERROR:
Get-ADUser : Error parsing query: '(name -gt "w30000*" -and name -lt "w99999*")
-or (name -gt "we0000*" -and name -lt "we9999*") `
-or (name -gt "cr0000*" -and name -lt "cr9999*") -or (name -gt "ac
0000**" -and name -lt "ac9999*")`
-or (name -gt "cm0000*" -and name -lt "cm9999*") -or (name -gt "do
0000*" -and name -lt "do9999*") `
-or (name -gt "ec0000*" -and name -lt "ec9999*") -or (name -gt "ev
0000*" -and name -lt "ev9999*") `
-or (name -gt "fm0000*" -and name -lt "fm9999*") -or (name -gt "ia
0000*" -and name -lt "ia9999*") `
-or (name -gt "in0000*" -and name -lt "in9999*") -or (name -gt "le
0000*" -and name -lt "le9999*") `
-or (name -gt "md0000*" -and name -lt "md9999*") -or (name -gt "mk
0000*" -and name -lt "mk9999*") `
-or (name -gt "np0000*" -and name -lt "np9999*") -or (name -gt "pb
0000*" -and name -lt "pb9999*") `
-or (name -gt "ps0000*" -and name -lt "ps9999*") -or (name -gt "re
0000*" -and name -lt "re9999*") `
-or (name -gt "sf0000*" -and name -lt "sf9999*") -or (name -gt "so
0000*" -and name -lt "so9999*") `
-or (name -gt "tr0000*" -and name -lt "tr9999*") -or (name -gt "wn
0000*" -and name -lt "wn9999*") ' Error Message: 'Operator Not supported: ' at
position: '95'.
At J:\DATA\IR\ITSecurity\Intern\AlyssaC 2014\Part-time 2014-2015 task\AD\AD cle
an-up\Daily Script\AD-User.MonitorOwnership.ps1:3 char:22
+ $userIDs = Get-Aduser <<<< -filter {(name -gt "w30000*" -and name -lt "w9999
9*") -or (name -gt "we0000*" -and name -lt "we9999*") `
+ CategoryInfo : ParserError: (:) [Get-ADUser], ADFilterParsingEx
ception
+ FullyQualifiedErrorId : Error parsing query: '(name -gt "w30000*" -and n
ame -lt "w99999*") -or (name -gt "we0000*" -and name -lt "we9999*") `
-or (name -gt "cr0000*" -and name -lt "cr9999*") -or (name -g
t "ac0000**" -and name -lt "ac9999*")`
-or (name -gt "cm0000*" -and name -lt "cm9999*") -or (name -g
t "do0000*" -and name -lt "do9999*") `
-or (name -gt "ec0000*" -and name -lt "ec9999*") -or (name -g
t "ev0000*" -and name -lt "ev9999*") `
-or (name -gt "fm0000*" -and name -lt "fm9999*") -or (name -g
t "ia0000*" -and name -lt "ia9999*") `
-or (name -gt "in0000*" -and name -lt "in9999*") -or (name -g
t "le0000*" -and name -lt "le9999*") `
-or (name -gt "md0000*" -and name -lt "md9999*") -or (name -g
t "mk0000*" -and name -lt "mk9999*") `
-or (name -gt "np0000*" -and name -lt "np9999*") -or (name -g
t "pb0000*" -and name -lt "pb9999*") `
-or (name -gt "ps0000*" -and name -lt "ps9999*") -or (name -g
t "re0000*" -and name -lt "re9999*") `
-or (name -gt "sf0000*" -and name -lt "sf9999*") -or (name -g
t "so0000*" -and name -lt "so9999*") `
-or (name -gt "tr0000*" -and name -lt "tr9999*") -or (name -g
t "wn0000*" -and name -lt "wn9999*") ' Error Message: 'Operator Not suppor
ted: ' at position: '95'.,Microsoft.ActiveDirectory.Management.Commands.Ge
tADUser
UPDATE 2: this time i did each one individually and they worked???? I don't understand why my main filter doesn't work unless they are filtered individually
Some of them:
$wIDs = Get-Aduser -filter {(name -gt "w30000*" -and name -lt "w99999*")} -Properties * | Select name, SurName, DisplayName, enabled
$weIDs = Get-Aduser -filter {(name -gt "we0000*" -and name -lt "we9999*")} -Properties * | Select name, SurName, DisplayName, enabled
foreach ($user in $wIDs) {
if ($user.DisplayName -like "*-DISABLED"){
#$groups = get-Adgroup -properties managedby -filter {managedby -eq $user.name}
write-host "User ID: " $user.name
write-host "Last Name: " $user.SurName
write-host "Display Name: " $user.DisplayName
write-host $break1 "Next User:" $break1
}#end of if statement
}#end foreach
foreach ($user in $weIDs) {
if ($user.DisplayName -like "*-DISABLED"){
#$groups = get-Adgroup -properties managedby -filter {managedby -eq $user.name}
write-host "User ID: " $user.name
write-host "Last Name: " $user.SurName
write-host "Display Name: " $user.DisplayName
#write-host "Managed Groups: " $groups
write-host $break1 "Next User:" $break1
}#end of if statement
}#end foreach
These print correctly with no errors????
The use of -Filter is preferred for performance reasons since Get-ADUser wont be returning all user objects. However, in this case, I think because of the amount of conditional criteria that a regex based after the fact might be a better fit for this. So unless you have 10's of 1000's of users this should work just fine. Also you are returing all user properties but then only taking 4. That would be a performance hit in itself. The only thing that is not default is Enabled so we will be sure to take that.
$prefixes = "cr","cm","ec","fm","in","md","np","ps","sf","tr","ac","do","ev","ia","le","mk","pb","re","so","wn","we","w[3-9]"
$regex = "^($($prefixes -Join "|"))\d*"
$results = Get-ADUser -Filter * -Properties Enabled,DisplayName |
Where-Object{$_.Name -match $regex} |
Select Name,SurName,DisplayName,Enabled
$results
Basically building a regex match string where the name must start with one of the groups of two characters* (the w30000 criteria is different than the other so that is why at the end you see w[3-9] which mean "w" followed by a number that is "3 to 9") which is followed by some numbers. The string is built from the array of $prefixes that you can add and remove as you please.
This might not fit your exact criteria but it can be changed easily depending on what it is matching. Pretty sure as well that -lt,-gt,etc does not support wildcards. Think it treats them as the literal asterisks character. -like and -notlike support wildcards.
Are there account that exist with different 2 character prefixes? If not this could be done with a much simple regex like ^\w{2}\d+ which is 2 characters followed by at least one digit.
Does this work for you?
Get-Aduser -filter {name -gt "w3000" -and name -lt "w9999"}
Edit:
Given new requirements:
$prefixes = "cr","cm","ec","fm","in","md","np","ps","sf","tr","ac","do","ev","ia","le","mk","pb","re","so","wn","we"
#Create filter for searches
$DNFilters = $prefixes -replace '^','(Name=' -replace '$','*)'
$Filter = "(|$DNFilters)"
Get-ADUser -LDAPFilter $Filter -Properties Enabled |
Where-Object {$_.name -like '??[0-9][0-9][0-9][0-9]'}
That will let you use early filtering to return just the accounts with names that match the prefixes. The late filter (Where-Object) will then filter the ones that don't have 4 digits following.
Edit:
This line:
$DNFilters = $prefixes -replace '^','(Name=' -replace '$','*)'
Takes each prefix, and pre-pends the string '(Name=' and then appends the string '*)' to it. The result is, for e.g. the prefix 'cr' will become '(Name=cr*)' . That is the LDAP filter for any name that starts with 'cr'.
Then this line:
$Filter = "(|$DNFilters)"
wraps those in '(|' and ')' . The '|' in an LDAP filter means 'OR'. The resulting filter looks like this:
(|(Name=cr*) (Name=cm*) (Name=ec*) (Name=fm*) (Name=in*) (Name=md*) (Name=np*) (Name=ps*) (Name=sf*) (Name=tr*) (Name=ac*) (Name=do*) (Name=ev*) (Name=ia*) (Name=le*) (Name=mk*) (Name=pb*) (Name=re*) (Name=so*) (Name=wn*) (Name=we*))
All of the individual LDAP filters are ORed together into one filter.
In this line:
Where-Object {$_.name -like '??[0-9][0-9][0-9][0-9]'}
the ?? means "any two characters". In wildcard match (-like) the ? means "any single character".

Conditional PowerShell operators

I am trying to get a list where the title does not have temp or temporary or *contractor or contractor*.
This code is working, meaning I get a list which does not have temporary records.
$pTitle = $profile["Title"]
if ($pTitle -ne "Temporary")
However the following code does not work when I add -or and -notlike for the wildcard.
$pTitle = $profile["Title"]
if ($pTitle -ne "Temporary" -or $pTitle -notlike "Temporary" -or $pTitle -notlike "contractor" -or $pTitle -notlike "Temp")
You actually want -and here. Your expression will only evaluate to false if all of the words are found currently.
$List = #(1,2,3)
If I ask you to return all the items in the list that are:
not equal to 1
or
not equal to 2
or
not equal to 3
the answer will be the whole list
$List | where { ($_ -ne 1) -or ($_ -ne 2) -or ($_ -ne 3) }
1
2
3
You are getting your logical operators mixed up.
Look at replacing -or with -and