filter single parameter multiple values - powershell

I have the below code that gives me all users with enabled accounts, and description not like "Shared Account", "Service Account" or "Resource Account".
Get-ADUser -Filter {(SamAccountName -notlike "nam-svc*") -and (SamAccountName -notlike "nam_svc*") -and (enabled -eq $true) -and (description -notlike "Shared Account*") -and (Description -notlike "service account*") -and (description -notlike "Resource Account*") } -Properties memberof
How can I simplify my code so that it is not as cluttered?

The -and operator gives you free continuation across line breaks, so you could indent it like so:
Get-ADUser -Filter {
(enabled -eq $true) -and
(SamAccountName -notlike "nam-svc*") -and
(SamAccountName -notlike "nam_svc*") -and
(description -notlike "Shared Account*") -and
(Description -notlike "service account*") -and
(description -notlike "Resource Account*") } -Properties memberof
If you have many additional parameter arguments you want to pass to Get-ADUser, I suggest combining with splatting:
$ADUserParams = #{
Filter = {
(enabled -eq $true) -and
(SamAccountName -notlike "nam-svc*") -and
(SamAccountName -notlike "nam_svc*") -and
(description -notlike "Shared Account*") -and
(Description -notlike "service account*") -and
(description -notlike "Resource Account*")
}
Properties = 'memberof'
SearchBase = "OU=target,DC=domain,DC=tld"
SearchScope = 'subtree'
Server = 'some-specific-DC.domain.tld'
}
Get-ADUser #ADUserParams

Related

PowerShell Multiple -and operators?

Is there a simpler way to do this? Or does it require me to type out each -and/-notlike for each of the criteria?
Where-Object {$_.DistinguishedName -like "<Enter Domain OU>"} |
Select-Object UserPrincipalName |
Where-Object `
{$_.UserPrincipalName -notlike 'a-*' `
-and $_.UserPrincipalName -notlike 'falkon*' `
-and $_.UserPrincipalName -notlike 'test*' `
-and $_.UserPrincipalName -notlike '*whiteboard*' `
-and $_.UserPrincipalName -notlike '*CSC*' `
-and $_.UserPrincipalName -notlike '*autopilot*'} |
Sort-Object UserPrincipalName
Unfortunately, he can't use -match in an AD filter, but he can use -notlike. The poster can drop the backticks and use operators to continue lines at least. Distinguishedname can't be in an AD filter.
get-aduser -filter "UserPrincipalName -notlike 'a-*' -and
UserPrincipalName -notlike 'falkon*' -and
UserPrincipalName -notlike 'test*' -and
UserPrincipalName -notlike '*whiteboard*' -and
UserPrincipalName -notlike '*CSC*' -and
UserPrincipalName -notlike
'*autopilot*'" -searchbase 'DC=stackoverflow,DC=com' -resultsetsize 1
You can do the following string manipulation to build an LDAP Filter for less verbosity on your script and to leverage Active Directory Filtering capabilities.
Worth mentioning, as more users are under the SearchBase Organizational Unit the faster -Filter / -LDAPFilter becomes compared to Where-Object.
$ou = 'OU=some,OU=ou,DC=some,DC=domain'
$notLike = 'a-*', 'falkon*', 'test*', '*whiteboard*', '*CSC*', '*autopilot*'
$filter = '(&(!userprincipalname={0}))' -f ($notLike -join ')(!userprincipalname=')
$params = #{
SearchBase = $ou
SearchScope = 'OneLevel' # Or SubTree for all child OUs under `$ou`
LDAPFilter = $filter
}
Get-ADUser #params | Sort-Object UserPrincipalName

Powershell Scripts inconsistent behavior

