i have below powershell line. It will return 1 when there is account found in administrators group other than built-in administrator, group1, group2, group3.
If ((Get-LocalGroupMember -Group Administrators | Where-Object {($_.ObjectClass -eq 'User' -or $_.ObjectClass -eq 'Group') -and (($_.Name -notlike "$env:computername\administrator") -and ($_.Name -notlike 'group1') -and ($_.Name -notlike 'group2') -and ($_.Name -notlike 'group3') )}).Count -gt 0) {
echo 1
}else{
echo 0
}
how do i change the above if statement to read in the string value (which has commas) in registry so I don’t need to hard code group1, group2, group3 in the if statement?? Thanks
example i had set it at hklm:\system\test , named as adm and string value of group1,group2,group3
i am able to pull the value i set at registry using this line.
$listofadm = (Get-ItemProperty -Path "HKLM:\system\test" -ErrorAction Stop -Name adm).adm
Not sure why you are checking if user or group, if you can omit that it will simplify your check. To streamline this I would make a regex pattern of all the groups including the computer\adminsitrator account. If the groups indeed do not have a space then you can simply replace the commas with a pipe | character.
$listofadm = "$env:computername\administrator|" +
(Get-ItemProperty -Path "HKLM:\system\test" -ErrorAction Stop -Name adm).adm -replace ',','|'
This will make $listofadm contain something like
DESKTOP-NEKK74J\administrator|group1|group2|group3
Now if you just want to find any object whose name is not any of those 4
Get-LocalGroupMember -Group Administrators | where name -NotMatch $listofadm
Single item checks in the Where clause can omit the { } curly braces. If you do need to ensure it's a user or group object then this is how that would look.
Get-LocalGroupMember -Group Administrators |
Where-Object {($_.ObjectClass -eq 'User' -or $_.ObjectClass -eq 'Group') -and $_.name -NotMatch $listofadm}
Related
How can I exclude specific string collections
CN=HealthMailbox478eb865ff384698bf3ff10c9c889f1c,CN=MonitoringMailboxes,CN=Microsoft
Exchange System Objects,...
CN=HealthMailbox7s7df7s7vn3421nifdfu,CN=MonitoringMailboxes,CN=Microsoft Exchange System Objects,...
OU=Disabled Computers
OU=Service Accounts
from the result of the script below:
Get-ADObject -Filter 'ObjectClass -eq "user" -or ObjectClass -eq "computer" -and isDeleted -ne $True -and isRecycled -eq $false -and name -ne "Deleted Objects"'
Updated as per #Theo:
Get-ADObject -Filter "ObjectClass -eq 'user' -or ObjectClass -eq 'computer' -and isDeleted -ne $True -and isRecycled -eq $false -and name -ne 'Deleted Objects'"
However, the error is still:
Get-ADObject : Error parsing query: 'ObjectClass -eq 'user' -or ObjectClass -eq 'computer' -and isDeleted -ne True -and isRecycled -eq False -and name -ne 'Deleted Objects''
Error Message: 'syntax error' at position: '74'.
At line:1 char:1
+ Get-ADObject -Filter "ObjectClass -eq 'user' -or ObjectClass -eq 'com ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Get-ADObject], ADFilterParsingException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADFilterParsingException,Microsoft.ActiveDirectory.Management.Commands.GetADObject
From within the -Filter argument You'll have a hard time excluding on the basis of when a collection contains a value. This may be a case to filter as much as you can on the left, but append a post filtering Where{} . The rule is to filter "as much as you can, as far left as you can" (quotes are mine). There are always going to be cases where there's a little more to be done. Something like:
$Exclusions = "Server1","Server2"
Get-ADObject ... | Where-Object{ $_.Name -notin $Exclusions }
Or:
Where-Object{ $Exclusions -notcontains $_.Name }
In similar cases I like to create a $Exclusions array, so it can be appended as needed while you are dev-ing or for later maintenance.
Note: You may not need -and isDeleted -ne $True If the
-IncludeDeletedObjects' parameter is any indication Get-ADObjectexcludes them by default. Also, as written it's another inversion, the literal idea "not deleted" is easier to read asisDeleted -eq
$false`
That said, and with the limited example above, you might be able to add Name -notlike "HealthMailbox*" to your filter string. You could probably add additional -and -notlike ..., but who knows when that'll get out of hand.
As I mentioned in my other answer Get-ADObject seems to reject double quoted queries as suggested in previous comments. Granted this seems to be unusual and backwards behavior, but in testing Get-ADObject seems to expect expansion of $true/$false. Replacing with single quotes just makes it fail. Indeed and so far as I can tell the query as given in the question is working. I invite others to comment...
Nevertheless About_Quoting_Rules, doc may be a helpful refresher...
Note: The AD cmdlets are known to be finicky regarding the typing of the -Filter's argument, so to a certain extend I'm not surprised.
I'm trying to write a script that will log out users which don't have specific process running in their session.
I guess the workflow should look like:
Get usernames of all the users logged in, get list of all the processes runnning on the workstation, check if X process is running for Y user, if not, then log user Y out.
So far i managed to create object with all the users currently logged in:
((quser) -replace '^>', '') -replace '\s{2,}', ',' | ConvertFrom-Csv
And list of all the processes running with usernames:
get-process -IncludeUserName
I believe foreach with if inside should do the job, but I can't quite get my head around it. I would appreciate any help.
Thanks!
edit:
$process = get-process -IncludeUserName|Where-Object{
($_.ProcessName -Like "processIneed1*") -or
($_.ProcessName -Like "processIneed2*") -or
($_.ProcessName -Like "processIneed") -or
($_.ProcessName -like 'processIneed3*') -and
($_.username -notlike '*userIwantToSkip1*') -and
($_.username -notlike '*userIwantToSkip2*')
}
$users = Get-RDUserSession | Where-Object -Property UserName -NE 'administrator'
$ActiveUsers = $users.username
foreach ($ProcUser in $process.username){
foreach ($ActiveUser in $ActiveUsers){
if ($ProcUser -like "*$ActiveUser*"){
$ActiveUsers = $ActiveUsers -notlike "*$ActiveUser*"
}
}
}
in $activeusers we are left with inactive users.
I will most likely change username to session ID and check it this way.
Next step will be logging off disconnected users.
$process = get-process -IncludeUserName|Where-Object{
($_.ProcessName -Like "processIneed1*") -or
($_.ProcessName -Like "processIneed2*") -or
($_.ProcessName -Like "processIneed") -or
($_.ProcessName -like 'processIneed3*') -and
($_.username -notlike '*userIwantToSkip1*') -and
($_.username -notlike '*userIwantToSkip2*')
}
$users = Get-RDUserSession | Where-Object -Property UserName -NE 'administrator'
$ActiveUsers = $users.username
foreach ($ProcUser in $process.username){
foreach ($ActiveUser in $ActiveUsers){
if ($ProcUser -like "*$ActiveUser*"){
$ActiveUsers = $ActiveUsers -notlike "*$ActiveUser*"
}
}
}
foreach ($inactiveusers in $ActiveUsers){
logoff $inactiveuser
}
When I execute below code, I get an error as : A parameter cannot be found that matches name or. How can I get user list who don't have abc.com or xyz.com in their email address?
Get-ADGroupMember -Identity "AQ" -Recursive | where objectClass -eq 'user' | Get-ADUser -Properties *, "msDS-UserPasswordExpiryTimeComputed", PasswordNeverExpires |
where mail -notmatch "#abc.com" -or "#xyz.com" |
Select-Object #{Label = "SAM Account Name";Expression = {$_.SamAccountName}}
The curly braces (actually a scriptblock with the filter script) can not always be skipped with Where-Object.
You can do Where-Object objectClass -eq 'user' but everything that involves more than a single operator requires to be written as a filter script:
where {$_.mail -notmatch "#abc.com" -or "#xyz.com" }
Now this logic doesn't work, as this is equivalent to the following statement:
where {($_.mail -notmatch "#abc.com") -or $true }
So your where clause is true, regardless of the result of the -notmatch operation. You want two -notmatch operations instead:
Where-Object - { $_.Mail -notmatch '#abc.com' -and $_.Mail -notmatch '#xyz.com' }
Depending on the amount of email addresses, that you want to exclude in your filter script, you might want to use a different approach: Strip the user name from the email address and see, if this address appears in the array of email addresses that you want to exclude.
Where-Object { ( $_.Mail -replace '^[^#]+') -notin '#abc.com','#xyz.com','#foo.bar' }
for multiple conditions use full syntax:
where-object { $_.property -eq $b -and $_.otherproperty -match $a }
You're missing some brackets around your where-clause:
where {objectClass -eq 'user'}
And this:
where {mail -notmatch "#abc.com" -or "#xyz.com"}
Should look like that:
where {mail -notmatch "#abc.com" -or mail -notmatch "#xyz.com"}
Please rethink the logic of your second where since it will always be true.
I'm trying to filter out various user accounts in PowerShell (using the NTFSSecurity module) and it's not working as completely as expected. It is supposed to get an array of $users except for the following conditions:
$users = Get-NTFSAccess $path | Where-Object {
$_.Account -ne "DOMAIN\Domain Admins" -and
$_.Account -ne "Group1" -and
$_.Account -ne "Group2" -and
$_.Account -notlike "SecProj_*" -and
$_.Account -notlike "GRP_SECURE_*"
}
The script filtering out DOMAIN\Domain Admins, Group1, and Group2. These groups are defined directly by name.
The script is NOT filtering out SecProj_* and GRP_SECURE_*.
Am I using the wildcard (*) correctly in the -notlike statement?
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