manipulate imported csv data in PowerShell - csv

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

Related

use where-object to find data, but want to add data to every row also the export to csv

Hi I have a script that reads a csv file, creates a json file, checks the users in the file against a service, then i get the result as a json file.
I take that result and finds the users i csv file and creates a new file.
I do that with a where-object
But i need to add some extra values on every user before i export it to csv
This is my 2 lines for finding users and then export
$matches = $users | where-object { $_.number -in $response.allowedItemIds } | Select-Object -Property Number,Surname,Forename,Emailaddress
$matches | Export-Csv -path $Saved$savefile -NoTypeInformation -Append
Is that possible or do i need to do a for each?
Cheers
Assuming I've interpretted your question correctly, you should be able to use PowerShell's Calculated Properties for this purpose.
For example, if you wanted to add a field called "Date" and set the current Date/Time to each user row, you could do the following:
$matches = $users | where-object { $_.number -in $response.allowedItemIds } | Select-Object -Property Number,Surname,Forename,Emailaddress, #{Name="Date";Expression={Get-Date}}
The Expression value can either be a static value such as "StaticValue", a variable such as $i (useful if used as part of a loop, for example) or more complex value that is returned from other cmdlets (as in my example above)

Issue while saving collection into csv using powershell

I have below powershell code using which am saving results into csv file but I couldnt save them in csv file.
[Reflection.Assembly]::LoadWithPartialName("Microsoft.AnalysisServices")
$SSASServerName = "SSAS_ServerName"
$SSASDB = "TESTDB"
$SSASServer = New-Object Microsoft.AnalysisServices.Server
$SSASServer.Connect($SSASServerName)
$SSASDatabase = $SSASServer.Databases.Item($SSASDB)
$SSASDatabase.Roles | Select-Object Name, Members | Export-Csv C:\dev\psout\test.Csv
pause
This script extracts name of the role and members associated to that role. one role can have multiple members.
I tried above script, it exports role but in Members field, I see string "Microsoft.AnalysisServices.RoleMemberCollection" for all the roles.
If I do not export to csv, I can view the members in either ps window or text file.
what am i missing?
You can only export values that can be represented as a string to a csv-file. Members is a collection-object that may include multiple RoleMember-objects, so you need use a calculated property to access the Name-property inside each RoleMember. How to approach this depends on the desired output.
You can join the objects Name-property to a single string
$SSASDatabase.Roles |
Select-Object Name, #{n="Members";e={ ($_.Members | % { $_.Name }) -join '; '}} |
Export-Csv C:\dev\psout\test.Csv -NoTypeInformation
Role1,"User1; User2"
Role2,"User3; User4"
Or you could make one row in the csv-file "per row per member" which I usually prefer since it's easier to filter in Excel.
$SSASDatabase.Roles | ForEach-Object {
#Store role-reference so we can access it later inside the member-foreach
$r = $_
$r.Members | ForEach-Object {
#Store member-reference so it's available inside Selec-Object
$m = $_
$r | Select-Object Name, #{n="Member";e={ $m.Name }}
}
} | Export-Csv C:\dev\psout\test.Csv -NoTypeInformation
Role1,User1
Role1,User2
Role2,User3
...

PowerShell script to go through a directory of csvs and convert them to html

This is a PowerShell question, not a SharePoint question.
I'm using a script to grab an inventory of SharePoint features, web parts, etc. It outputs each type of report in the same directory as csv files. So I'll end up with a directory on my computer with the csv files.
I'd like to run another PowerShell script after the first one that converts these csvs into html files for easily readable reports.
I'm getting stuck on the part where I would import-csv each file and create each html file with similarly named html files.
Here's what I have so far. Can anyone help me complete this to do what I want it to do? To use Import-CSV, I have to specify the file name as you can see in $dir. Is there another way?
$dir = "C:\Users\me\Desktop\output\TestInvSiteCollections.csv"
dir -LiteralPath $dir | % {Import-Csv $dir}
or use this somehow..
Import-Csv -LiteralPath $dir | ConvertTo-Html | Out-File "C:\Users\me\Desktop\output\myhtmlfile.html"
I would do it like this:
Get-ChildItem -Path 'C:\Users\me\Desktop\output\*.csv' | ForEach-Object {
Import-Csv $_ | ConvertTo-Html | Out-File -FilePath (Join-Path -Path $_.DirectoryName -ChildPath ($_.BaseName + '.html'));
}
I'm not entirely sure I find html tables easier to read than csv files. Excel's filtering and sorting is too useful.
Here's your code. It should split the name of the file and add the extension.
Import-Csv -LiteralPath $dir | ConvertTo-Html | Out-File ($dir.Split(".")[0]+".html")
This is a slightly more verbose method, but I generally prefer readable code over conciseness for maintainability:
#get the list of csv files
$csvFiles = Get-ChildItem $path -Filter *.csv
foreach ($file in $csvFiles)
{
#create FileInfo object
[System.IO.FileInfo]$fileInfo = "$path\$file"
#Get base name of file
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
#do HTML conversion
Import-Csv $fileInfo.FullName | ConvertTo-Html | Out-File "$htmlPath\$baseName.html"
}
This is working code assuming you have $path defined somewhere and can obviously be modified to suite your needs.

