Reputation: 3
My goal is to get a list of AD computer objects not following naming conventions with the whenCreated property. I am trying to export out a HTML file using the following PowerShell function:
function get_bad_names
{
$result = Get-ADComputer -searchbase $OU
-Filter {Name -notlike 'name1' -and
Name -notlike 'name2' -and
Name -notlike 'name3'}
-Properties whenCreated | sort whenCreated
$result | ConvertTo-Html | Out-File $dir\badnames.html
}
get_bad_names
Is there a more elegant way of structuring the Name filter lines? We have over 40 lines of different "names." In other words, over 40 lines in my script say Name -notlike 'name#' -and
Ideally I'd like for the code to read from a text file and export out the same results.
FYI: this function works but it is not ideally written. Any suggestions would be appreciated.
Upvotes: 0
Views: 5119
Reputation: 3
Thank you to everyone for their feedback. I was impressed how fast the responses were.
I was able to achieve my goal using regular expressions reading from a text file.
My code now looks like this:
[regex]$Expression = Get-Content $dir\regex.txt
function get_bad_names
{
$result = Get-ADComputer -searchbase $OU
-Filter {Enabled -eq $true}
-Properties whenCreated | Where-Object {$_.Name -notmatch $Expression}| sort whenCreated
$result | ConvertTo-Html | Out-File $dir\badnames.html
}
get_bad_names
Upvotes: 0
Reputation: 174475
If you'd like to filter the query, construct an LDAP filter:
# Define the names to exclude
$NamesToExclude = "Name1","Name2","Name3"
# Turn them into LDAP clauses in the form of "(!(Name=Name1))"
$LDAPClauses = $NamesToExclude |ForEach-Object {
'(!(Name={0}))' -f $_
}
# Create a single query filter string with all the clauses from above
$LDAPFilter = "(&$LDAPClauses)"
$result = Get-ADComputer -LDAPFilter $LDAPFilter -SearchBase $OU -Properties whenCreated |Sort-Object whenCreated
Upvotes: 1
Reputation: 32155
Is there a more elegant way of structuring the Name filter lines?
Not exactly. You have a fairly limited set of operators when you use the -Filter
parameter of commands in the ActiveDirectory module because it has to translate them all to LDAP filters.
However, you can do something like this:
$ExcludedPatterns = 'Name1', 'Name2', 'Name3'
$ComputerFilter = foreach ($Pattern in $ExcludedPatterns) { "(Name -notlike '$Pattern')" }
$ComputerFilter = $ComputerFilter -join ' -and '
Get-ADComputer -Filter $ComputerFilter
Now you can maintain a list of name patterns.
Keep in mind that the -Filter
property is not a ScriptBlock on the ActiveDirectory commands. They're all Strings and in spite of the documentation for these commands they should be written that way. Writing them as ScriptBlocks will eventually cause you problems with variable expansion.
Compare:
$ComputerName = hostname
Get-ADComputer -Filter "Name -eq '$ComputerName'"
Get-ADComputer -Filter { Name -eq '$ComputerName' }
Upvotes: 0
Reputation: 1660
You could filter with a regular expression using Select-Object
but then you should get all computers in the OU with the -filter *
, and that might strain your network. I would do the filtering and if more properties are needed, run Get-Computer
again only for the matches:
Get-ADComputer -searchbase $OU -Filter * |
? { $_.name -match "name\d{1,2}" } | # Match if string "name" is followed one or two digits
Get-ADComputer -property * # Get all properties for the computers if needed
Upvotes: 0