Adding Imported users into multiple groups - powershell

I have code to import users and modify their properties:
Import-Csv users.csv |
select Surname, #{n='GivenName';e={$_.'FirstName'}},
#{n='samaccountname';e={$_.FirstName.substring(0,2) + $_.Surname}},
#{n='UserPrincipalName';e={$_.FirstName.substring(0,2) + $_.Surname}},
#{n='Name';e={$_.'FirstName' + ' ' + $_.'Surname'}} |
New-ADUser -Enabled $true -AccountPassword (ConvertTo-SecureString -AsPlainText "Password1" -Force) -ChangePasswordAtLogon $true -Path "OU=Intake 20XX,OU=Students,OU=Ravenloft users,DC=RAVENLOFT,DC=test" -ProfilePath {"\\TESTSVR\Profiles$\Intake20XX\" +$_.SamAccountName} -HomeDrive "D:" -HomeDirectory {"\\TESTSVR\Work$\Intake20XX\" +$_.SamAccountName} -PassThru |
Foreach-Object {
Add-ADGroupMember -Identity "CN=StudentGroup,OU=Students,OU=Ravenloft users,DC=RAVENLOFT,DC=test" -Members $_
}
What I'm looking to do is add them to a second group in addition to the "Studentgroup" that is already working.

Simply do another Add-ADGroupMember:
Foreach-Object {
Add-ADGroupMember -Identity 'StudentGroup' -Members $_
Add-ADGroupMember -Identity 'othergroup' -Members $_
}
You can use the SamAccountName of the groups, BTW. The distinguished name is not required.
With that said, if you want to add all new users to the same group, it would be better to collect the users in a variable, and then add them all in one go:
$users = Import-Csv users.csv | ... | New-ADUser ... -PassThru
Add-ADGroupMember -Identity 'StudentGroup' -Members $users
Add-ADGroupMember -Identity 'othergroup' -Members $users

Related

List of Active Directory groups not showing from PowerShell code

I input a list of groups for each user in CSV, and tried to create users using PowerShell code.
This is the PowerShell code:
- name: Change group for AD users
ansible.windows.win_powershell:
script: |
[CmdletBinding()]
param (
[array]
$datalist
)
$output = foreach ($user in $datalist) {
$name = $user.SamAccountName
$groups = $user.Groups
$users = Get-ADUser -Filter "SamAccountName -eq '$name'"
Get-ADUser -Filter "SamAccountName -eq '$name'" -Properties MemberOf | ForEach-Object {$_.MemberOf | Remove-ADGroupMember -Members $users -Confirm:$false}
Add-ADGroupMember -Identity $groups -Members $users
}
parameters:
datalist: "{{ hostvars.localhost.list }}"
I ended up getting this error:
"message": "Cannot convert 'System.Object[]' to the type 'Microsoft.ActiveDirectory.Management.ADGroup' required by parameter 'Identity'. Specified method is not supported."
Also tried '$groups':
"message": "Cannot find an object with identity: '$groups' under: 'DC=adexample,DC=local'.",
And "$groups":
"message": "Cannot find an object with identity: 'CN=GroupA,OU=Groups,DC=adexample,DC=local CN=Test Group,OU=Groups,DC=adexample,DC=local' under: 'DC=adexample,DC=local'.",
This is how I input my list of groups into the CSV file:
Groups
CN=GroupA,OU=Groups,DC=adexample,DC=local;CN=Test Group,OU=Groups,DC=adexample,DC=local
CN=GroupA,OU=Groups,DC=adexample,DC=local;CN=Test Group,OU=Groups,DC=adexample,DC=local
What is the right way to write $groups so that my list of groups can be output correctly?
Updated with CSV in plain text:
FirstName,SamAccountName,path,UserPrincipalName,Groups
Greg,gre.b87,"OU=Temporary Users,DC=adexample,DC=local",gre.b87#gmail.com,"CN=GroupA,OU=Groups,DC=adexample,DC=local;CN=Test Group,OU=Groups,DC=adexample,DC=local"
Zee,zeef.cd,"OU=Temporary Users,DC=adexample,DC=local",zeef.cd#gmail.com,"CN=GroupA,OU=Groups,DC=adexample,DC=local;CN=Test Group,OU=Groups,DC=adexample,DC=local"
I adapted bhuvanachand komara's to mine and it worked for me:
$output = foreach ($user in $datalist) {
$name = $user.SamAccountName
$groups = $user.Groups -split ";"
Get-ADUser -Filter "SamAccountName -eq '$samname'"
$users = Get-ADUser -Filter "SamAccountName -eq '$samname'"
foreach ($group in $groups) {
Add-ADGroupMember -Identity $group -Members $user
}
Get-ADUser -Filter "SamAccountName -eq '$samname'" -Properties MemberOf | ForEach-Object {$_.MemberOf | Remove-ADGroupMember -Members $users -Confirm:$false}
}
The main thing is that I need to add $groups = $user.Groups -split ";" and another foreach loop for the groups.
$csvFile = 'path\to\csv\file.csv'
$users = Import-Csv -Path $csvFile
foreach ($user in $users) {
$samAccountName = $user.SamAccountName
$givenName = $user.GivenName
$surname = $user.Surname
$password = $user.Password
$email = $user.Email
$groups = $user.Groups -split ","
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
New-ADUser -SamAccountName $samAccountName -GivenName $givenName -Surname $surname -DisplayName "$givenName $surname" -EmailAddress $email -AccountPassword $securePassword -Enabled $true
foreach ($group in $groups) {
Add-ADGroupMember -Identity $group -Members $samAccountName
}
}
Example CSV
SamAccountName,GivenName,Surname,Password,Email,Groups
user1,chand,komara,Password1,user1#example.com,group1,group2
user2,bhuvan,unnava,Password2,user2#example.com,group2,group3
For each user in the $users array, the code creates a new Active Directory user using the New-ADUser cmdlet with the specified SamAccountName,
GivenName, Surname, DisplayName, EmailAddress, and account password.
It then adds the user to the specified groups using the Add-ADGroupMember cmdlet.

How to fix cannot convert system.object[] error

I am receiving the following error when running this script:
Get-ADGroupMember : Cannot convert 'System.Object[]' to the type
'Microsoft.ActiveDirectory.Management.ADGroup' required by parameter
'Identity'. Specified method is not supported.
Also, the users move from the Win7 group to the Win10 group, but depending on if they are members of the other groups in the if statements, none of the groups in the if statements are moving for any of the users. Please help.
Just for reference the userlist file contains Active Directory usernames in a text file like this:
jsmith
ksmith
etc.
The grouplist text file contains Active Directory groups like this:
Nitro7
Project7
Visio7
Zoom7
SnagIt7
OneNote7
Code:
Import-Module ActiveDirectory
$users = Get-Content -Path .\userlist.txt
$group = Get-Content -Path .\grouplist.txt
$members = Get-ADGroupMember -Identity $group -Recursive
foreach ($user in $users){
Remove-ADGroupMember -Identity "Win7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Win10" -Members $user -Confirm:$false -Verbose
If ($members.SamAccountName -contains $user) {
Remove-ADGroupMember -Identity "Nitro7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Nitro10" -Members $user -Confirm:$false -Verbose
}
If ($members.SamAccountName -contains $user) {
Remove-ADGroupMember -Identity "Project7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Project10" -Members $user -Confirm:$false -Verbose
}
If ($members.SamAccountName -contains $user) {
Remove-ADGroupMember -Identity "OneNote7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "OneNote10" -Members $user -Confirm:$false -Verbose
}
If ($members.SamAccountName -contains $user) {
Remove-ADGroupMember -Identity "Zoom7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Zoom10" -Members $user -Confirm:$false -Verbose
}
If ($members.SamAccountName -contains $user) {
Remove-ADGroupMember -Identity "SnagIt7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "SnagIt10" -Members $user -Confirm:$false -Verbose
}
If ($members.SamAccountName -contains $user) {
Remove-ADGroupMember -Identity "Visio7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Visio10" -Members $user -Confirm:$false -Verbose
}
}
The -Identity property of Get-ADGroupMember is a singleton, not an array.
However, the -Identity property does accept the pipeline for input. So, you may be able to do something like this:
$members = $group | Get-ADGroupMember -Recursive
Although, IMX, some of the AD commands are a bit wonky due to their age. I expect you may need to do something like this:
$members = foreach ($g in $group) { Get-ADGroupMember -Identity $g -Recursive }
The rest of your script has kind of a confused logic, however, so I can't really tell what you're intending to do.
{snip}
Based on your comments, here's what I'd do.
First, I'd change your groups file. Instead of a plain text list of the groups, I'd make it a CSV file with two columns: The old group and the new group.
So, grouplist.csv looks like this:
"OldGroupName","NewGroupName"
"Nitro7","Nitro10"
"OneNote7","OneNote10"
"Project7","Project10"
"SnagIt7","SnagIt10"
"Visio7","Visio10"
"Win7","Win10"
"Zoom7","Zoom10"
Now you have a map for each old group and the group you want to migrate your users to.
Now, we do it like this:
$users = Get-Content .\userlist.txt
$groups = Import-Csv .\grouplist.csv
foreach ($group in $groups) {
$UsersToModify = Get-ADGroupMember $group.OldGroupName -Recursive | Where-Object SamAccountName -in $users
Remove-ADGroupMember -Identity $group.OldGroupName -Members $UsersToModify -Confirm:$false -Verbose -WhatIf
Add-ADGroupMember -Identity $group.NewGroupName -Members $UsersToModify -Confirm:$false -Verbose -WhatIf
}
[Note: Remove the -WhatIf to actually perform the actions.]
For each group, we get a list of the groups members, filter it to the usernames in $users and save that to $UsersToModify. Then, we pass that list of users to the Remove and Add commands. We only need to call it once per each group.
I know you had a special exception for Win7 to Win10, but I don't see where the logic of the script really needs to change to accommodate that. If you want to always add all users in $users to Win10, you could add that manually:
$UsersToAddtoWin10 = $users | Get-ADUser
Add-ADGroupMember -Identity Win10 -Members $UsersToAddtoWin10 -Confirm:$false -Verbose -WhatIf
Import-Module ActiveDirectory
$users = Get-Content -Path .\userlist.txt
foreach ($user in $users){
Remove-ADGroupMember -Identity "View_Win7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "View_Win10" -Members $user -Confirm:$false -Verbose
[array]$grps=Get-ADUser $user -Property memberOf | Select -ExpandProperty memberOf | Get-ADGroup | Select Name
foreach($grp in $grps){
if($grp.Name -match "Nitro7") {
Remove-ADGroupMember -Identity "Nitro7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Nitro10" -Members $user -Confirm:$false -Verbose
}
If ($grp.Name -match "Project7") {
Remove-ADGroupMember -Identity "Project7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Project10" -Members $user -Confirm:$false -Verbose
}
If ($grp.Name -match "OneNote7") {
Remove-ADGroupMember -Identity "OneNote7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "OneNote10" -Members $user -Confirm:$false -Verbose
}
If ($grp.Name -match "Zoom7") {
Remove-ADGroupMember -Identity "Zoom7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Zoom10" -Members $user -Confirm:$false -Verbose
}
If ($grp.Name -match "SnagIt7") {
Remove-ADGroupMember -Identity "SnagIt7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "SnagIt10" -Members $user -Confirm:$false -Verbose
}
If ($grp.Name -match "Visio7") {
Remove-ADGroupMember -Identity "Visio7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Visio10" -Members $user -Confirm:$false -Verbose
}
}
}
Let's see if this will work for you, considering your $user and $group lists are exactly as you show...
#get your users...
$users = Get-Content -Path .\userlist.txt
#get your groups...
$groups = Get-Content -Path .\grouplist.txt
#for each user...
foreach ($user in $users) {
#get their group memberships, expand the property...
$memberOf = Get-ADUser -Identity $user -Properties MemberOf | Select -ExpandProperty memberof
#for each membership found in $groups that also ends in '7'...
foreach ($membership in ($memberOf | Where-Object {($_ -match ($groups -join "|")) -and ($_ -like '*7')})) {
#remove the user from the matched group...
Remove-ADGroupMember -Identity $membership -Members $user -Confirm:$false
#add the user to a group with the same name, replacing 7 with 10...
Add-ADGroupMember -Identity $membership.Replace("7","10") -Members $user -Confirm:$false
}
}
IMPORTANT
Please note that this -match operator will return any other groups that are contained in $groups that also end in 7. If you have additional group names that match that criteria stored in $groups, you will want more filtering on $memberOf for the $membership iteration.
This script will also replace every instance of the character '7' in $membership (a matched group's DistinguishedName), with '10', in order to add $user to the new group. So, make sure that isn't a problem.

How to fix an issue where users aren't moving AD groups

Import-Module ActiveDirectory
$users = Get-Content -Path .\userlist.txt
$group = "Nitro_Win7"
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty Name
foreach ($user in $users){
Remove-ADGroupMember -Identity "Win7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Win10" -Members $user -Confirm:$false -Verbose
If ($members -contains $user) {
Remove-ADGroupMember -Identity "Nitro_Win7" -Members $user -Confirm:$false -Verbose
Add-ADGroupMember -Identity "Nitro_Win10" -Members $user -Confirm:$false -Verbose
}
}
The list of users are migrating successfully from the "Win7" group to the "Win10" group. However, the second step in the if statement does not seem to be working properly. The goal is to also have users removed from "Nitro_Win7" and added to "Nitro_Win10" if they are a member of "Nitro_Win7". After running, if users are a member of "Nitro_Win7", they stay in "Nitro_Win7". This is not working as hoped. Please help!

Remove specific items from a list

I am creating a script that will help my colleagues to create a new AD user. This is what I have done so far:
ipmo activedirectory
$users = import-csv C:\Users\...\Desktop\test_bulk.csv -delimiter ";"
foreach ($User in $users)
{
$Displayname = $User.Givenname + " " + $User.Surname
$Usersurname = $User.Surname
$Userfirstname = $User.Givenname
$SAM = $User.Samaccountname
$OU = $User.path
$password = $User.Password
$newuser = New-ADUser -PassThru -Name $Displayname -SamAccountName $SAM -
GivenName $Userfirstname -Surname $Usersurname -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force)-Enabled $true -Path $OU -ChangePasswordAtLogon $false -PasswordNeverExpires $true -OtherAttributes #{businesscategory="Internal"}
$gpuser = Get-ADPrincipalGroupMembership $User.gpuser | select -ExpandProperty name
Add-ADPrincipalGroupMembership -Identity $newuser -MemberOf $gpuser
}
As you can see I have set a variable $gpuser so I can output a user's group membership to set all these into the new user's membership.
But there is a little hurdle... I need to remove up to three groups from the retrieved list.
I mean each time I output a user's membership I need to remove a few groups IF they are present in the list.
The thing is I don't know how to script that and where to start.
You should take a look at the Where-Object cmdlet and the -notin operator.
Basically you will do something like this:
$excludeFromThisList = #("group1", "group2")
$newGroupList = $gpuser | Where-Object { $_ -notin $excludeFromThisList }

If And statement with a foreach for AD Users in Powershell

$names = Import-CSV C:\PowerShell\TerminatedEmployees.csv
$Date = Get-Date
foreach ($name in $names)
{
Get-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" | select Name | Out-File "C:\Powershell\ADUserMemberships\$($name.TextBox37)Memberships.txt"
$ADgroups = Get-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" | where {$_.Name -ne "Domain Users"}
Remove-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" -MemberOf $ADgroups -Confirm:$false
Disable-ADAccount -Identity "$($name.TextBox37)"
Get-ADUser -Identity "$($name.TextBox37)" | Move-ADObject -TargetPath "OU=DisabledAccounts,OU=XXX,DC=XXX,DC=XXXX,DC=XXX"
Set-ADUser -Identity "$($name.TextBox37)" -Description "Disabled $Date"
}
This is an already working script I have. However, I realized I need to check 2 properties on the AD user to determine if they need to need to go through my foreach statement. Both properties need to be met. If they are then there's no reason for the AD users to be processed.
The AD user is already disabled.
The AD user already resides in the Disabled OU.
I'm thinking this needs to be done in an If -And statement. But does this need to be done before the foreach or inside the foreach?
Start out by retrieving the user account with Get-ADUser and then inspect the Disabled property + compare the Disabled OU to the DistinguishedName of the user:
$names = Import-CSV C:\PowerShell\TerminatedEmployees.csv
$Date = Get-Date
$DisabledOU = "OU=DisabledAccounts,OU=XXX,DC=XXX,DC=XXXX,DC=XXX"
foreach ($name in $names)
{
$ADUser = Get-ADUser -Identity "$($name.TextBox37)"
if(-not($ADUser.Enabled) -and $ADUser.DistinguishedName -like "*,$DisabledOU")
{
# no need to proceed, skip to next name in foreach loop
continue
}
$ADGroups = Get-ADPrincipalGroupMembership -Identity "$($name.TextBox37)"
$ADGroups |Select-Object Name |Out-File "C:\Powershell\ADUserMemberships\$($name.TextBox37)Memberships.txt"
# no need to call Get-ADPrincipalGroupMembership again
$ADgroups = $ADGroups | where {$_.Name -ne "Domain Users"}
Remove-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" -MemberOf $ADgroups -Confirm:$false
Disable-ADAccount -Identity "$($name.TextBox37)"
$ADUser | Move-ADObject -TargetPath $DisabledOU
Set-ADUser -Identity "$($name.TextBox37)" -Description "Disabled $Date"
}