Get-ADUser using old pre-Windows 2000 Logon name instead of CN - powershell

I'm trying to use Add-ADGroupMember cmdlet in PowerShell, but I've realized PS doesn't recognize the object if I use the CN, and it only seems to recognize the pre-Windows 2000 logon name.
That attribute had a character limitation of 20 characters, so some of our accounts have different CNs and Pre-Windows 2000 logon names.
My whole process is:
Step 1: Get a list of my users (this gives me the legacy pre-Windows 2000 logon names):
Get-ADUser -Filter {department –notlike “Field”} –SearchBase “OU=Accounts,OU=HQ,OU=Production,DC=MYDC,DC=MYDC1,DC=MYDC2” -Properties department | select name | Out-file C:\Users\Public\Users.txt
Step 2: Add those users to my security group:
$UserList = Get-Content "C:\Users\Public\Users.txt"
$GroupName = "MY-SEC-Group"
$Members = Get-ADGroupMember -Identity $GroupName -Recursive | Select -ExpandProperty SAMAccountName
ForEach ($user in $UserList)
{
If ($Members -contains $user)
{
Write-Host "$user is member of $GroupName"
}
Else
{
Write-Host "$user is not a member. Attempting to add now, run script again for verification"
Add-ADGroupMember -Identity $GroupName -Members $User
}
}
For all accounts where the legacy logon name and the CN are the exact same, there are no issues. But in situations where they are different, I get the error "Object not found"
Is there a better/more up-to-date cmdlet to use? Maybe one that relies on the CN instead of the legacy logon name? Or do I need to add in CN to all my scripts now?

