I’m trying to clean up my AD user accounts, in the past my organization would put a date in the beginning of the Description field for the users…
I can get all the text in Description field using PowerShell but I don’t know how to delete only the date in the “Description” field.
And the date in the field is written in the following formats: mm/dd/yy or mm/dd/yyyy
Get-ADUser -SearchBase $OU_To_Search -Filter {(description -like '*/*/* ^az') -and (enabled -eq $true)} -Properties cn,description | Export-csv C:\temp\A_Users.csv
I’m sure there is a better way of getting the date… but I’m not there yet.
You could set the Description field to a variable and use the -replace parameter to remove the date like so:
$this = $this -replace "([0-9]+)/([0-9]+)/([0-9]+) ",""
Then, it's just a matter of using Set-ADUser to replace the current description
You can put your search, and then run your results through a -replace option and replace the regex filter of \d{1,2}/\d{1,2}/\d{2,4}\s? (that's 1 or 2 numbers, followed by a slash, followed by 1 or 2 number, followed by a slash, followed by two through four numbers, and then if there's a space after it include that) and just leave off the item to replace it with so it simply removes it. Then output the updated result. Lastly I have it exporting to a CSV as you did above.
Get-ADUser -SearchBase $OU_To_Search -Filter {(description -like '*/*/* ^az') -and (enabled -eq $true)} -Properties cn,description|%{$_.Description -Replace "\d{1,2}/\d{1,2}/\d{2,4}\s?";$_}| Export-csv C:\temp\A_Users.csv
Alternatively you could have it Set-ADUser $_ instead just outputting it to the pipe to be exported to CSV. To do that you would change ;$_} to ;Set-ADUser $_} and leave off the |Export-CSV bit at the end.
Related
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
Trying to make a list of users who's names were changed after account creation for various reason (i.e. marriage, etc...)Came across a few ideas, but nothing panned out after I got stumped with Get-ADuser -Filter -Searchbase. Basic idea was to match the users first/last name with the right format for a username ($n = $.firstname.substring(0,1) + $.surname) against the current SamAccountUser name. Then that failed so just tried to simplify with matching the last names and getting a list from there.
The code below has no output (meaning that when ran the line is blank). The goal is to provide a listing of users by csv, however I wasn't able to get an output so I haven't gotten that far.
I feel like I'm missing something obvious so any help would be appreciated.
Get-ADUser -Filter * -SearchBase "CN=sample,OU=samples ,DC=sampler,DC=sampling" -Properties SamAccountName, surname | Where-Object {($_.SamAccountName.substring(1)) -ne $_.surname}
You could try it with Compare-Object, that should give you a list of differences (in both ways). If you pipe it to Out-GridView, you can filter it and copy/paste it to Excel.
We use "GivenName"."Surname" as SamAccountName, this has to be edited to your needs.
$users = Get-ADUser -Filter * -SearchBase "OU=Users,DC=contoso,DC=com" -Properties SamAccountName,Surname,GivenName
foreach($user in $users)
{
$compare += Compare-Object -DifferenceObject $user.SamAccountName -ReferenceObject ($user.GivenName + "." + $user.Surname)
}
$compare | Out-GridView
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.
I have created a script that would allow for the addition of the values "1-" to the beginning of our current AD fax numbers. I am running this in a test environment and the script runs exactly as I want it. I am looking for a failback and I can't seem to get that script to remove the "1-" it instead removes the 1 from the beginning and the final number from the end of the fax so the output looks like this: "-(###)-###-###" instead of looking like the correct number format "(###)-###-####"
Get-ADUser -Filter {facsimileTelephoneNumber -like "*"} -Properties facsimileTelephoneNumber| foreach {Set-ADUser -Identity $_ –replace #{facsimileTelephoneNumber="1-$($_.facsimileTelephoneNumber)"}}
Get-ADUser -Filter {facsimileTelephoneNumber -like "*"} -Properties facsimileTelephoneNumber| foreach {Set-ADUser -Identity $_ –replace #{facsimileTelephoneNumber="$(($_.facsimileTelephoneNumber).Substring(1,($_.facsimileTelephoneNumber.length) -2 ))"}}
Following my answer to your previous question where the 1- is added to the fax number, this is how you can reverse that.
I see in your question you are trying to do it all as one-liners, thereby skipping all possibility to check your code step-by-step. Using the first oneliner in your question also prepends 1- to simply every faxnumber found, regardless if it is needed or not.
Especially when just starting PowerShell, writing things out is a good thing.
Having said that, here's the code to remove the leading 1- from faxnumbers
# Remove leading '1-' from ADUsers faxnumbers
Import-Module ActiveDirectory
# get all users in the specified OU that have a fax number starting with '1-'
Get-ADUser -LdapFilter '(facsimileTelephoneNumber=1-*)' -SearchBase 'OU=UserAccounts,DC=YourDomain,DC=com' -Properties 'Fax' | ForEach-Object {
# using Substring() to remove the first two characters. See: https://ss64.com/ps/substring.html
$newFax = ($_.Fax).Substring(2)
Write-Host "Setting Faxnumber to '$newFax' for user $($_.Name)"
# remove the '-WhatIf' if you are sure the number may be changed
$_ | Set-ADUser -Fax $newFax -WhatIf
}
Hope this helps
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