I am looking at a way to list how many times an AD property matching a certain value appears against each user.
Specifically - Users in our AD have a Custom Attribute distinguishing their company. I need to run monthly reports that will display a list of all companies and how many users are listed.
This is as close as I have it - but it is not user friendly for our Accounts team.
import-csv c:\HostedCompanyList.csv -header ID |
foreach {
$total = (get-aduser -filter "(extensionattribute1 -eq '$($_.ID)') -and (extensionattribute2 -eq 'billed')" -properties *).count
write-host $total $_.ID
}
This is the content of HostedCompanyList.csv
ID
Company1
Company2
Company3
My output shows as `
35 Company1
12 Company2
27 Company3
I'd like to output this information to a CSV or HTML file as opposed to displaying it on the PS window.
I appreciate this is likely already a very long winded way of running this query - could I perhaps have overlooked a much simpler method?
Bonus points if there's a way I can do this without having to import a CSV file at all - that would cut out the need to add additional entries into that list when new "companies" get added on or taken away!
Thank you for any help offered.
Untested, since I don't have the same extension attributes, but this shape:
query everyone, filter the billed people
group-object by company name
select properties and export to csv
should work with one query, no text file to read from, and csv export.
$filter = "extensionattribute2 -eq 'billed'"
$users = Get-ADUser -filter $filter -Property extensionattribute1, extensionattribute2
$groups = $users | Group -Property extensionattribute1
$groups | select Count, Name | Export-Csv out.csv -notypeinformation
If I have two rows in a CSV file like below (but 200 entries or so).
$Username $Phone
Example.A 911
Example.B 123
How would I get PowerShell to take each row and enter it into a command?
I know how to do it if the phonenumber (Using a for each loop) is the same for everyone, but if everyone has a different phonenumber, how would I go about it then? Can I use a for each loop fetching two rows instead of 1 row from the csv file?
Foreach $Username, $Phonenumber in $CSV
Set-ADuser -identity $Username -PhoneNumber $Phonenumber
Above is how I would like it to be, but that doesn't work.
To do what you're attempting, you just need a couple of slight modifications as follows:
$CSV = Import-Csv -Delimiter "," -Path "\\your\file\path"
foreach ($user in $CSV) {
Set-ADuser -identity $user.Username -PhoneNumber $user.Phonenumber
}
I have a csv file that is auto generated from an external source (NetSuite)
I am hoping to use data from the csv file to update Active Directory user accounts to add or update the "Manager"
NetSuite gives me a csv file that has Email and Manager as 2 column headers.
Email - contains the employees email address and Manager contains Manager Name in a Last, First format.
I would like to convert both of these column into data that can be used in
Set-AdUser -Identity user.name -manager first.last
Objective 1 would be to remove the #domain from the email address column
Objective 2 would be to reorder Last, First into first.last
Import-Csv c:\test.csv
Email | Supervisor
user.1#test.com | "Number1, Manager"
user.2#test.com | "Number2, Manager"
I'd like to be able to export this to a csv file that looks like this
Email | Supervisor
user.1 | Manager.Number1
user.2 | Manager.Number2
So the workflow I am imagining to automate the Employee - Manager field in AD is:
1. NetSuite Exports csv file at a scheduled time
2. PowerShell Script to import the NetSuite csv and edit the data as described.
3. Export-Csv to new csv with the usable data
4. PowerShell script to Set-AdUser -Manager from new csv
All that I am seek guidance on are Steps 2 and 3
Is this possible? I will update if I figure this out on my own.
edit
I have figured out Objective 1
Now all I need to be able to do is to take "Last, First" data from a column and change it to "First.Last"
edit 2 - This doesn't seem to work quiet right....
$txt = import-csv .\book1.csv | % {
$_.Email = $_.Email -replace "#test.com", ""
$_
}
export-csv -InputObject $txt -NoTypeInformation .\newbook1.csv
You could try:
Import-Csv -Path .\book1.csv | ForEach-Object {
#Remove #AndEverthingThatFollows
$_.Email = $_.Email -replace "#.*$"
#Replace "LastName, FirstName" (space optional) with FirstName.Lastname
$_.Supervisor = $_.Supervisor -replace '(\w+),\s*?(\w+)', '$2.$1'
} | Export-Csv -NoTypeInformation -Path .\newbook1.csv
I'm trying to figure out the best way to do this, and I'm not sure how to Import-Csv with 2 different files through the same pipeline and export a value found...
So lets start with CSV file 1: I only want the values for LoginNumber where Type = H and (ContractorDomain -ne $null -or ContractorDomain -ne ""). For example, this should only pull values 0031482 and 2167312 from below.
Note: I only added spaces and arrows to make it easier to read as columns here. The csv files have no spaces between the column values or arrows.
"LoginNumber","Type","ContractorDomain"
"0031482" ,"H" ,"P12345" <<
"1251632" ,"P" ,"A52671"
"2167312" ,"H" ,"425126" <<
"0598217" ,"L" ,""
"1405735" ,"H" ,""
"2058194" ,"A" ,"L21514"
When the value number for LoginNumber (based on conditions explained above) is found, search for it in CSV file 2. Then grab the value of AccountStatus and SamAccountName for the respective value of UserIDNumber.
"SamAccountName","UserIDNumber","AccountDescriptionDetails","AccountStatus"
"jd12395" ,"0052142" ,"Company CEO" ,"Enabled"
"jwet" ,"2167312" ,"Software Developer" ,"Disabled" <<
"1b3gas5" ,"1385293" ,"Project Manager" ,"Disabled"
"632g1fsa" ,"0031482" ,"QA Tester" ,"Enabled" <<
"4126hs" ,"0000418" ,"Program Manager" ,"Disabled"
"axv" ,"1840237" ,"Accountant Administrator" ,"Disabled"
For the 3rd CSV file we have the following:
"domainName","SameAccountName","DateExpired"
"TempDomain","jwet" ,"20151230" <<
"PermDomain","p21942" ,""
"PermDomain","qz231034" ,""
"TempDomain","632g1fsa" ,"20151231" <<
"TempDomain","ru20da2bb22" ,"20160425"
Next, for the 3rd file, I want to add the column to plug in the Disabled and Enabled values (or User Match Not Found value):
"domainName","SameAccountName","DateExpired","UserStatus"
"TempDomain","jwet" ,"20151230" ,"Disabled" <<
"PermDomain","p21942" ,"" ,"User Match Not Found"
"PermDomain","qz231034" ,"" ,"User Match Not Found"
"TempDomain","632g1fsa" ,"20151231" ,"Enabled" <<
"TempDomain","ru20da2bb22" ,"20160425" ,"User Match Not Found"
I learned how to import-csv and create new columns with something like this...
Import-Csv $file | Select-Object -Property *, #{Name="UserStatus";Expression={
if ($true) {"fill value in here"}
}} | Export-Csv $newFile -NoType
So I'm thinking something like this. I'm just not sure how to search/find/pass multiple CSV files values through the pipeline.
Note: some of these CSV files have like 15 columns before and after the columns we are searching for. Also, some of the columns values have a comma, so I can't really rely on the -Delimiter ,. Also, some of the column values do not have " (if you were to open the CSV in txt format).
Columns containing commas shouldn't be an issue if the values are properly quoted (i.e. if the CSV is valid). Import-Csv will correctly import a record 42,"a,b",c as three values 42, a,b and c. If your CSV isn't well-formed: fix that first.
Fetch the login IDs from the first CSV file:
$logins = Import-Csv 'C:\path\to\file1.csv' |
Where-Object { $_.Type -eq 'H' -and $_.ContractorDomain } |
Select-Object -Expand LoginNumber
You can simplify the ContractorDomain property check to just $_.ContractorDomain, because PowerShell interprets both an empty string and $null as a boolean value $false in that context. The same would happen for other zero or empty values (0, 0.0, empty array, etc.), but that shouldn't be an issue in your scenario.
Next create a hashtable mapping account names to their respective status. Filter the imported second CSV by the list of IDs you created before, so the hashtable contains only relevant mappings.
$accountStatus = #{}
Import-Csv 'C:\path\to\file2.csv' | Where-Object {
$logins -contains $_.UserIDNumber
} | ForEach-Object {
$accountStatus[$_.SamAccountName] = $_.AccountStatus
}
With that hashtable you can now add the UserStatus column to your third CSV:
(Import-Csv 'C:\path\to\file3.csv') |
Select-Object -Property *, #{n='UserStatus';e={
if ($accountStatus.ContainsKey($_.SameAccountName)) {
$accountStatus[$_.SameAccountName]
} else {
'User Match Not Found'
}
}} | Export-Csv 'C:\path\to\file3.csv' -NoType
The parentheses around the Import-Csv statement ensure that the file is completely read and closed before Export-Csv starts writing to it. They're only required if you're writing the modified data back to the same file and can be omitted otherwise. The asterisk selects all imported columns, and the additional calculated property adds the new column you want to include.
I have 2 CSV files I'd like to compare. They both have multiple columns of different data but they also both have a column with IP addresses. Call them $log1 and $log2
I am trying to compare the files. If an IP from $log1 is found in $log2 I would like an output file that has the entire row of data from the match of $log2...
When I use:
Compare-Object -Property 'IP address' -ReferenceObject $log1 -DifferenceObject $log2
It returns only the 'IP address' column and the SideIndicator.
I think I'm barking up the wrong tree here, can anyone offer some advice?
I would try another approach :
$log1,$log2 | group-object -Property 'IP address' | where {$_.count -eq 2}
In the result you will find a group property with the two lines.
"Try adding the -PassThru flag to your command."
- Dave Sexton
This works. I exported the results to CSV and sorted by the SideIndicator when I opened the file (don't think you can get PS to sort by SideIndicator).
Thanks Dave.
There's probably more ways to accomplish this, as noted by others but this achieved my goal.
This script will compare your both csv files and writhe output for each double ip address found.
#import your csv files
$csv1 = Import-Csv "C:\Users\Admin\Desktop\csv\csv1.csv"
$csv2 = Import-Csv "C:\Users\Admin\Desktop\csv\csv2.csv"
#Compare both csv files (.ip corresponds to your column name for your ip address in the csv file )
$compare = Compare-Object $csv1.ip $csv2.ip -IncludeEqual | ? {$_.SideIndicator -eq "=="}
if ($compare) {
foreach ($ip in $compare.InputObject) {
Write-Output "IP $ip exist in both csv files"
}
}
Else
{
Write-Output "Double ip not found"
}