I have two powershell scripts that revolve around abandoned accounts. These scripts should exclude six specific OUs in our environment. The first reports all accounts that will require action. The second takes action and disables the accounts based on the same criteria.
For reasons I can't figure out, the disable script is leaving behind users across multiple OUs that it is not taking action on. Any help at all will be appreciated.
Here's the reporting version:
import-module activedirectory
$datestring = Get-Date -f MM-dd-yyyy
$oldDate = [DateTime]::Today.AddDays(-45)
$OUDN1 = "OU=Resource accounts,OU=Domain Users,DC=placeholder,DC=org"
$OUDN2 = "OU=Service Accounts,OU=Domain Users,DC=placeholder,DC=org"
$OUDN3 = "OU=DO NOT DELETE,OU=Disabled Accounts,DC=placeholder,DC=org"
$OUDN4 = "CN=Users,DC=placeholder,DC=org"
$OUDN5 = "OU=User Templates,OU=Domain Users,DC=placeholder,DC=org"
$OUDN6 = "CN=Microsoft Exchange System Objects,DC=placeholder,DC=org"
Get-ADUser -filter {(Enabled -eq $True) -AND ((LastLogonDate -lt $olddate) -OR ((LastLogonDate -notlike "*") -AND (WhenCreated -lt $olddate)))} -Properties DisplayName,Name,LastLogonDate,Modified,info,description,sAMAccountName,WhenCreated | Where-Object {($_.DistinguishedName -notlike "*,$OUDN1") -and ($_.DistinguishedName -notlike "*,$OUDN2") -and ($_.DistinguishedName -notlike "*,$OUDN3")-and ($_.DistinguishedName -notlike "*,$OUDN4") -and ($_.DistinguishedName -notlike "*,$OUDN5") -and ($_.DistinguishedName -notlike "*,$OUDN6")} | Select sAMAccountName,Name,description,LastLogonDate,WhenCreated,Modified,DistinguishedName | Export-CSV c:\Reports\nolog45_$datestring.csv
And here's the action version:
import-module activedirectory
$disUsers = #()
$oldDate = [DateTime]::Today.AddDays(-45)
$OUDN1 = "OU=Resource accounts,OU=Domain Users,DC=placeholder,DC=org"
$OUDN2 = "OU=Service Accounts,OU=Domain Users,DC=placeholder,DC=org"
$OUDN3 = "OU=DO NOT DELETE,OU=Disabled Accounts,DC=placeholder,DC=org"
$OUDN4 = "CN=Users,DC=placeholder,DC=org"
$OUDN5 = "OU=User Templates,OU=Domain Users,DC=placeholder,DC=org"
$OUDN6 = "CN=Microsoft Exchange System Objects,DC=placeholder,DC=org"
$disUsers = Get-ADUser -filter {(Enabled -eq $True) -AND (LastLogonDate -lt $olddate)} -Properties sAMAccountName,Name,SID,Enabled,LastLogonDate,Modified,info,description,DistinguishedName | Where-Object {($_.DistinguishedName -notlike "*,$OUDN1") -and ($_.DistinguishedName -notlike "*,$OUDN2") -and ($_.DistinguishedName -notlike "*,$OUDN3")-and ($_.DistinguishedName -notlike "*,$OUDN4") -and ($_.DistinguishedName -notlike "*,$OUDN5") -and ($_.DistinguishedName -notlike "*,$OUDN6")}
foreach ($name in $disUsers) {
$DistName = $name.DistinguishedName
Disable-ADAccount -Identity $DistName -ErrorAction Continue
}
Today's run for example left 30 accounts that the report script found still enabled. It wasn't permissions, because I could disable the same accounts manually with no problems. No red text was generated, no error output - just seemingly ignored the accounts.
Thanks in advance for your help.
The criteria in both scripts is not the same.
Your reporting script has this, which your action script does not:
-OR ((LastLogonDate -notlike "*") -AND (WhenCreated -lt $olddate))

Powershell Write-Eventlog Linebreak

