Create a CSV with all AD users to import into Elastix - csv

I'm working in a test environment with about 1000 users and I'm trying to create a CSV with the following headers to be used in Elastix: Display Name, User Extension, Secret, Tech.
The users currently do not have extensions assigned to them and random extensions would be fine. The secret will be "123456" for all of them. The Tech will be "Sip" for all of them.
Currently I have this, but I'm struggling to strip the name off each user in my loop:
$users = get-aduser -filter * | Select Name
$outpath = "C:\scripts\users.csv"
$outputArray =#()
"Display Name, User Extension, Secret, Tech"|out-file $outpath -Force
$ext = 1000
foreach($row in $users)
{
$outputArray += "," + $ext++ + "," + "123456" + "," + "Sip"
}
$outputArray | out-file $outpath -Force

Use can do this using the Select-Object cmdlet with 'calculated properties' and the Export-Csv cmdlet.
(Note: In my original answer I did not specify the script scope for the randomExtension variable when modified in an expression. When trying to fix, I found the solution here: How can I increase the value of a variable in an expression?
$outputPath = "C:\test\users.csv"
$script:randomExtension = 1000
get-aduser -filter * |
Select #{n='Display Name';e={$_.Name}},
#{n='User Extension';e={$script:randomExtension++; $script:randomExtension}},
#{n='Secret';e={'123456'}},
#{n='Tech';e={'Sip'}} |
Export-Csv -Path $outputPath -NoTypeInformation

Related

Exporting all memberof values using Export-Csv with join

I'm trying to pump out a list of users in a specific OU along with their group memberships to a CSV. I wanted a list of groups but I get "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection" My command is
Get-ADUser -Filter * -SearchBase "ou=Vendor Accounts,dc=mydomain,dc=com" -Properties * | Select ‘Name’,’DisplayName’,’SamAccountName’, #{Name=’MemberOf';Expression={[string]::join(“;”, ($_.MemberOf))}}| export-csv c:\temp\citrix_vendors.csv -NoTypeInformation -Append
I get all the other properties as expected, pretty columns and everything, but can't seem to get the multi-valued attribute to output the way I want. I'm running v4.
I looked at How to list AD group membership for AD users using input list? and tried implementing a similar fix,
$GroupMembership = ($user.memberof | % { (Get-ADGroup $_).Name; }) -join ';';
$user = Get-ADUser -Filter * -SearchBase "ou=Vendor Accounts,dc=mydomain,dc=com" -Properties *
$user.Samaccountname + ',' + $GroupMembership | export-csv c:\scripts\citrix_vendors.csv -NoTypeInformation -Append
but the output Changed from Columns with almost all the info I am grabbing to a single column titled "Length" with a number in each row.

How to deal with automated duplicate user removal

I have the following:
#(Import-Csv C:\Users\Administrator\Desktop\dbs\Monday.csv) +
#(Import-Csv C:\Users\Administrator\Desktop\dbs\Tuesday.csv) +
#(Import-Csv C:\Users\Administrator\Desktop\dbs\Wednesday.csv) +
#(Import-Csv C:\Users\Administrator\Desktop\dbs\Thursday.csv) +
#(Import-Csv C:\Users\Administrator\Desktop\dbs\Friday.csv) |
sort first_name,last_name,phone1 -Unique |
Export-Csv C:\Users\Administrator\Desktop\dbs\joined.csv
Import-Module ActiveDirectory
#EDIT PATH SO IT POINTS TO DB FILE \/
$newUserList = Import-Csv C:\Users\Administrator\Desktop\dbs\joined.csv
ForEach ($item in $newUserList){
$fname = $($item.first_name)
$lname = $($item.last_name)
$phone = $($item.phone1)
$username=$fname+$lname.substring(0,1)
# Puts Domain name into a Placeholder.
$domain='#csilab.local'
# Build the User Principal Name Username with Domain added to it
$UPN=$username+$domain
# Create the Displayname
$Name=$fname+" "+$lname
$newusers1 = (New-ADUser -GivenName $fname -Surname $lname -HomePhone $phone -Name $Name -DisplayName $Name -SamAccountName $username -AccountPassword (ConvertTo-SecureString "1NewPassword" -asplaintext -force) -ChangePasswordAtLogon $true -UserPrincipalName $UPN -Path "ou=test,dc=csi,dc=lab" -Enabled $true -PassThru) |
# I need this block to check for duplicates missed by the csv sort & merge
# as well as any in the destination OU itself as the script will run daily
# with inevitable possibility that user is unique to the csv but not the AD.
$newusers1 | Get-ADUser -Filter * -SearchBase "OU=Active Users,DC=csilab,DC=local" |
Sort-Object -Unique |
Remove-ADUser -confirm:$false
However I run it and get:
Get-ADUser : The input object cannot be bound to any parameters for the command
either because the command does not take pipeline input or the input and its
properties do not match any of the parameters that take pipeline input.
At C:\Users\Administrator\Desktop\Team2.ps1:40 char:14
+ $newusers1 | Get-ADUser -Filter * -SearchBase "OU=Active Users,DC=csilab,DC=loca ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (CN=Bethanie Cut...csilab,dc=local:PSObject) [Get-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.ActiveDirectory.Management.Commands.GetADUser
I also worry even if it did work that it'd delete the unique users instead of duplicates.
get-AdUser $username | Move-ADObject -TargetPath 'OU=Active Users,dc=csilab,dc=local'
}
What can I do to ensure all users are there without any originals getting deleted, just the duplicates?
You still have an empty pipe at the end of your New-ADUser statement, which would cause your script to fail with an "empty pipe element is not allowed" error, but oh well ...
To avoid collisions just check if an account already exists before you try to create it, and create it only if it doesn't:
$username = $fname + $lname.substring(0,1)
...
if (Get-ADUser -Filter "SamAccountName -eq '$username'") {
Write-Host "Account $username already exists."
} else {
New-ADUser -SamAccountName $username -Name $Name ... -PassThru
}
Also, you're overcomplicating the CSV handling. Simply process a list of the files via ForEach-Object:
$domain = '#csilab.local'
Set-Location 'C:\Users\Administrator\Desktop\dbs'
'Monday.csv', 'Tuesday.csv', 'Wednesday.csv', 'Thursday.csv', 'Friday.csv' |
ForEach-Object { Import-Csv $_ } |
Sort-Object first_name, last_name, phone1 -Unique |
ForEach-Object {
$fname = $_.first_name
$lname = $_.last_name
$phone = $_.phone1
...
}
You might want to use Try/Catch:
Try {$newusers1=(New-ADUser–GivenName$fname–Surname$lname-HomePhone$phone–Name$Name-DisplayName $Name –SamAccountName$username–AccountPassword(ConvertTo-SecureString"1NewPassword"-asplaintext-force) -ChangePasswordAtLogon$true–UserPrincipalName$UPN–Path"dc=csi,dc=lab"-Enabled$true)}
Catch {
If ($_.Exception.Message -match "account already exists")
{
#do whatever here, eg $NewUsers1 = Get-ADUser $Name
}
}
Also, if you can't see the user when browsing via ADUC it could be that you are connected to a different DC.
As mentioned above, the newuser1 variable will be null if the command failed. It will not load with the other user automatically, and it would be scary bad if it did. You need to decide what to do if the account already exist, that may simply be loading the variable with the other account, or doing something like appending a "1" to $name and retrying the command.

Get AD distinguished name

I'm trying to take input from a CSV file, which has a list of group names (canonical names) and get the Distinguished Name from it, then output to another CSV file. The code:
#get input file if passed
Param($InputFile)
#Set global variable to null
$WasError = $null
#Prompt for file name if not already provided
If ($InputFile -eq $NULL) {
$InputFile = Read-Host "Enter the name of the input CSV file (file must have header of 'Group')"
}
#Import Active Directory module
Import-Module -Name ActiveDirectory -ErrorAction SilentlyContinue
$DistinguishedNames = Import-Csv -Path $InputFile -Header Group | foreach-Object {
$GN = $_.Group
$DN = Get-ADGroup -Identity $GN | Select DistinguishedName
}
$FileName = "RESULT_Get-DistinguishedNames" + ".csv"
#Export list to CSV
$DNarray | Export-Csv -Path $FileName -NoTypeInformation
I've tried multiple solutions, and none have seemed to work. Currently, it throws an error because
Cannot validate argument on parameter 'Identity'. The argument is null. Supply a non-null argument and try the command again.
I tried using -Filter also, and in a previous attempt I used this code:
Param($InputFile)
#Set global variable to null
$WasError = $null
#Prompt for file name if not already provided
If ($InputFile -eq $NULL) {
$InputFile = Read-Host "Enter the name of the input CSV file(file must have header of 'GroupName')"
}
#Import Active Directory module
Import-Module -Name ActiveDirectory -ErrorAction SilentlyContinue
$DistinguishedNames = Import-Csv -Path $InputFile | foreach {
$strFilter = "*"
$Root = [ADSI]"GC://$($objDomain.Name)"
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher($root)
$objSearcher.Filter = $strFilter
$objSearcher.PageSize = 1000
$objsearcher.PropertiesToLoad.Add("distinguishedname") | Out-Null
$objcolresults = $objsearcher.FindAll()
$objitem = $objcolresults.Properties
[string]$objDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
[string]$DN = $objitem.distinguishedname
[string]$GN = $objitem.groupname
#Get group info and add mgr ID and Display Name
$props = #{'Group Name'= $GN;'Domain' = $objDomain;'Distinguished Name' = $DN;}
$DNS = New-Object psobject -Property $props
}
$FileName = "RESULT_Get-DistinguishedNames" + ".csv"
#Export list to CSV
$DistinguishedNames | Sort Name | Export-Csv $FileName -NoTypeInformation
The filter isn't the same one I was using here, I can't find the one I was using, the I currently have is a broken attempt.
Anyway, the main issue I was having is that it will get the group name, but search for it in the wrong domain (it wouldn't include Organizational Units) which caused none of them to be found. When I search for a group in PowerShell though (using Get-ADGroup ADMIN) they show up with the correct DN and everything. Any hints or code samples are appreciated.
You seemingly miss the point of $variable = cmdlet|foreach {script-block} assignment. The objects to assign to $variable should be returned (passed through the script block) in order to end up in $variable. Both your main loops contain the structure of the line $somevar=expectedOutput where expectedOutput is either a New-Object psobject or Get-ADGroup call. The assignment to $someVar suppresses the output, so that the script block does not have anything to return, and $variable remains null. To fix, do not prepend the call that should return an object into outside variable with an assignment.
$DistinguishedNames = Import-Csv -Path $InputFile -Header Group | foreach-Object {
$GN = $_.Group
Get-ADGroup -Identity $GN | Select DistinguishedName # drop '$DN=`
}
$DistinguishedNames | Export-CSV -Path $FileName -NoTypeInformation
The same issue with the second script.

PowerShell Import CSV to add Active Directory Security Groups

I have a CSV from a client with a few columns in it. A column for Email, SamAccountName, SecurityGroups.
In the Security Group column, each Security Group is separated by a ','
Each row would look like below
User1 User1#email.com SecurityGroup1, SecurityGroup2, SecurityGroup3
User2 User2#email.com SecurityGroup1, SecurityGroup2, SecurityGroup3
User3 User3#email.com SecurityGroup13, SecurityGroup5, SecurityGroup6
A list of users in different Security groups, how do I go about reading the CSV and only adding the Security Groups each user needs.
Below is what I have so far, when I run it in WhatIf mode it adds all the security groups to one user.
Clear
$ADGroup = $null
$i = 0
$ADGroup = import-csv 'File.csv'
$sADGroup = $ADGroup.'Groups required'
Import-CSV "TestUsers.csv" | % {
$SAM = $_.SamAccountName
$ADUser = Get-Aduser -filter {SamAccountName -eq $SAM} -Properties * | Select SamAccountName, MemberOf
Write-Host 'SamAccountName :' $_.SamAccountName ' - ADUser - ' $SAM
$sADGroup | ForEach-Object{
Write-HOst $ADGroup.ADgroup[$i]
Add-ADGroupMember $sADGroup.split(",")[$i] -Members $ADUser.SamAccountName -WhatIf
$i += 1
}
}
Here is the final script, using AD-ADPrincipalGroupMembership was the find, instead of using Add-ADGroupMember
Import-Csv 'testusers.csv' |
ForEach-Object {
add-content $LogFile "Adding User to Group - $($_.Name)"
Try{
Add-ADPrincipalGroupMembership -identity $_.'SamAccountName' -memberof ($_.'Groups' -split', ')
}
Catch {
Add-content $LogFile "Error adding user to group - $($_.Name)"
}
}

How to update AD Info attribute to list groups user was deleted from?

I have this script that will only list a user's groups on the ISE screen where the data can be copied and pasted elsewhere, but I'm trying to get the group membership names written into the Telephone Notes tab (or Info field). I'm thinking next that these probably need to be turned into string values since I'm getting errors about multi properties not allowed. Here is what I've been trying, but I keep getting errors. Thanks
Import-Module ActiveDirectory
$Users= Import-csv "C:\Scripts\UsersSAM-DisplayName.csv"
ForEach ($User in $Users) {
$SamAccountName=$User.SamAccountName
$DisplayName=$User.DisplayName
$TableFormat= #{E={$_.Name};L="$($DisplayName) - $($SamAccountName)"}
Get-ADUser -Identity $SamAccountName -Properties MemberOf | % {$_.MemberOf } | % {Get-ADGroup -Identity $_ } | % { Set-ADUser -Identity $SamAccountName -add #{info="$_.name"}} | Select Name |
Format-Table $TableFormat }
I figured this out. What they wanted was to first write out a terminated user's groups, then remove those. I did it like this and this code includes the semi-colon so if the user comes back, all you need to do to add them back to all the groups is copy and paste those from the output stored in the Telephones Tab, Notes field. I've also used a trimmed down version of this to export a user's groups to speed up duplicating a user's groups so they match with others on the same team. Hope this helps someone.
Import-csv "$Terms" | % {
$user = Get-ADUser -LDAPFilter ("(sAMAccountName=" + $_.samaccountname + ")") -Properties samaccountname,enabled,name,memberof,distinguishedname,info
#Grab all user group names
$user | ForEach-Object {
$grps = $_.MemberOf | Get-ADGroup | ForEach-Object {$_.Name} | Sort-Object
$arec = $_.Name,$_.SamAccountName
$aline = ($grps -join ";")
#Add info to Notes field Telephone Tab
Get-ADPrincipalGroupMembership -Identity $user | %{
If ($_.SamAccountName -ne "Domain Users") {
$Userinfo=$user.info
Set-ADUser $User -replace #{info= "$Userinfo | $a | Terminated via automated process | $aline"}
#Remove User Groups Process in Telephones Tab Notes Field.
Remove-ADPrincipalGroupMembership -Identity $user -MemberOf $_.SamAccountName -Confirm:$false
(" "+ $a +" [" + $User.samaccountname + "], Removed from group [" + $_.samaccountname + "]. ") | Out-File -FilePath $ErrorLog -Append
}
}}}