Find missing prefix for computer name - powershell

I am trying to write a script that will automatically find the full asset tag based on the ID of the computer.
For example:
The PC ID is: PC0001
$computerID = PC0001;
But the full asset tag that I need is: WKSPC0001
But these asset tags might have different prefixes, for example DSTPC0002, TBLPC0003 etc. But they all have common pattern: Prefix+PC+ID (the ID is unique and there is no repetition).
I am trying to figure out how to write a query for that in PowerShell but I cant figure it out. I've tried:
$current = Get-ADComputer -Filter {Name -like "*$computerId.text"} |
Select -Property Name
But I was having issues to get it to work.
What am I doing wrong?

A few observations.
You want $computerId to be a string, so $computerID = "PC0001";
The filter expression for Get-ADComputer is expected to be a string also, using curly braces here is wrong. So Get-ADComputer -Filter "..."
Powershell can expand variable values in strings, but it only does that in double-quoted strings. "Name -like '$variable'" will work, but 'Name -like "$variable"' won't.
There is no .text in your $computerId variable. It's a plain string.
Knowing that, try:
$current = Get-ADComputer -Filter "Name -like '*$computerId'"
Other notes
Don't do ... | Select Name unless you really must. Storing the computer object itself will be more versatile. You can do $current.Name when you need it anytime.
Querying the AD with a filter that begins with a wildcard is slow. Try to avoid.
If you have a fixed number of possible prefixes, an LDAP filter like the following will be much faster:
$current = Get-ADComputer -LDAPFilter "(|(cn=WKS$computerId)(cn=DST$computerId)(cn=TBL$computerId))"

Related

Issues getting get-adcomputer to recognize variable in filter

Below is the code I am working with. I have verified that the initial import-csv is working as it should be, and if I change out the variable object for a concrete object, the script works as it should. It just seems to not recognize/use the variable the way that it should.
$CSVOutput = "C:\temp\output.csv"
$Output = foreach($u in $userlastname)
{
Get-ADComputer -Filter {Description -Like '*$u*'} -properties Description | Select Name, Description
}
$Output | Export-Csv $CSVOutput
If I replace the $u in the filter with one of the values from the $userlastname variable, it works, but it just runs the search with the set value as many times as it runs the foreach loop. I am expecting to see several different computer objects that have the different values from $userlastname in their description. Currently it returns nothing, as if it found no values that matched in the description field.
While it’s technically possible to use a scriptblock as a filter in the ADCommands, it isn’t recommended - use a string instead:
Get-ADComputer -Filter "Description -like '*$($u.name)*'" -Properties ...
Using a string will solve your variable substitution issue.
ETA: Comments indicated that you were getting #{Name=User} as the expansion for $u in the filter expression. This is because $u was a structured [PSCustomObject], and you were looking for a single field from that object. The easiest way to get the value of the desired field of the object is simply to use the PowerShell evaluation construct, as given in the edited answer.

How to query the Active Directory using a list of users in a text file for a specific attribute with PowerShell

I'm somewhat basic to Powershell and use one-liner commands only to keep it short and basic.
I would like to do the following: I have a list of users in a text file in the form of UserPrincipalName. I'd like to query this list of users if their accounts are still active/enabled or not. To do so, I'm trying to run the following command, which just reveals nothing in the end (blank output):
gc .\users.txt | foreach {get-aduser -server "corp.xxx.com"
-f 'name -like "$_"' -properties *}| select displayname,enabled
As mentioned, the output is blank with no errors or whatsoever.
I read that aduser doesn't work with pipelines, but I need to find a solution.
Kindly request your support :)
Thanks
Your use of single quotes in your filter is not allowing the expansion of the variable. Double-quotes should be wrapping the filter expression so as to allow the interpolation of the automatic variable $_:
Get-ADUser -Filter "name -like '$_'" ...
Single-quoted strings:
A string enclosed in single quotation marks is a verbatim string. The string is passed to the command exactly as you type it. No substitution is performed.
Also note, you mention in your question that the file has the user's UserPrincipalName attribute, yet you're querying the Name attribute, if that's the case, the filter should be:
Get-ADUser -Filter "UserPrincipalName -eq '$_'" ...
Note the use of -eq instead of -like, for exact matches you should always use this operator, see about_ActiveDirectory_Filter for usage details and examples of each operator.
If you're only interested in DisplayName and Enabled for your output, there is no reason in querying all the user's attributes, -Properties * should be just -Properties DisplayName since Enabled is already part of the default attributes returned by Get-ADUser.
Finally, the -Identity parameter can be bound from pipeline, and this parameter accepts a UserPrincipalName as argument, hence ForEach-Object is not needed in this case:
Get-Content .\users.txt |
Get-ADUser -server "corp.xxx.com" -Properties DisplayName |
Select-Object DisplayName, Enabled

Filter result from Get-ADUser using sAMAccountname

