AD query Powershell and Export to txt file - powershell

Can someone help me?
I have to create a .txt file with the following format:
user("SamAccountName","GivenName Surname"){}
I'm able to create just this:
#Get AD Users Info
cls
$SamAccountName = New-Item 'c:\SamAccountName.txt' -type file -Force
Get-ADUser -Filter * -Properties SamAccountName |
select -First 15 | Sort-Object SamAccountName |
Format-Table SamAccountName | Out-File $SamAccountName
$content = Get-Content $SamAccountName
$content | Foreach {$_.TrimEnd() } | where {$_ -ne ""} | Select-Object -Skip 3 | Set-Content $SamAccountName
#Write quotes (make it nice and readable!)
$ACTIVEDIRECTORY = New-Item 'c:\ACTIVEDIRECTORY.lst' -type file -Force
Clear-Content $ACTIVEDIRECTORY
$quotes= '"'
(Get-Content $SamAccountName) |
ForEach-Object {Add-Content $ACTIVEDIRECTORY "$quotes$_$quotes"}
Get-Content $ACTIVEDIRECTORY
This give me this result:
"GivenName"
"GivenName"
"GivenName"

I agree with #notjustme about your question being a mess, but I'll throw an answer out there anyway.
Your first problem is how you set these two variables. They end up being objects, but you're trying to use them like file paths.
$SamAccountName = "c:\SamAccountName.txt"
$ACTIVEDIRECTORY = "c:\ACTIVEDIRECTORY.lst"
This will get you a comma separated list of your users, which is (sort of) what part of your code is doing.
Get-ADUser -Filter * | Select-Object SamAccountName, GivenName, SurName -First 15 | Sort-Object SamAccountName | Export-Csv $SamAccountName -NoTypeInformation
This will get you the list of users with the string format you specified at the top, which is odd, but whatever.
Import-Csv $SamAccountName | ForEach-Object {"user(`"$($_.SamAccountName)`",`"$($_.GivenName) $($_.Surname)`"){}"} | Out-File $ACTIVEDIRECTORY

Can't try it out myself at the moment but... from experience...
-properties * | select SamAccountName, GivenName, Surname
Should get ya in the ballpark.
Re-read your code a few times and well... it seems a mess to be honest. You state what you wanna accomplish and then there's a crud-load of other stuff that make close to no sense in this case. Maybe I'm just too tired, I'll check back in the morning and edit/delete if needed.
Allright, re-read a few more times and the headache is given but still...
In general I'd like to advise you (or anyone, really) if Powershell get's confuzzling to break it down in easily processable pieces.
For the users;
$users = Get-ADUser -Filter { Name -like '*' } -Properties * | select SamAccountName, Givenname, Surname
For the output;
foreach ($user in $users)
{
'("{0}""{1}{2}"' -f $user.SamAccountName, $user.GivenName, $user.Surname
}
Unfortunatly I have no way to try this out myself at the moment but it should be in the ballpark... if you end up getting some errors, lemme know and I'm sure I can guide ya through it. I'm not 100% sure about them single and doublequotes in this particular case... I'd have to try it out.

Related

Get entries of a file from a filtered list

