How do I add a user to multiple groups - active-directory

I want to specify a source user and capture the list of the groups that user belongs to. I want to then specify a second user and have the original captured groups added to the new users account.
If user1 is a member of GroupA, GroupB, GroupC I want the script to capture that and add it to user3 when I type his name.
Import-Module ActiveDirectory
$SourceUser = Read-Host -Prompt 'Enter the username of the user whos groups you would like to copy'
$DestUser = Read-Host -Prompt "Enter the username of the user who will get: $SourceUser groups"
$SourceGroups = Get-ADUser $SourceUser -Property MemberOf | % {
$_.MemberOf | Get-ADGroup | select Name | sort name
}
"List of groups for user $DestUser BEFORE script: "
Get-ADUser $DestUser -Property MemberOf | % {
$_.MemberOf | Get-ADGroup | select Name | sort name
}
# ***Where my problem is***
#Add-ADGroupMember $SourceGroups –Member $DestUser
"List of groups for user $DestUser AFTER script: "
Get-ADUser -Identity $DestUser -Property MemberOf | % {
$_.MemberOf | Get-ADGroup | select Name | sort name
}

When in doubt, read the documentation.
Syntax
Add-ADGroupMember [-Identity] <ADGroup> [-Members] <ADPrincipal[]> ...
The -Identity parameter (the first argument) takes a single group identity, not a list of identities. To add a user to a list of groups you need a loop:
$SourceGroups | ForEach-Object { Add-ADGroupMember $_ –Member $DestUser }

Here is the corrected code that now works.
$T2FolderExists = Test-Path "C:\T2\"
$LogsFolderExists = Test-Path "C:\T2\Logs\"
IF ($T2FolderExists -eq $False)
{
New-Item C:\T2\ -type directory
IF ($LogsFolderExists -eq $False)
{
New-Item C:\T2\Logs\ -type directory
}
ELSE
{
}
"`n"
Start-Transcript -Path C:\T2\Logs\CopyMembershipFromADAccount.txt -Append
"`n"
}
ELSE
{
"`n"
Start-Transcript -Path C:\T2\Logs\CopyMembershipFromADAccount.txt -Append
"`n"
}
<#*****Session Paramaters*****>
Set-ExecutionPolicy Unrestricted -force
Import-Module ActiveDirectory
Clear-Host
Write-Host "Enter the username of the user whos groups you would like to copy" -foregroundcolor Green -backgroundcolor Black
$SourceUser = Read-Host
"`n"
Write-Host "Enter the username of the user who will get: $SourceUser groups" -foregroundcolor Green -backgroundcolor Black
$DestUser = Read-Host
"`n"
$SourceGroups = Get-ADUser $SourceUser -Property MemberOf | ForEach-Object {
$_.MemberOf | Get-ADGroup | select Name -ExpandProperty Name | sort name
}
"`n`n"
Write-Host "List of groups for user $SourceUser BEFORE script: "
Get-ADUser $SourceUser -Property MemberOf | ForEach-Object {
$_.MemberOf | Get-ADGroup | select Name -ExpandProperty Name | sort name
}
"`n`n"
Write-Host "List of groups for user $DestUser BEFORE script: "
Get-ADUser $DestUser -Property MemberOf | ForEach-Object {
$_.MemberOf | Get-ADGroup | select Name -ExpandProperty Name | sort name
}
"`n`n"
ForEach ($Group in $SourceGroups)
{
Add-ADGroupMember $Group –Member $DestUser
Write-Host "Adding $Group to $DestUser 's Account" -foregroundcolor Cyan -backgroundcolor Black
}
"`n`n"
Write-Host "List of groups for user $SourceUser BEFORE script: "
Get-ADUser $SourceUser -Property MemberOf | ForEach-Object {
$_.MemberOf | Get-ADGroup | select Name -ExpandProperty Name | sort name
}
"`n`n"
Write-Host "List of groups for user $DestUser AFTER script: "
Get-ADUser $DestUser -Property MemberOf | ForEach-Object {
$_.MemberOf | Get-ADGroup | select Name -ExpandProperty Name | sort name
}
"`n"
Stop-Transcript
Exit

