I have been tasked with creating a bunch of security groups for Active Directory on a 2016 Windows Server. At the moment I have this code
$CSVLocation = Read-Host -Prompt "Please enter the path of CSV file"
$Groups = Import-CSV $CSVLocation
foreach ($Group in $Groups) {
$Groupname = Get-ADGroup -Identity $Group.Group
if ($Groupname -eq $null) {
New-ADGroup -Name $Group.Group -Path $group.GroupLocation -GroupScope $Group.GroupType
}
else {
echo "Group existes"
}
}
This is code is trying to create a group if that group doesn't exist and if it does then skip the entry in the CSV. As of this moment, all it does it pump out Get-ADGroup errors about how it can't find the group and then skips the creation of it.
The CSV format is like such:
Group,GroupType,GroupLocation
Group01,Universal,"OU=Test,DC=Example,DC=Local"
Group02,Universal,"OU=Test,DC=Example,DC=Local"
Group03,Universal,"OU=Test,DC=Example,DC=Local"
Error Message:
Get-ADGroup : Cannot find an object with identity: 'AU-CTX-RDP' under: 'DC=Example,DC=local'.
At C:\Users\Administrator\Desktop\Scripts\Import Groups.ps1:10 char:14
+ $Groupname = Get-ADGroup -Identity $Group.Group
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (AU-CTX-RDP:ADGroup) [Get-ADGroup], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADGroup
If you query for a not existing group you get a terminatig error. So the script execution would stop. To avoid this you can use -ErrorAction SilentlyContinue. This way it should work actually
$CSVLocation = Read-Host -Prompt "Please enter the path of CSV file"
$Groups = Import-CSV $CSVLocation
foreach ($Group in $Groups) {
if (-not (Get-ADGroup -Filter "Name -eq '$($group.Group)'" -ErrorAction SilentlyContinue)) {
New-ADGroup -Name $Group.Group -Path $group.GroupLocation -GroupScope $Group.GroupType
}
else {
"Group '$($Group.Group)' already exists"
}
}
Run this script to create bulk users in Powershell, Task will be completed within 30 seconds
New-ADGroup "-Name -GroupScope -GroupSecurity -GroupName" -Path “OU=OUWhereIStoreMyGroups" -Description
Related
Need help to catch the error. Whenever my network connection is unstable my get-ad script will be terminated.
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$Date = Get-Date -Format yyyy_MM_dd_THHmm
Start-Transcript -Path "$ScriptDir\Logs.log" -Append
$List = Import-Csv "$ScriptDir\Accounts.csv"
$TotalCount = $List.Length
$CurrentCount = 0
Write-Host 'Total Count: '$TotalCount
ForEach ($user in $List) {
# Retrieve UserSamAccountName and ADGroup
$Groups = $User.Group
$UserSam = $User.SamAccountName
# Retrieve SamAccountName and ADGroup
$ADUser = Get-ADUser -Filter "SamAccountName -eq '$UserSam'" | Select-Object SamAccountName
$ADGroups = Get-ADGroup -Filter * | Select-Object Name
# User does not exist in AD
if ($ADUser -eq $null) {
Write-Host "$UserSam does not exist in AD" -ForegroundColor DarkCyan
Continue
}
# User does not have a group specified in CSV file
if ($Groups -eq $null) {
Write-Host "$UserSam has no group specified in CSV file" -ForegroundColor Yellow
Continue
}
# Retrieve AD user group membership
$ExistingGroups = Get-ADPrincipalGroupMembership $UserSam | Select-Object Name
foreach ($Group in $Groups.Split(';')) {
# Group does not exist in AD
if ($ADGroups.Name -notcontains $Group) {
Write-Host "$Group group does not exist in AD" -ForegroundColor Gray
Continue
}
# User already member of group
if ($ExistingGroups.Name -eq $Group) {
Write-Host "$UserSam already exists in group $Group." -ForeGroundColor Yellow
}
else {
# User not a member of group
Write-Host "User $UserSam doesn't exists in $Group AD group" -ForegroundColor Red
}
}
$CurrentCount++
$Percentage = [math]::Round($CurrentCount/$TotalCount*100)
Write-Progress -Activity "Building report in progress" -Status "$Percentage% Complete" -PercentComplete $Percentage
}
Stop-Transcript
Write-Output 'Script complete.'
OUTPUT ERROR
Get-ADUser : Unable to find a default server with Active Directory Web Services running.
At C:\Users\JVERE05\Desktop\Powershell\Powershell\CheckIfExist\08_08.ps1:22 char:11
+ $ADUser = Get-ADUser -Filter "SamAccountName -eq '$UserSam'" | Select ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [Get-ADUser], ADServerDownException
+ FullyQualifiedErrorId : ActiveDirectoryServer:1355,Microsoft.ActiveDirectory.Management.Commands.GetADUser
The fully qualified type name is Microsoft.ActiveDirectory.Management.ADServerDownException:
try {
Get-ADUser ... -ErrorAction Stop
}
catch [Microsoft.ActiveDirectory.Management.ADServerDownException] {
<# AD Server is down #>
}
catch {
<# Something else went wrong #>
}
I am trying to add a dialog box into my Import-Csv script in Powershell v7. Basically, I do not want to remember different names of .csv files that have been exported from another script, so this will make it a lot easier. I have looked around and could not find anything that relates to what I am getting.
The code I have is this:
Write-Host "This will bulk add users to an AD group." -ForegroundColor Yellow
" "
# Import the data from CSV file and assign it to variable
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFIleDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.InitialDirectory = $InitialDirectory
$OpenFileDialog.Filter = "CSV (*.csv) | *.csv"
$OpenFileDialog.ShowDialog() | Out-Null
$Path = $OpenFileDialog.Filename
$Users = Import-Csv -Path $Path
# Specify target group where the users will be added to
# You can add the distinguishedName of the group. For example: CN=Pilot,OU=Groups,OU=Company,DC=exoip,DC=local
$Group = Read-Host "Enter in the target group name"
# Start transcript
Start-Transcript -Path "C:\Output Log\Users Logs\Add-ADUsers.log" -Append -UseMinimalHeader
foreach ($User in $Users) {
# Retrieve UPN
$UPN = $User.UserPrincipalName
# Retrieve UPN related SamAccountName
$ADUser = Get-ADUser -Filter "UserPrincipalName -eq '$UPN'" | Select-Object SamAccountName
# User from CSV not in AD
if ($null -eq $ADUser) {
Write-Host "$UPN does not exist in AD" -ForegroundColor Red
}
else {
# Retrieve AD user group membership
$ExistingGroups = Get-ADPrincipalGroupMembership $ADUser.SamAccountName | Select-Object Name
# User already member of group
if ($ExistingGroups.Name -eq $Group) {
Write-Host "$UPN already exists in $Group" -ForeGroundColor Yellow
}
else {
# Add user to group
Add-ADGroupMember -Identity $Group -Members $ADUser.SamAccountName
Write-Host "Added $UPN to $Group" -ForeGroundColor Green
}
}
}
Stop-Transcript
" "
Remove-Variable -Name Users
Write-Host "Users have finished adding to $group" -ForegroundColor Yellow
" "
}
The results of the output is this:
The search filter cannot be recognized
+ CategoryInfo : NotSpecified: (:) [Get-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser
+ PSComputerName : localhost
does not exist in AD
Note: "does not exist in AD" has a blank in front of it. I suspect it is because the import is not reading the file, but I cannot make sense of how to fix it.
Any help will be much appreciated!
Thank you in advanced.
Import-CSV "C:\Temp\jacktest.csv" | Foreach-Object {
$aduser = Get-ADUser -Filter "UPN-eq '$($_.UPN)'"
if( $aduser ) {
Write-Output "Adding user $($aduser.SamAccountName) to groupname"
Add-ADGroupMember -Identity JackTest -Members $aduser
} else {
Write-Warning "Could not find user in AD with email address $($_.EmailAddress)"
}
}
I receive the following Error:
Transcript started, output file is C:\Temp\Add-ADUsers.log
Get-ADUser : The search filter cannot be recognized
At line:19 char:15
$ADUser = Get-ADUser -Filter "UPN -eq '$UPN'" | Select-Object Sam ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [Get-ADUser], ADException
FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser
This answer is meant to help you troubleshoot your issue so we can understand what could be going wrong with your CSV.
Note, this code assumes that your CSV is comma delimited and the CSV has a column with name "UserPrincipalName".
$usersToAdd = foreach($line in Import-CSV "C:\Temp\jacktest.csv")
{
if([string]::IsNullOrWhiteSpace($line.UserPrincipalName))
{
Write-Warning 'Empty UserPrincialName Value:'
Write-Warning $line
continue
}
$aduser = Get-ADUser -Filter "UserPrincipalName -eq '$($line.UserPrincipalName)'"
if(-not $aduser)
{
Write-Warning "$($line.UserPrincipalName) could not be found."
continue
}
$aduser
}
if($usersToAdd)
{
Write-Host 'The following users will be added to the Group'
$usersToAdd.UserPrincialName
try
{
Add-ADGroupMember -Identity JackTest -Members $usersToAdd
}
catch
{
Write-Warning $_.Exception.Message
}
}
check the csv file, it seems you are not using the default delimiter.
if so add parameter -delimiter to the import-csv cmdlet.
for example for Tab delimiter:
Import-CSV "C:\Temp\jacktest.csv" -delimiter "`t"
I have a .csv file that I am using to modify custom attributes on users in Active Directory, but PowerShell does not like the script:
Import-Csv -path c:\users\user\desktop\doc.csv | ForEach-Object {
Set-ADUser $_.mail -replace #{
ExtensionAttribute1 = $_.ExtensionAttribute1
}
}
I get the following error:
Set-ADUser : replace
At line:2 char:4
Set-ADUser $_.mail -replace #{
CategoryInfo: InvalidOperation: (user123:ADUser) [Set-ADUser], ADInvalidOperationException
FullyQualifiedErrorId: ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.SetADUser
The CSV only has 2 columns:
extensionAttribute1,mail
Any help would be appreciated
The -Identity parameter for Set-ADUser does not take an email address.
It needs either the DistinguishedName, objectGUID, SID or SamAccountName. You can also pipe a user object directly to the cmdlet.
Because of that, you need to first try to find the user with Get-ADUser and if that succeeds set the attribute.
Import-Csv -Path 'c:\users\user\desktop\doc.csv' | ForEach-Object {
$user = Get-ADUser -Filter "EmailAddress -eq '$($_.mail)'" -ErrorAction SilentlyContinue
if ($user) {
$user | Set-ADUser -Replace #{ extensionAttribute1 = $_.extensionAttribute1 }
}
else {
Write-Warning "No user with email address '$($_.mail)' found.."
}
}
PS. I always use the exact LDAP name inside the Hash for the key name when using -Add, -Replace etc. Case sensitive.
I am trying to add an AD group into user profiles based on an OU
I had a similar script working, so tried to modify it and failed. I am guessing it's the " -Identity $_" it maybe, but I am not good enough to debug.
#Create a new class to hold the info for our CSV entry
Class CSVEntry{
[String]$UserName
[String]$GroupName
[String]$TimeStamp
}
#Creating a list to hold the CSV entries
$Results = New-Object 'System.Collections.Generic.List[PSObject]'
#Defined the name of the group here
$GroupName = 'GROUPS NAME'
$ou = 'ou=XX,ou=XX,ou=XX,dc=XX,dc=local'
Get-ADUser -Filter * -SearchBase $ou | ForEach-Object{
#Add the user to the group here
Add-ADPrincipalGroupMembership -MemberOf $GroupName Identity $_
#Write-Host $_.Name - $groupName
#Build a custom CSVEntry object and add it to the list
$newRecord = [CSVEntry]::new()
$newRecord.UserName = $_.Name
$newRecord.GroupName = $groupName
$newRecord.TimeStamp = Get-Date
#Add the new record to the list
$Results.Add($newRecord)
}
#Export the list of CSV entries
$Results | Export-Csv C:\PS\AddADGroupToUsers.csv
errors:
Add-ADPrincipalGroupMembership : A positional parameter cannot be found that accepts argument 'CN=NAME,OU=XX,OU=XX,OU=XX,OU=XX,DC=XX,DC=LOCAL'.
At line:18 char:5
+ Add-ADPrincipalGroupMembership -MemberOf $GroupName Identity $_
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Add-ADPrincipalGroupMembership], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.AddADPrincipal
GroupMembership
EDIT:
So, the script doesn't actually do any changes, the group doesn't get added to the users. the output on screen is:
WARNING: User is already a member of group XYZ
WARNING: User is already a member of group XYZ
WARNING: User is already a member of group XYZ
UserName GroupName TimeStamp
-------- --------- ---------
shows ok XYZ 14/10/2019 14:50:23
shows ok XYZ 14/10/2019 14:50:23
shows ok XYZ 14/10/2019 14:50:23
All I have changed is the group name to XYZ and username shows ok in the second half. But, shows blank in the top, and I assure you that a) the user isn't already in the group and b) the script isn't adding them
Current tweaked code, warts and all but sanitised:
$groupName = 'GROUP'
$ou = 'setcorrectly'
$cred = Get-Credential -credential dom\usr
$results = Get-ADUser -Filter * -SearchBase $ou -Credential $cred | ForEach-Object {
#Add the user to the group here
try {
Add-ADGroupMember -Identity $groupName -Members $_.DistinguishedName -Credential $cred -ErrorAction Stop
}
catch {
Write-Warning "User $($_.Name) is already a member of group $groupName"
}
# output a PsCustomObject that gets collected in the $results variable
[PsCustomObject]#{
'UserName' = $_.Name
'GroupName' = $groupName
'TimeStamp' = Get-Date
}
}
# output on console
$results | Format-Table -AutoSize
# Export to CSV file
$results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation
Read-Host -Prompt "Press Enter to exit"
CSV output shows the second half of the screen output only, and doesn't say anything is already a member
Below uses Add-ADGroupMember to add user(s) to 1 group instead of Add-ADPrincipalGroupMembership which is used to add 1 user to multiple groups.
It also uses [PsCustomObject]s to output the results, so you don't need to use the Class CSVEntry.
# Define the name of the group here.
# can be either:
# A distinguished name
# A GUID (objectGUID)
# A security identifier (objectSid)
# A Security Account Manager account name (sAMAccountName)
$groupName = '<NAME OF THE GROUP>'
$ou = 'ou=XX,ou=XX,ou=XX,dc=XX,dc=local'
$results = Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
#Add the user to the group here
$userName = $_.Name
try {
Add-ADGroupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorAction Stop
# output a PsCustomObject that gets collected in the $results variable
[PsCustomObject]#{
'UserName' = $_.Name
'GroupName' = $groupName
'TimeStamp' = Get-Date
}
}
catch {
Write-Warning "User $userName is already a member of group $groupName"
}
}
# output on console
$results | Format-Table -AutoSize
# Export to CSV file
$results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation
Edit
If you want the $results variable to ALSO contain users that are already a member of the group, you could simply move the creation of the [PsCustomObject] below the catch{..} block:
$results = Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
#Add the user to the group here
$userName = $_.Name
try {
Add-ADGroupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorAction Stop
$status = "User added successfully"
}
catch {
Write-Warning "User $userName is already a member of group $groupName"
$status = "User is already a member"
}
# output a PsCustomObject that gets collected in the $results variable
[PsCustomObject]#{
'UserName' = $userName
'GroupName' = $groupName
'TimeStamp' = Get-Date
'Status' = $status
}
}
Hope that helps