I'm making a script which searches all Computer with specific Operating systems, run them through a Whitelist and, if there are Computer that are not on the Whitelist, I write an errorlog. The log looks like this right now:
#{Name=Computername1; Operatingsystem=Windows 10 Enterprise; DistinguishedName=CN=la,OU=computers,OU=lu,OU=Hosting,DC=a,DC=b,DC=ch; OperatingSystemVersion=10.0 (10586)}
But it should look like this:
Name=Computername1
Operatingsystem=Windows 10 Enterprise
DistinguishedName=CN=la,OU=computers,OU=lu,OU=Hosting,DC=a,DC=b,DC=ch
OperatingSystemVersion=10.0 (10586)
I want to delete the #{} and the 4 informations should be separated by line breaks.
My code:
$username = $env:UserName
$getad = Get-ADComputer -Filter {(operatingsystem -like "*Windows 10*" -and OperatingSystemVersion -notlike "*16299*" -and OperatingSystemVersion -notlike "*14393*" -and OperatingSystemVersion -notlike "*14279*" -and OperatingSystemVersion -notlike "*15063*" -and OperatingSystemVersion -notlike "*10159*" -and OperatingSystemVersion -notlike "*16193*" -and OperatingSystemVersion -notlike "*17025*" -and OperatingSystemVersion -notlike "*10074*" -and OperatingSystem -notlike "*LTSB") -or (operatingsystem -like "*Windows Vista*") -or (operatingsystem -like "*Windows XP*") -or (operatingsystem -like "*95*") -or (operatingsystem -like "*94*") -or ( operatingsystem -like "*Windows 8*" -and OperatingSystemVersion -notlike "*9600*" -and OperatingSystem -notlike "*LTSB") -or (operatingsystem -like "*2000 Professional*") -or (operatingsystem -like "*2000 Server*") -or (operatingsystem -like "*2003*") -or (operatingsystem -like "*Windows NT*") -or (operatingsystem -like "*Windows 7*" -and OperatingSystemVersion -notlike "*7601*" -and OperatingSystem -notlike "*LTSB")} -Properties ('Name', 'operatingsystem', 'DistinguishedName', 'OperatingsystemVersion') | ? {$_.distinguishedname -notlike "*OU=Oldwin10-Test,OU=a,OU=b,OU=c,OU=d,DC=e,DC=f,DC=ch"}
$whitelisted = Get-Content "C:\Users\$username\Desktop\whitelistedpcs.txt"
$getad | Select-Object Name, Operatingsystem, DistinguishedName,
OperatingSystemVersion | ForEach-Object {
if ($whitelisted -match $_.DistinguishedName) {
}
else{
Write-EventLog -LogName Application -Source "OldWinalert" -EntryType Error -EventId 1 -Message "$_"
}
}
You need to convert the output to string before sending it to the -Message parameter using Out-String will do:
for your case I would try this:
[...] -EntryType Error -EventId 1 -Message ($_ | Format-List | Out-String)
Another option:
else{
$Message = #"
Name: $($_.name)
Operating System: $($_.Operatingsystem)
Distinguished Name: $($_.DistinguishedName)
Operating System Version: $($_.OperatingSystemVersion)
"#
Write-EventLog -LogName Application -Source "OldWinalert" -EntryType Error -EventId 1 -Message $Message
}
and if you want extra line space add `n (for new line) on each line end after the brackets

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
}

How can I exclude particular names from Get-ADComputer results?

I want to get all computers in my domain that are enabled, and have 2003 operating system, and the name of the computers do Not contain ' ping , pict , pire '
Here is what I have, but totally failing:
Get-ADComputer -filter {(Enabled -eq $True) -and (OperatingSystem -like "*2003*")} -properties OperatingSystem | where {($_.Name -notlike 'PING*') -or ($_.Name -notlike 'PICT*') -or ($_.Name -notlike 'PIRE*')} | Select Name
You can use the -notlike operator inside the filter, so there is no need for the where statement. See the Get-ADComputer reference on technet.
As well as changing your -or operators to -and as I mentioned, I put all conditions into the filter ending up with this:
Get-ADComputer -filter {
Enabled -eq $True -and
OperatingSystem -like '*2003*' -and
Name -notlike 'PING*' -and
Name -notlike 'PICT*' -and
Name -notlike 'PIRE*'
} | Select Name