I am trying to grab the host file entries of servers in mulptiple OUs here to show the host file entries and server names
$OUpath =
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
$ExportPath = 'c:\servers.csv'
$OUpath | Foreach {
Get-ADComputer -Filter * -SearchBase $OUpath} | Select-object DistinguishedName,DNSHostName,Name,Description | Export-Csv -NoType $ExportPath
Part A up ran fine...How can i get the entries of the results. I am tending towards content but hope to have it all in one script. Any help would be nice.
An alternative to #FoxDeploy's helpful answer, here is how you can do the same using the pipelines with ForEach-Object.
Note that Description is not a default property for Get-ADComputer you will need to add -Properties Description to see it's value.
Another point to consider, by default, if you don't specify the -SearchScope, Get-ADComputer will perform a SubTree search, meaning that it will bring all computers of the specified OU and all computers on all the OUs contained in the Base OU. If you just want to bring the computers in the OU without going down in recursion, you should add -SearchScope OneLevel.
#(
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
) | ForEach-Object {
Get-ADComputer -Filter * -SearchBase $_ -Properties Description
} | Select-Object DistinguishedName,DNSHostName,Name,Description |
Export-Csv 'c:\servers.csv' -NoTypeInformation
I think the primary issues were the array getting declared incorrectly, and incorrect syntax for the ForEach-Object cmdlet
$OUpath = #(
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
)
$ExportPath = 'c:\servers.csv'
$OUpath |
ForEach-Object {
Get-ADComputer -Filter * -SearchBase $_ -Properties Description
} |
Select-Object DistinguishedName, DNSHostName, Name, Description |
Export-Csv $ExportPath -NoTypeInformation
You have to use $_ in this context where you were using $OUpath previously. Select-Object can take the the piped output from the ForEach-Object loop rather than being in the loop, which should be more efficient. Likewise for Export-Csv.
As implied by FoxDeply's very good answer that might signal an attempt to use A ForEach(...) loop construct instead of ForEach-Object. But if we are going that route I think it's slightly better to let PowerShell populate the array for us.
$OUpath = #(
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
)
$Servers =
ForEach( $Path in $OUpath )
{
Get-ADComputer -Filter * -SearchBase $path -Properties Description |
Select-Object DistinguishedName, DNSHostName, Name, Description
}
$Servers | Export-Csv $ExportPath -NoTypeInformation
Alternatively you could skip the Select-Object inside the loop and add $Servers = $Servers | Select-Object ... right after the loop. Although the difference is probably negligible.
With some minor restructuring, this should get you past your issue
$OUpath = (
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local',
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local',
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local')
$ExportPath = 'c:\servers.csv'
$servers = new-object System.Collections.ArrayList
ForEach($path in $OUpath){
$ouServers = Get-ADComputer -Filter * -SearchBase $path | Select-object DistinguishedName,DNSHostName,Name,Description
$servers.AddRange($ouServers) | Out-Null
}
"found $($servers.Count) servers!"
$servers | export-csv $exportPath
I made the list of OU Paths a PowerShell array, then iterate through them using the standalone ForEach loop. Then commit the items to a variable that will persist ($servers) and output the CSV.

Using powershell to change attribute

First:
I am complete new to Powershell-Scripting.
Want to change the attribute "preferredLanguage" from some Users via powershell.
The users are written in txt-file
testUser000
testUser001 and so on
My first try was to become a list with users and some attributes:
$users = ForEach ($user in $(Get-Content C:\Temp\users.txt)) {
Get-AdUser $user -Properties Department, Mail, preferredLanguage
}
$users |
Select-Object SamAccountName,Department,Mail, preferredLanguage |
Export-CSV -Path C:\temp\outputUsers.csv -NoTypeInformation
That worked so far:
"SamAccountName","Department","Mail","preferredLanguage"
"tesUser000","dept1","testUser000#domain.com","DE"
"testUser0001","dept2","testUser001#domain.com",
testUser000 has an entry in preferredLanguage
testUser0001 has no entry
That's ok. When I have completed the users.txt, there are more than 100 users without an entry in 'preferredLanguage'
Now I want to change the preferredLanguage and with some investigation in the Internet I made this:
$users = ForEach ($user in $(Get-Content C:\Temp\users.txt)) {
Get-AdUser $user -Properties Department, Mail, preferredLanguage
}
$users |
Set-AdUser $users -Replace #preferredLanguage="DE" |
Select-Object SamAccountName,Department,Mail, preferredLanguage |
Export-CSV -Path C:\temp\outputUsers.csv -NoTypeInformation
When I understand this script right, then it get from my txt-File every user in it with the given attributes then it changes the attribute 'preferredLanguage' from the users in the txt-file and then it select it again then it will save the output in a csv-file.
Maybe someone can look over the script and would be so kind and give me feedback about it or a better way, because Iam too scary to use this script on the AD-Server.
Just a few things:
Get-AdUser $user means you must be sure the user with that identity exists or an exception will be thrown
the syntax for the -Replace operator should be #{preferredLanguage="DE"}
Set-ADUser does not generate any output unless the -PassThru parameter is used.
if you use ForEach-Object, you can do all this in one loop
Try changing the code with this:
(Get-Content C:\Temp\users.txt) | ForEach-Object {
$account = Get-AdUser -Filter "SamAccountName -eq '$_'" -Properties Department, Mail, preferredLanguage -ErrorAction SilentlyContinue
if ($account) {
$account | Set-AdUser -Replace #{preferredLanguage="DE"} -PassThru |
Select-Object SamAccountName,Department,Mail, preferredLanguage
}
else {
Write-Warning "User '$_' does not exist"
}
} | Export-CSV -Path C:\temp\outputUsers.csv -NoTypeInformation
Hope that helps

Active Directory Powershell to fixed width txt file

Trying to export 4 objects from Ad to a fixed-width txt file with no header.
I need the following columns to be the width that follows.
Employee ID 10
Work Phone 10
Work Phone Extension 5
Work Email Address 50
User ID 20
The following gives me the best output, but doesn't size the columns the way I need. I have been digging around, and think what I need is a bit beyond what I'm comfortable with.
I'm not sure if i need to export with export-csv and then import that into reformat or if I can do out-file directly.
$DateTime = Get-Date -f "yyyyMMdd"
#// Set CSV file name
$CSVFile = "d:\scripts\workday\int002_"+$DateTime+".txt"
Get-ADGroup -Filter {(name -like "*Group Name*")} `
| Get-ADGroupMember -Recursive | Where { $_.objectClass -eq "user" } `
| Get-ADUser -properties * | where {$_.enabled -eq $true} `
| select employeeid,telephoneNumber,mail,sAMAccountName -unique | FT employeeid,telephoneNumber,mail,sAMAccountName -hidetableheaders -autosize | out-file $CSVFile
Sample Output:
8855 2122445710 xxxry.michalsen#companydomain.com michalsenm
You might need to do it manually...
$result = foreach($user in $users) {
$user.employeeid.PadRight(10),
$user.telephoneNumber.PadRight(10),
$user.mail.PadRight(50),
$user.sAMAccountName.PadRight(20) -join ' '
}
$result | Out-File $CSVFile
A revised version that also works if the property is not a string:
$result = foreach($user in $users) {
'{0,-10}{1,-10}{2,-50}{3,-20}' -f
$user.employeeid,
$user.telephoneNumber,
$user.mail,
$user.sAMAccountName
}
$result | Out-File $CSVFile

get displayname and office from samaccountname export to csv

How I can get the displayname and the office from a samaccountname list (.txt)? After that I want to save the displaynames and the offices to a .csv file. Here is a approach:
$users = Get-Content C:\TMP\test.txt
foreach ($user in $users)
{
Get-ADUser -ldapfilter "(samaccountname=$user)" -Property name, office | Select-Object -Property Name, Office
}
It should look like:
Hope you can help me?
You are asking for the Export-CSV command but from your comments you might be having issues with placement or your construct of foreach.
Lets try this then
$users = Get-Content C:\TMP\test.txt
$users | ForEach-Object {
Get-ADUser -ldapfilter "(samaccountname=$_)" -Property name,office | Select-Object -Property Name,office
} | Export-Csv -Path C:\temp\export.csv -NoTypeInformation
Update from comments
Was having issues understanding your output from the comments which was why I wanted more that just a picture of the headers. I don't an issue with this code and the text should be quoted so special characters, like commas, should not be an issue. Please update you question with the text content of a sample file and your PowerShell version in case that is coming into play.
Use the delimiter parameter at the end
$users = Get-Content C:\TMP\test.txt
$users | ForEach-Object {
Get-ADUser -ldapfilter "(samaccountname=$_)" -Property name,office | Select-Object -Property Name,office
} | Export-Csv -Path C:\temp\export.csv -NoTypeInformation -Delimiter ";"

Getting Active Directory Domain Services Folder and/or DistingiushedName

I'm new to scripting with Powershell for Active Directory, and attempting to pull out users in a list and enumerating their groups; however when I do so the resultant information contains just the name of the group which is duplicated under many differently named OUs. Looking at them in AD Users and Computers under the Member Of tab shows the Name and the Active Directory Domain Services Folder which contains exactly the differentiating info I need, or alternately I could use the DistinguishedName which isn't as nicely formatted for readability but would also work.
Problem with simplified examples: If a group name is the same across different OUs (like "TestUsers") then the script currently dumps multiple group names without differentiation "TestUsers, TestUsers, TestUsers" instead of showing the underlying OUs in a clean format "Michigan\TestUsers, NewYork\TestUsers" or Distinguished Name format "CN=TestUsers,CN=Michigan,etc";"CN=TestUsers,CN=NewYork,etc".
$alist = "Name`tAccountName`tDescription`twhenCreated`tAcctEnabled`tGroups`n"
$userlist = Get-ADUser -SearchBase "OU=Service Accounts,OU=Information Systems,DC=conteso,DC=local" -Filter * -Properties * | Select-Object -Property Name,SamAccountName,Description,EmailAddress,LastLogonDate,Manager,Title,Department,Company,whenCreated,Enabled,MemberOf | Sort-Object -Property Name
$userlist | ForEach-Object {
$grps = $_.MemberOf | Get-ADGroup | ForEach-Object {$_.Name} | Sort-Object
$arec = $_.Name,$_.SamAccountName,$_.Description,$_.whenCreated,$_.Enabled
$aline = ($arec -join "`t") + "`t" + ($grps -join "`t") + "`n"
$alist += $aline
}
$alist | Out-File C:\psscripts\service_accounts_groups.csv
Any help is appreciated!
I agree that DistinguishedName already has this information but I think it is easier to just use Get-AdGroup to get some friendlier information. A little string manipulation on the CanonicalName of the group, while not as efficient maybe, would be easier to work with.
$grps = $_.MemberOf | Get-AdGroup -Properties CanonicalName | ForEach-Object{
$CN = ($_.CanonicalName -Split "/")
"{0}\{1}" -f $CN[-2],$CN[-1]
}
or as a one liner if you prefer.
$grps = $_.MemberOf | Get-AdGroup -Properties CanonicalName | ForEach-Object{$CN = ($_.CanonicalName -Split "/"); "{0}\{1}" -f $CN[-2],$CN[-1]}
What we do is take the CanonicalName which can be considered the path of the object in Active Directory. Since you only wanted the parent container we split up the path and join only the last two parts. The group object and its container.
Same result could come from just getting the second last element from CanonicalName and appending the group name to it. Might look at little nicer
$grps = $_.MemberOf | Get-AdGroup -Properties CanonicalName | ForEach-Object{"{0}\{1}" -f ($_.CanonicalName -Split "/")[-2],$_.Name}
Since the "$_.memberof" property already has the Distinguished name, you don't need to pass it to Get-Adgroup again. so simply replace your $grps line like this
$grps = $_.MemberOf -replace "CN=","" -replace "OU=","" -replace "DC=","" -replace ",","\" | Sort-Object
Or if you still want to proceed with your approach, use it with distinguishedname property instead of name property - like this (with the text replace)
$grps = $_.MemberOf | Get-ADGroup | ForEach-Object {$_.DistinguishedName -replace "CN=","" -replace "OU=","" -replace "DC=","" -replace ",","\"} | Sort-Object
Or as suggested by Matt in the comment, simply use canonicalname property.
$grps = $_.MemberOf | Get-ADGroup -Properties canonicalname | select -ExpandProperty canonicalname
Cheers, GJ