This is what I did:
Import-Module ActiveDirectory
Import-CSV "data.csv" -Delimiter ";" |
ForEach {`
$_.Group1,$_.Group2,$_.Group3,$_.Group4,$_.Group5,$_.Group6 |
Add-ADGroupMember `
-Members $_.Alias`
}
You can have more groups in the script without using them.
And in the "data.csv", you put this (for example):
Alias;Group1;Group2;Group3;Group4
l.salvador;Spanish;Republic;Central;WWW
Although I had an error with "Identity" could not be checked, it worked.

Related

How do I change my powershell script to GUI

I have recently started taking online Active Directory courses and in the process, I have developed a script for moving computers between OUs. The script is fine and running, but I was wondering if someone can help me change it to GUI(exe) file.
I have looked around and it does not seem there is a good place to provide a nice explanation. Code is below:
...script searches a computer given a keyword. user selects one of the computers listed after search. script then searches an OU based on a keyword input from user. Then, then uses chooses an option of the OUs listed after search. Script then moves the computer to that OU.
Import-Module ActiveDirectory
$computerName = Read-Host -Prompt 'Enter The Name of The Computer You Want To Move'
$temp = Get-ADComputer -filter "Name -like '*$computerName*'" -Properties DistinguishedName | Select-Object -Property DistinguishedName
#$comp[0].DistinguishedName.Split("=").Split(",")[1]
Function Select-Computer
{
$counter = 0
Write-Host "Select Item"
foreach ($c in $temp)
{
write-host "$counter :" $c.DistinguishedName.Split("=").Split(",")[1]
$Counter++
}
[ValidateNotNullOrEmpty()]
$Selection = Read-Host -Prompt 'Choose the computer you want to move'
return $temp[$Selection]
}
$returned = Select-Computer
$computerLocation = $returned.DistinguishedName
$keyword = Read-Host -Prompt "Enter a keyword of the OU you want to move to"
$find = Get-ADOrganizationalUnit -Filter "Name -like '*$keyword*'" -Properties DistinguishedName | Select-Object -Property DistinguishedName
Function Select-OU
{
$counter = 0
Write-Host "Select the OU"
foreach ($ou in $find)
{
$canonicalName = Get-ADOrganizationalUnit -Identity $ou.DistinguishedName -Properties CanonicalName | Select-Object CanonicalName
write-host "$counter :" $ou.DistinguishedName.Split("=").Split(",")[1] in "$canonicalName".Split("=").Replace("#", "").Replace("{", "").Replace("}", "").Replace("CanonicalName", "")
#DistinguishedName.Split("=").Replace("OU", "").Replace(",", "/")
#
$Counter++
}
[ValidateNotNullOrEmpty()]
$Selection = Read-Host -Prompt 'Choose the target you OU'
return $find[$Selection]
}
$return = Select-OU
$targetOU = $return.DistinguishedName
Move-ADObject -Identity "$computerLocation" -TargetPath "$targetOU" -Verbose

PowerShell: Add New Value to Array

Using PowerShell I retrieve information from multiple ActiveDirectory groups and output it to a single CSV file. To each row I want to add the name of the group, in addition to the information retrieved. How can I achieve this?
Desired Result:
"CN","Department","co","Company","Group"
"ABCDEF","Media","UK","Global Entertainment","XXX"
Current Result:
"CN","Department","co","Company"
"ABCDEF","Media","UK","Global Entertainment"
My PowerShell code:
#Roles to check membership for
$Roles= #(
'XXX'
'YYY'
)
$FolderName = "C:\"
$OutputAD = #()
foreach ($role in $Roles) {
$GroupMembers = Get-ADGroupMember -identity $role | select name
$GroupMembersArray = $GroupMembers | Foreach {"$($_.Name)"}
$GroupMembersArray | ForEach-Object {
$UserLookup = Get-ADUser -Filter "Name -eq '$_'" -Properties CN,Department,co,Company | Select-Object CN,Department,co,Company
$OutputAD += $UserLookup
}
}
$OutputAD | Export-Csv "$FolderName\Membership $(get-date -Format yyyy-MMM-dd-HH-mm-ss).csv" -NoTypeInformation
Found the solution. In Select-Object you can add a calculated property.
Example: Select-Object CN,Department,co,Company,#{n='Role';e={$role}}

Export-Csv Cannot bind argument to parameter 'InputObject' because it is null

I am trying to fetch the AD group members information through power shell. But I am getting the messages as
Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
Import-Module ActiveDirectory
$Path = Get-Location
$GroupName = Read-Host "Type the Group Name to check the members in it`t "
foreach ($group in $GroupName) {
$users = #{}
Get-ADUser -Filter '*' -Property Name, DisplayName | ForEach-Object {
$users[$_.DistinguishedName] = $_
}
$MemberCount = (Get-ADGroup $group -Properties Member | Select-Object -Expand Member).Count
Write-Host "`t Total Number of Users/Groups added on this Group : $MemberCount" -BackgroundColor DarkCyan
$Info = Get-ADGroup $group -Properties Member |
Select-Object -Expand Member |
ForEach-Object { $users[$_] }
$Info | Export-Csv -NoTypeInformation -Append -Force $Path\new.csv
The error means that $Info contains empty/null values. The most likely reason for their presence is that the group has members that aren't returned by Get-ADUser.
You can avoid the issue by checking for the presence of the key in the $users hashtable:
$Info = Get-ADGroup $group -Properties Member |
Select-Object -Expand Member |
ForEach-Object { if ($users.ContainsKey($_) {$users[$_]} }
If you want to further investigate the missing distinguished names you could collect them like this:
$missing = Get-ADGroup $group -Properties Member |
Select-Object -Expand Member |
ForEach-Object { if (-not $users.ContainsKey($_) {$_} }

Need to log my results to a seperate file

I have this great powershell script I wrote a while back which copy's the users from one Active Directory Group to Another. I need to log the results of each screen output so I have a log of what the script did should there ever be a problem. I would like to write the output to C:\Temp\CopyLog.txt but I can't figure out how to get it to work correctly. I have tried Add-Content and out-file but they don't seem to like me.
Import-Module activedirectory
$string = Get-Content C:\Temp\GroupsToCopy.txt
foreach($i in $string)
{
$split = $i.split(";")
$Source_Group = $split[0]
$Destination_Group = $split[1]
"***Results before script***"
"Current Member's of: $Source_Group"
Get-ADGroupMember $Source_Group | select name | ft -hide
"`n"
"Current Member's of: $Destination_Group"
$Source = Get-ADGroupMember $Source_Group | select name | ft -hide
$DST = Get-ADGroupMember $Destination_Group
if ($DST -eq $null)
{
"Group has no members"
}
else
{
Get-ADGroupMember $Destination_Group | select name | ft -hide
}
$Target = Get-ADGroupMember $Source_Group
foreach ($Person in $Target)
{
Add-ADGroupMember $Destination_Group -Members $Person.distinguishedname
}
"`n"
"***Results after script***"
"`n"
"Current Member's of: $Source_Group"
Get-ADGroupMember $Source_Group | select name | ft -hide
"`n"
"Current Member's of: $Destination_Group"
Get-ADGroupMember $Destination_Group | select name | ft -hide
"`n"
}
Use Start-Transcript:
Start-Transcript -Path C:\Temp\CopyLog.txt -Append
# Rest of script goes here
Stop-Transcript

Call a Group Object by Name in ForEach Loop

I've imported a CSV file into an array and grouped it by email address. I'd like to be able to call the group by name in another ForEach loop so that I can send an email to each email address with a table of the $ServerID(s) and $DateTime(s) associated with them. Was Group-Object the best way to start this?
In the CSV file, one email address can be associated with many servers, but one server is only associated with one email address. The values in the file will be updated constantly - thus the need for dynamic variables for almost all objects.
$csv = import-csv "C:Example.csv"
$array = #()
ForEach ($server in $csv) {
$object = New-Object PSObject -Property #{"Email"= $server.Email; "ServerID" = $server.ServerID; "DateTime" = $server.DateTime}
$array += $object}
$array | Group-Object Email
Count Name Group
2 A#gmail.com {#{PG_Email=A#gmail.com; ServerID=333; Lease_End=10/10/15}, #{PG_Email=A#gmail.com; ServerID=111; Lease_End=12/12/15}}
1 B#gmail.com {#{PG_Email=B#gmail.com; ServerID=222; Lease_End=09/09/15}}
Yes, you should use Group-Object. I'm not sure what you mean with "call the group by name". If you want to select a group based by the name you would have to save the result from Group-Object and search for your group like:
$groups = $array | Group-Object Email
$selectedmail = "B#gmail.com"
$groups | Where-Object { $_.Name -eq $selectedmail }
Or you could save the groups in a hashtable:
#Create hashtable
$ht = #{}
#Fill hashtable with groups (email as key/ID)
$array | Group-Object Email | ForEach-Object { $ht[$_.Name] = $_.Group }
$selectedmail = "B#gmail.com"
#Get objects for selected mail
$ht[$selectedmail]
If you are going to mail everyone, I would simplify this to:
Import-Csv "C:\Example.csv" |
Group-Object Email |
ForEach-Object {
$to = $_.Name
#Get table of ServerID + Lease_End as string to send as mailbody
$mailbody = $_.Group | Format-Table -Property ServerID, Lease_End -AutoSize | Out-String
#You could also create a HTML-table with:
$htmlbody = $_.Group | Select-Object -Property ServerID, Lease_End | ConvertTo-HTML -Property Name, Length
#Send mail
#Send-MailMessage -To $to -Subject "Lease-status" -Body $mailbody -From "mysupersecret#mail.com"
}

Resources