Simple PowerShell, Variable inside bracket no working - powershell

I'm missing formatting or something simple having to do with the variable. When I enter the variable data, no output. If I enter the SMTP: address manually script works fine.
$EmailAddressAlias=Read-Host "Enter the FULL Email Address to find the associated Mailbox "
Get-Mailbox -Identity * |
Where-Object {$_.EmailAddresses -like 'SMTP:$EmailAddressAlias'} |
Format-List Identity, EmailAddresses

I see two issues here, and a suggestion. You've got a variable inside single quotes, and you have no wildcards in your -like comparison. In order for the variable to expand into its value you need to use double quotes like this:
$_.EmailAddresses -like "SMTP:$EmailAddressAlias"
Also, when you use -like with no wildcards you may as well be using -eq. Lastly, you should really filter at the Get-Mailbox level rather than getting all mailboxes, and then filtering for just the one you want. You may want to try this instead:
Get-Mailbox -Filter "EmailAddresses -like '*$EmailAddressAlias*'" | Format-List Identity, EmailAddresses

Related

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

Powershell Expression gives no results

I have created an expression that should return the OU canonical name. A small outline:
#(Search-ADAccount -LockedOut -UsersOnly) | Select-Object Name,SamAccountName,#{Name="OU";Expression={((Get-ADOrganizationalUnit -Identity $($_."DistinguishedName")).CanonicalName)}}
However, this expression returns an empty OU column, the other 2 columns are filled.
My question is what is wrong with this expression? Any feedback is appreciated.
With kind regards,
TheStingPilot
A troubleshooting technique for calculated properties:
The script block stored in the Expression entry of a hashtable defining a calculated property:
runs in a child scope relative to the caller's scope.
more importantly, it quietly ignores any errors that occur.
However, such errors are recorded in the automatic $Error variable, so to diagnose your problem you can do the following:
$Error.Clear()
Search-ADAccount -LockedOut -UsersOnly |
Select-Object Name, SamAccountName, #{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName).CanonicalName}}
$Error # Output the errors that occurred inside the calculated property's script block.
Solution to your specific problem:
As Santiago Squarzon's helpful answer explains, you need to extract the OU's distinguished name (DN) from the user's and pass the former to Get-ADOrganizationalUnit -Identity.
While $_.DistinguishedName.Split(',',2)[1], which removes the first ,-separated token from the user's DN will typically work, it can fail with DNs that use escaped , chars. (\,) that are to be treated as part of a value; e.g.:
# !! Simple splitting by the first "," is NOT enough here:
PS> 'CN=Martin Luther King\, Jr.,OU=Ministry,DC=example,DC=org'.Split(',',2)[1]
Jr.,OU=Ministry,DC=example,DC=org # !! WRONG - split at the *escaped* ","
To also handle these edge cases, i.e. to robustly extract the OU's DN from a user's, a sophisticated regex is required, in combination with the -replace operator:
# OK: The regex correctly recognizes the escaped \, as such.
PS> 'CN=Martin Luther King\, Jr.,OU=Ministry,DC=example,DC=org' -replace '^.+?((?<=[^\\])(?:\\\\)*),'
OU=Ministry,DC=example,DC=org # OK
To put it all together:
Search-ADAccount -LockedOut -UsersOnly |
Select-Object Name,
SamAccountName,
#{
Name = 'OU'
Expression = {
(Get-ADOrganizationalUnit -Identity ($_.DistinguishedName -replace '^.+?((?<=[^\\])(?:\\\\)*),')).CanonicalName
}
}
The issue with your code is that you're trying to feed Get-ADOrganizationalUnit a user's DistinguishedName instead of an OU's DistinguishedName which is not valid.
It's also worth mentioning, you're missing -Properties CanonicalName on Get-ADOrganizationalUnit.
Try this instead:
$e={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}
Search-ADAccount -LockedOut -UsersOnly |
Select-Object Name, SamAccountName, #{Name="OU";Expression=$e}

Using filter to find email addresses matching a domain

I'm trying to find email addresses in O365 Exchange that matches a particular domain using PowerShell.
If I use:
Get-Recipient -ResultSize unlimited -filter '(PrimarySMTPAddress -like "*smith*")' | fl primarysmtpaddress
I get all the addresses that have the string
If I use:
Get-Recipient -ResultSize unlimited -filter '(PrimarySMTPAddress -like "*#domain*")' | fl primarysmtpaddress
I get no results.
It looks like nothing is matched after the #.
I want to use -filter rather than a where statement because it is so much faster.
I was able to reproduce your issue. It seems to be related to the the specific attribute you filtered on, "PrimarySMTPAddress".
I was able to get the filter statement to return results by changing it to leverage "EmailAddresses", another attribute the email address is stored in:
Get-Recipient -ResultSize unlimited -filter '(EmailAddresses -like "*#domain*")' | fl primarysmtpaddress
Something else I saw of note: the "filterable properties" documentation mentions avoiding using "PrimarySMTPAddress" for another reason that I didn't know of:
Don't use the PrimarySmtpAddress property; use the EmailAddresses property instead. Any filter that uses the PrimarySmtpAddress property will also search values in the EmailAddresses property. For example, if a mailbox has the primary email address dario#contoso.com, and the additional proxy addresses dario2#contoso.com and dario3#contoso.com, all of the following filters will return that mailbox in the result: "PrimarySmtpAddress -eq 'dario#contoso.com'", "PrimarySmtpAddress -eq 'dario2#contoso.com'", or "PrimarySmtpAddress -eq 'dario3#contoso.com'".
Source
https://learn.microsoft.com/en-us/powershell/exchange/filter-properties?view=exchange-ps