I would like to extract a username from AD using Get-ADUser. The issue I'm having is when using sAMAaccount name as filter, I get multiple results if the value is found in multiple entries. To illustrate, if my samaccountname is 'a123b', and my coworker's is 'c1234d', I get both our names when I run this:
get-aduser -ldapFilter "(samaccountname=*123*)"| select Name
I would like to return only my information based on '123' and not '1234'
I've already tried the following as well to no avail:
get-aduser -Filter "samaccountname -like '*123*'" | select Name
You can narrow it down with a regular expression:
$filter = "[a-zA-Z]123[a-zA-Z]"
Get-ADUser -Filter "samaccountname -like '*123*'" | where { $_.samaccountname -match $filter} | select name
$filter is a simple regex pattern looking for 123 surrounded by letters (uppercase or lowercase)
-match is the operator that allows a regex comparison
When using a partial SamAccountName in a Filter or LDAPFilter, it is more than likely to get multiple results.
To test and return a specific user account, you need the filter to be more specific if possible (depends on what policies your environment uses for accountnames), like
Get-ADUser -Filter "SamAccountName -like 'a123*'" | Select-Object Name
or use an extra Where-Object clause to narrow down the results by some other user property like the firstname for instance:
Get-ADUser -Filter "SamAccountName -like '*123*'" | Where-Object { $_.GivenName -eq 'John' } | Select-Object Name
Mind you, the above examples can still return multiple user objects..
If you have it, the absolute sure way of retrieving a single user object is by using the DistinghuishedName of that user and get the object by using the -Identity parameter. See Get-ADUSer
P.S.:
When using the -like operator or an LDAPFilter, use wildcard characters on the parts of the name that can vary.
Since you can't use regex in the LDAP query, you could use a query like this to tell it to find user accounts that contain 123 but not with a fourth digit:
(&(objectClass=user)(samaccountname=*123*)(!samaccountname=*1231*)(!samaccountname=*1232*)(!samaccountname=*1233*)(!samaccountname=*1234*)(!samaccountname=*1235*)(!samaccountname=*1236*)(!samaccountname=*1237*)(!samaccountname=*1238*)(!samaccountname=*1239*)(!samaccountname=*1230*))
It's ugly, but it works.
Note that, if you have a filter that starts with a wildcard, the index for that attribute cannot be used, so it will have to look at every account to find a match. I added a filter for objectClass, since that is indexed and it will ensure it only looks at user objects.

Get-ADComputer save results as string array?

What is the output format of Get-ADComputer? I'm trying to do something like this to take an inventory.
[string[]]$server_list = Get-ADComputer -Filter * -Property Name # Select-Object Name
However, when I use $server_list in a foreach, I see the object curly brackets like so
foreach ($machine_name in $server_list) {
"processing : $machine_name";
}
output:
#{Name=some-machine-name-123-here}
I just need the actual name value, how do i get that?
The -Property Name parameter is unnecessary, as Get-ADComputer always retrieves the Name property. (This doesn't select only the Name property, as you seem to have thought.)
Rather than -Property Name, append | Select-Object -ExpandProperty Name to your Get-ADComputer command line.
So, my query returned a different result. Thus you might need to do a little work on this.
Basically, -Property says that you want an object with a certain field. Select does more or less the same thing.
If you want to keep your existing solution, expand the property instead of selecting it. This is the best way to do that:
[string[]]$server_list = (Get-ADComputer -Filter * -Property Name).Name
You returned #{} which is powershell's way of representing an object inside a string. In this case, an object that contains properties about your ADComputers, of which you chose to only include "Name". If you included additional properties, you would see a larger comma separated list of type=value.
You can actually remove -Property Name, however this will take longer to run, since you're filtering on the right. (Gathering a lot of data and THEN filtering it to only Name.)

-contains operator failing when it should not be

I am writing a script to create new AD users and doing a test to make sure an existing displayname is not found because New-ADUser will fail if one is found. Can someone help me understand why I might never get a true outcome from the following array list?
$ExistingDNs= Get-ADUser -SearchBase 'OU=whateverOU' -Filter * -Property displayname | select displayname | Out-string
My goal is to load up all the existing displaynames in an OU and then compare this with a method in which I read a CSV file to create a displayname, but I can't seem to get it to return as true.
If ($ExistingDNs.DisplayName -contains $DisplayName)
I was told this should work, but when I try looking at the array it is empty? Only $ExistingDSs shows me the list visually in ISE, where I can see clearly that a name exists that is the same in my CSV file, but the match is never found and never comes back as true even though both are string values I believe.
I'm sure it is because you are using Out-String which breaks the object array that select displayname would have created. Currently your $ExistingDNs is a newline delimited string when you really want a string array.
$ExistingDNs = Get-ADUser -SearchBase 'OU=whateverOU' -Filter * -Property displayname | select -ExpandProperty displayname
Also we use -ExpandProperty so you just end up with an array of strings. That way your conditional statement can be reduced to...
If ($ExistingDNs -contains $DisplayName)