Get-ADGroupMember returns objects that point to the concrete user in ActiveDirectory and contain different fields including distinguishedName, SamAccountName , SID, Name and so on. In your code you create a txt file with Names (not SamAccountName) but use SamAccountName in Get-ADGroupMember. So, you just compare names with SamAccountName values (that's incorrect).
Just replace
select name | Out-file C:\Users\Public\Users.txt
with
select SamAccountName | Out-file C:\Users\Public\Users.txt
SamAccountName (just as SID) is the unique attribute in AD -
https://blogs.technet.microsoft.com/389thoughts/2017/02/03/uniqueness-requirements-for-attributes-and-objects-in-active-directory/ so, you should use it in your code.

Related

Bulk Disable PowerShell Script Not Executing

I am kinda new to powershell and started a role in support. Working on a powershell script that will do the following things:
Disable a user account
Remove all AD Groups except for Domain Users
Edit the description
Move AD object to a disabled users OU
I think I can probalby change the "$TargetOU = OUPath" because the disabled users OU is never really going to change...if that's the issue then i'll feel like a dumby lol.
I am trying and failing to complete this! I don't know what is going wrong. Powershell isn't faulting out or anything it is just not executing?
Thank you for any help!
My code is here:
Import-Module ActiveDirectory
$TargetOU = "OU=DisabledUsers"
Import-Csv "C:temp\DisableTest.csv" | ForEach-Object {
$samAccountName = $_."samAccountName"
Get-AdPrincipalGroupMembership -Identity $samAccountName {Where-Object -Property Name -Ne -Value 'Domain Users' | Remove-AdGroupMember -Members $samAccountName}
Get-ADUser -Identity $samAccountName | Disable-ADAccount
Get-ADUser -Identity $samAccountName -Description "Disabled Per Request XXXX"
Move-ADObject -Identity $UserDN -TargetPath $TargetOU
}
Need it to do four things:
Disable a user account
Remove all AD Groups except for Domain Users
Edit the description
Move AD object to a disabled users OU
You have several issues:
$TargetOU = "OU=DisabledUsers"
This should be the full distinguished name, so something like OU=DisabledUsers,DC=example,DC=com
Get-AdPrincipalGroupMembership -Identity $samAccountName {Where-Object -Property Name -Ne -Value 'Domain Users' | Remove-AdGroupMember -Members $samAccountName}
The sytax here is messed up. You want to pipe (|) the results from Get-AdPrincipalGroupMembership into Where-Object, but you have braces ({). The closing brace at the end of the line is thus unnecessary. The Where-Object cmdlet also lets you simplify the syntax to something more readable, like Where Name -ne 'Domain Users'.
Get-ADUser -Identity $samAccountName -Description "Disabled Per Request XXXX"
This should be Set-ADUser, which is explains why this isn't changing anything.
Move-ADObject -Identity $UserDN -TargetPath $TargetOU
You haven't defined $UserDN, so it's not going to find the user. And as already mentioned , the target path should be the full distinguished name.
You're also looking up the account several times. Every time you pass just the username, it has to search for the account. As you have it, it would be searching for the account 5 times. You can avoid that (and speed things up) by calling Get-ADUser once and passing the result into each of the other commands.
And just for simplicity, you can omit -Identity since the first parameter is assumed to be the identity.
Putting everything together, it would look something like this:
Import-Module ActiveDirectory
$TargetOU = "OU=DisabledUsers,DC=example,DC=com" #Change this to the real value
Import-Csv "C:temp\DisableTest.csv" | ForEach-Object {
$user = Get-ADUser $_."samAccountName"
Get-AdPrincipalGroupMembership $user | Where Name -ne 'Domain Users' | Remove-AdGroupMember -Members $user
Disable-ADAccount $user
Set-ADUser $user -Description "Disabled Per Request XXXX"
Move-ADObject $user -TargetPath $TargetOU
}

exporting AD users displayName for selected groups only - powershell

I am new to powershell so please excuse me if the answer is quite simple. I am trying to get user list sorted by selected AD groups and export that to table or csv at least. Due to the fact that:
Get-ADGroupMember -Identity "TestGroupName"
... gives me only user IDs for my AD, I used below:
Get-ADGroupMember -Identity "TestGroupName" | Get-ADObject -Properties displayName
This works perfectly but I do not want to type manually each group there so I decided to first export groups that I need which are beginning with "Test":
Get-ADGroup -Filter "name -like 'Test*'" |Select-Object Name | Export-csv -path \Groups.csv
Now I want to use information from Groups.csv to list all user displayName for groups listed in Groups.csv so I tried something like that:
Import-Csv -Path .\Groups.csv | Get-ADGroupMember ForEach($Name in $Groups) | Get-ADObject -Properties displayName | Export-csv -path \UsersByGroups.csv
unfortunately it does not work properly maybe because I still do not get exactly how to use ForEach
Can someone with more experience have a look and help?
Thanks!
Maciej
Just pipe the groups output by Get-ADGroup -Filter ... directly to Get-ADGroupMember:
Get-ADGroup -Filter "name -like 'Test*'" |Get-ADGroupMember |Get-ADObject -Properties displayName

powershell get-adgroupmember is not returning groups that are from a different forest

I can't seem to display groups of an active directory security group. I use the command
get-adgroupmember $group -server $serverName.
It doesn't return an error. It just returns empty results.
So i tried the command
get-adgroup $group -server $serverName -properties memberof
The memberof section is blank.
The one thing that stands out about this security group is that they were originally from another forest. We converted them over to the new forest with sidhistory in place.
The groups show up in "active directory for user and computers" gui. Any thoughts?
Group members added as external contacts , will always escape from get-adgroupmember .
Antidot is
get-adgroup "groupname" -properties member | select -expand member | get-adobject
you are missing the -Identity
get-adgroupmember -Identity $group -Server $serverName | Select SamAccountName

Trying to change displayname in AD LDS with Powershell

I have an online learning management system with most of its data in sql server but its page structure and contents in an AD LDS instance. I have a few classes which have already been set up with 50 pages called "Unused Portfolio 01" through "Unused Portfolio 50". These are their displaynames. Their CNs are "Portfolio 01" through "Portfolio 50".
I need to change the displaynames to each have a different student's name, in the format "Last, First". I am trying to use Active Directory Module for Windows Powershell. Right now I am on a test server trying to make this work for just a few pages. I can't manage to change more than one displayname at a time.
I can get a list of the objects for these pages:
Get-ADObject -Server localhost:389 -filter 'displayname -like "*Portfolio*" -and cn -like "Portfolio*"' -searchbase 'CN=DMIN2013-LMS 101-02,CN=LMS 101,CN=LMS,CN=Academics,CN=Portal,O=Jenzabar,C=US'
I get the distinguishedname, name, objectclass, and objectguid for all three expected objects and no unexpected objects. Great.
I can change any one object's displayname at a time:
set-adobject -Server localhost:389 -identity "CN=Portfolio 01,CN=DMIN2013-LMS 101-02,CN=LMS 101,CN=LMS,CN=Academics,CN=Portal,O=Jenzabar,C=US" -displayname "testing"
The specified object has its displayname changed to "testing". Awesome.
I'm trying to use this to change all of the displaynames for these three objects to "testing" at once, and obviously I have something wrong because it is not working:
Get-ADObject -Server localhost:389 -filter 'displayname -like "*Portfolio*" -and cn -like "Portfolio*"' -searchbase 'CN=DMIN2013-LMS 101-02,CN=LMS 101,CN=LMS,CN=Academics,CN=Portal,O=Jenzabar,C=US' | foreach-object 'set-adobject -Server localhost:389 -identity $_ -displayname "testing"'
The ultimate goal is that I will have a csv file (which I will have gotten from an sql query from the sql server) containing a "number" column 01 to 50, a "lastname" column, and a "firstname" column, and I will change each page's display name to match ", " for each student, but I'm not at that point yet.
Thanks for any help you can offer.
Foreach-Object uses a script block and not a string, so use:
something | Foreach-Object {Do something with $_}
This might be due to the fact that $_ contains an object and not its DN. $_.DistinguishedName. Also what ojk says
Get-ADObject -Server localhost:389 -filter 'displayname -like "*Portfolio*" -and cn -like "Portfolio*"' -searchbase 'CN=DMIN2013-LMS 101-02,CN=LMS 101,CN=LMS,CN=Academics,CN=Portal,O=Jenzabar,C=US' | foreach-object {set-adobject -Server localhost:389 -identity $_.DistinguishedName -displayname "testing"}

Error handling per user

I am trying to list the membership list for each user in the Active Directory Domain. I created the following line:
foreach($_ in $(Get-ADUser -Filter *).Name){
Get-ADPrincipalGroupMembership -Identity $_ | select Name,Groupscope,Groupcategory| sort Name
}
The problem is that running this line of code causes the following error to come up when a user doesn't have any groupmembership.
Get-ADPrincipalGroupMembership : Cannot find an object with identity: 'TEST USER'
under: 'DC=contoso,DC=com'.
Adding -Erroraction Silentlycontinue behind Get-ADPrinicpalGroupMembership does not mitigate the problem. I'd rather not mess around with $ErrorAction. However, changing $ErrorAction to "silentlycontinue" and changing it back after the line completes does work. Not a pretty solution though. Is there any way to prevent the error showing otherwise?
Output for noam's solution: (Only shows a full list of groups available, not the memberships of the users)
name groupScope groupCategory
---- ---------- -------------
Administrators DomainLocal Security
Distributed COM Users DomainLocal Security
Domain Admins Global Security
Domain Users Global Security
Enterprise Admins Universal Security
Group Policy Creator Ow... Global Security
HelpLibraryUpdaters DomainLocal Security
Schema Admins Universal Security
TESTGROUP1 Global Security
Domain Guests Global Security
Guests DomainLocal Security
Denied RODC Password Re... DomainLocal Security
Domain Users Global Security
You could retrieve the MemberOf property and only run Get-ADPrincipalGroupMembership when that property is not null.
$all = Get-ADUser -filter * -property memberOf
foreach ($usr in $all) {
if ($usr.MemberOf) {
$groups = $usr | Get-ADPrincipalGroupMembership | select name, groupScope, groupCategory
$usr.name + " belongs to the following groups:`n"
$groups | sort name | ft -auto
} else {$usr.name + " does not belong to any groups.`n"}
} #close foreach
Custom objects can also be useful for this kind of reporting.
Get-Member is useful for exploring object properties.
Get-ADUser joeUser -Property * | gm | where {$_.memberType -eq "Property"}
I am not sure of the behavior of these cmdlets, but the error you are seeing may be caused by using only the Name property value to identify the object and not it's DN or other unique identifier (Get-ADPrincipalGroupMembership Documentation. Try piping the output of Get-ADUser to Get-ADPrincipalGroupMembership to see if the issue still occurs (see example below). Also, you may want to pipe the contents of Get-ADUser to the next cmdlet so you don't have to store the information returned by Get-ADUser in memory before processing.
Get-ADUser -Filter * | Get-ADPrincipalGroupMembership
If the issue still exists:
You could use a try/catch block:
Get-ADUser -Filter * | %{ `
try
{
Get-ADPrincipalGroupMembership $_
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException]
{
#Log
Write-Host "not found"
}
}