Powershell: Reading in a column from a .CSV file and then adding a specific string to the beginning and exporting again

I'm attempting to write a script which will read in a CSV generated by querying AD for user information (that part is done) but then will allow me to add a string to the beginning of each value of a column in the CSV file and then export it.
For instance we have this CSV file:
"displayname","Office"
Bob,7142
Janet,8923
SantaClaus,0912
NicCage,0823
I want to take each entry for "Office", add the string "BUG" before it and then export it back out. The modified CSV should look like:
"displayname","Office"
Bob,BUG7142
Janet,BUG8923
SantaClaus,BUG0912
NicCage,BUG0823
At this point, I've been attempting to read in just the "Office" column and then displaying it with "Write-Host". The idea being that if I can do that then maybe I can create a new variable that would be something like:
$BUG = "BUG"
$NewVar = $BUG$Office
Which would hopefully look like the second CSV file. I am extremely new to powershell scripting.
The attempts I've made so far are these:
Attempt #1:
$UserList = Import-CSV C:\Users\username\CSV.csv
$UserList | ForEach-Object ($_.Office) { $UserList }
Attempt #2:
$projectName = import-csv C:\Users\username\CSV.csv | % {$_.Office}
$BUG = "BUG"
$projectName | ForEach-Object ($_) {$projectName}
Attempt #3:
$UserList = Import-CSV C:\Users\username\CSV.csv
#ForEach ($Office in $Userlist) {
#Write-Host $UserList.Office
#}
Attempt #4:
Import-Csv "C:\Users\username\CSV.csv" -Header ("displayname","Office","whenCreated","EmailAddress") | Select-Object Office | Export-CSV -Path C:\users\Username\test.csv
I have gotten it to read out just the Office numbers before using the ForEach-Object loop structure but then it never stops reading out the office numbers so that's unhelpful.
I think I'm going in the right direction, but I just can't figure out how to modify a column like this.
Instead of trying to extract the Office column, just pipe the full data set (all columns) to ForEach-Object, change the value of the Office property and pipe it back to Export-Csv:
$Prefix = "BUG"
Import-Csv .\file.csv | ForEach-Object {
$_.Office = $Prefix + $_.Office
$_
} | Export-Csv .\file_modified.csv -NoTypeInformation

Creating a Csv using Powershell

I am trying to take a filename such as: John_Doe_E_DOB_1/1/46_M(This is the gender)_ID_0000000_IMG_FileName_Date-of-File_1/1/15_Doc-page-1 And create a CSV file to open in Excel with column headers for: Last Name, First Name, MI, ID No, File Name, Date of File along with doc type. Here's my code so far:
Get-ChildItem -Path C:\Users\name\desktop\test -Recurse | ForEach-Object {$_ | add-member -name "Owner" -membertype noteproperty -value (get-acl $_.fullname).owner -passthru} | Sort-Object fullname | Select BaseName,Name,Owner | Export-Csv -Force -NoTypeInformation C:\Users\name\desktop\test\thing.csv
All this is doing is dropping that really long file name in at the top, and then adding the ext at the end in another column. Example:
John_Doe_E_DOB_1/1/46_M(This is the gender)_ID_0000000_IMG_FileName_Date-of-File_1/1/15_Doc-page-1 Would be in column 1 and
John_Doe_E_DOB_1/1/46_M(This is the gender)_ID_0000000_IMG_FileName_Date-of-File_1/1/15_Doc-page-1.txt <----- Would be the only difference in column 2
How can I split this up for over a million files, all different lengths, and sizes, and get it to break up into the categories listed above? All help would be greatly appreciated.
I would replace the Select stage of your pipeline with a call to a filter function like this:
filter GenObj {
$parts = $_.FullName.Split('_')
new-object pscustomobject -property #{
Owner = (get-acl $_.fullname).owner
FirstName = $parts[0]
LastName = $parts[1]
MiddleInitial = $parts[2]
# Fill in the rest
}
}
Get-ChildItem -Path C:\Users\name\desktop\test -Recurse |
Sort-Object fullname |
GenObj |
Export-Csv -Force -NoTypeInformation C:\Users\name\desktop\test\thing.csv
This will create a new custom object with all the properties on it that correspond to the parts of the filename you want to extract.
This string splitting approach may not work depending on how you handle names with no middle initial.
Also be aware that if you are processing a million files, the use of Sort-Object will cause every single FileInfo object (one for every file) to get buffered in memory so the sort can be performed. You may likely run out of memory and the command will fail. I would consider removing Sort-Object in this scenario.