Import-CSV and Foreach to use Get-ADUser

I have a CSV file that looks like this:
name
fname1lname1#companyemail.com
fname2lname2#companyemail.com
...
I would like to loop through each email address and query AD for that address to grab the user objects ID. I have been able to do this using a script, but I would like to be able to do it using just one line.
This is what I've done so far:
import-csv -path .\csv_file.csv | foreach-object { get-aduser -filter { proxyaddresses -like "*$_.name*} | select name } | out-file .\results.csv
This obviously doesn't work and I know it has something to do with how I am handling my $_ object in the foreach loop.
I'm hoping for the output to look something like:
fname1lname1#companyemail.com,userID1
fname2lname2#companyemail.com,userID2
...
You are filtering on the property proxyaddresses however that is not part of the default property set that Get-AdUser returns. Also your code had a errant " which might have been a copy paste error.
Import-CSV -Path .\csv_file.csv | ForEach-Object {
Get-ADUser -Filter "ProxyAddresses -like '*$($_.name)*'" -Properties ProxyAddresses,EmailAddress | select EmailAddress,SamAccountName
} | Export-CSV .\results.csv -NoTypeInformation
-Filter can be tricky sometimes as it is looking for string input. Wrap the whole thing in quotes and use a sub expression to ensure that the variable $_.Name is expanded properly and has is asterisks surrounding it.
Since you are also looking for emailaddress we add that to the properties list as well. I will assume the second column is for samaccountname.
We also use Export-CSV since that will make for nice CSV output.
If you're using Exchange this can be much simpler and faster if you use the Exchange cmdlets:
Import-CSV -Path .\csv_file.csv | ForEach-Object {
Get-Recipient $_ |
Select PrimarySMTPAddress,SamAccountName
} | Export-CSV .\results.csv -NoTypeInformation
Exchange requires all email address to be unique, and maintains it's own internal database that uses email address as a primary index so it can return the DN and SamAccountName that goes with that email address almost immediately.
AD doesn't require them to be unique, so it doesn't index on that attribute and it has to search every user object looking for the one that has that email address in it's proxy address collection.

-eq and -ne give me the same results

Why do the following two command, with the only difference the -eq and -ne operator give me my list of DCs?
Get-ADComputer -Filter {(operatingsystem -like "*server*") -AND
(PrimaryGroup -eq "CN=Domain Controllers,CN=Users,DC=domain,DC=com") }
-Property Name,PrimaryGroup
I'd expect this one to have everything, but domain controllers.
Get-ADComputer -Filter {(operatingsystem -like "*server*") -AND
(PrimaryGroup -ne "CN=Domain Controllers,CN=Users,DC=domain,DC=com") }
-Property Name,PrimaryGroup
If I run the equivalent against PrimaryGroupID instead of PrimaryGroup, it works as expected.
I actually get an error when trying both commands. Did a little digging and the filter was causing the problem. Had a quick look in ADSIEdit at a server object. It doesn't appear to have a attribute called "PrimaryGroup".
This was in a 2008 R2 AD running in 2008 R2 forest and domain functional levels.
As an aside, if you want a list of DC in a domain get-ADDomainController will do the job.
regards
Arcass
If you want to put one statement on separate lines, you need to put the backtick (`) at the end of the line to tell PowerShell that the statement continues on the next line. However, even then, you cannot split the filter on two different lines. So it should look something like this:
Get-ADComputer -Filter {(operatingsystem -like "*server*") -AND (PrimaryGroup -eq "CN=Domain Controllers,CN=Users,DC=example,DC=com") } `
-Property Name,PrimaryGroup
As you've found, AD doesn't actually have an attribute called PrimaryGroup. That is a property that PowerShell exposes to you, which interprets the value in the primaryGroupId attribute for you.
The primaryGroupId attribute of any object has the Relative Identifier (RID) of the group. The RID is the last section of number in the SID, but the group also stores this value in its primaryGroupToken atrribute. So you can get this value like this:
$primaryGroupToken = (Get-ADGroup "Domain Controllers" -Properties primaryGroupToken).primaryGroupToken
PowerShell has to convert what you pass into the -Filter parameter into a proper LDAP query, so when you use PrimaryGroup in the filter, PowerShell is doing that for you.
However, doing that lookup is not really necessary in this case, because the Domain Controllers group is a built-in group and always has an RID of 516. So you can do what you're trying to do like this:
Get-ADComputer -Filter "operatingsystem -like '*server*' -AND PrimaryGroupId -eq 516" `
-Property Name,PrimaryGroup