I am trying to replace a \ contained in the filenames I have queried from the database. My script below loops through a CSV containing project codes. For each project code the database is queried and the project name is retrieved.
However, the projectname contains \ which I am trying to replace.
$startRow = 2
$col = 3
$excel = New-Object -COM Excel.Application
$wb = $excel.Workbooks.Open("\myprojectfolder\projectcodes.csv")
$excel.Visible = $false
for ($i = 1; $i -le $wb.Sheets.Count; $i++){
$sh = $wb.Sheets.Item($i)
$endRow = $sh.UsedRange.Rows.Count
$rangeAddress = $sh.Cells.Item($startRow,$col).Address() + ":" +
$sh.Cells.Item($endRow,$col).Address()
$sh.Range($rangeAddress).Value2 | foreach {
#GET PROJECT NAME TO APPEND TO FOLDER NAME
$projectCode = $_
$Server= "MYSERVER"
$Database = "MYDATABASE"
$SQLQuery = $("SELECT [description] FROM [dbo].[projects] WHERE [project] = '$projectCode'")
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "server='$Server';database='$Database';trusted_connection=true;"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$Command.CommandText = $SQLQuery
$Reader = $Command.ExecuteReader()
while ($Reader.Read()) {
$projectName = $Reader.GetValue($1)
#CHECK AND REPLACE '\' CHARACTER IN PROJECTNAME
if ($projectName -like '*\\*') {
Write-Debug "PROJECT NAME CONTAINS \"
$projectName.Replace('\\', '_')
}
$folderPath = "\\myfolder\"
$pathTogether = $folderPath + $projectCode + "_" + $projectName + "\"
New-Item -Path $pathTogether -Type Directory -force
#CHECK IF FILE EXISTS IN APPROPRIATE DIRECTORY
$testFile = $pathTogether + $projectCode + "_" + $projectName + ".xlsm"
$fileExist = Test-Path $testFile
if ($fileExist -eq $false) {
$templateFile = $folderPath + "my_template\my_template.xlsm"
Copy-Item $templateFile $pathTogether
$newPath = $pathTogether + "\my_template.xlsm"
$saveFile = $projectCode + "_" + $projectName + ".xlsm"
$renameToOLD = $projectCode + "_" + $projectName + "_RENAMED" + ".xlsm"
#RENAME PROJECT FILE TO HAVE OLD IN FILENAME
Rename-Item $newPath $saveFile
$projectxlFile = New-Object -COM Excel.Application
$projectxlFile.workbooks.open($pathTogether + "\" + $saveFile)
$queryWS = $projectxlFile.worksheets.Item("Query")
$queryWS.Cells.Item(8,2) = $projectCode
$projectxlFile.DisplayAlerts = $False
$projectxlFile.Visible = $False
$savePath = $pathTogether + $saveFile
#Add-Type -AssemblyName Microsoft.Office.Interop.Excel
#$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbookMacroEnabled
$projectxlFile.ActiveWorkbook.Save()
$projectxlFile.Workbooks.Close()
$projectxlFile.Quit()
$ProcID = Get-Process |
Where-Object {$_.MainWindowHandle -eq $projectxlFile.HWND} |
Select -ExpandProperty ID
Get-Process -Id $ProcID | Stop-Process -Force
##[System.Runtime.Interopservices.Marshal]::ReleaseComObject($projectxlFile)
}
}
$Connection.Close()
}
}
$excel.Workbooks.Close()
$excel.Quit()
$ProcID2 = Get-Process |
Where-Object {$_.MainWindowHandle -eq $excel.HWND} |
Select -ExpandProperty ID
Get-Process -Id $ProcID2 | Stop-Process -Force
###[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
$projectName.Replace('\\', '_')
By default the Replace() method does regular string replacements, so the above would only replace double backslashes with an underscore. Also, it doesn't replace in-place, so you need to assign the modified string back to the variable:
$projectName = $projectName.Replace('\', '_')
The -like operator does wildcard matches, so you mustn't escape the backslash in that expression either, otherwise you don't even get to the replacement operation:
if ($projectName -like '*\*') {
Write-Debug 'PROJECT NAME CONTAINS \'
$projectName = $projectName.Replace('\', '_')
}
Related
I am trying to download all CSV files from the \tmp\ directory with a PS script and convert them to one excel file as a report and place it in the \reports\ directory under the name LDAP.xlsx . My CSV files have varying amounts of saved data.
In the forum I found this how-to-export-a-csv-to-excel-using-powershell and my code looks like this:
Clear-Host
# SOURCE
##########
# config file
$conf_file = "C:\PS_LDAP_searchlight\config\searchlight_conf.conf"
$conf_values = Get-Content $conf_file | Out-String | ConvertFrom-StringData
# variables from config file
$main_path = $conf_values.main_path
$tmp_path = $conf_values.tmp_path
$reports_path = $conf_values.reports_path
# PROGRAM
##########
$workingdir = $main_path + $tmp_path + "*.csv"
$reportsdir = $main_path + $reports_path
$csv = dir -path $workingdir
foreach($inputCSV in $csv){
$outputXLSX = $reportsdir + "\" + $inputCSV.Basename + ".xlsx"
### Create a new Excel Workbook with one empty sheet
$excel = New-Object -ComObject excel.application
$excel.DisplayAlerts = $False
$workbook = $excel.Workbooks.Add(1)
$worksheet = $workbook.worksheets.Item(1)
### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data ยป From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)
### Set the delimiter (, or ;) according to your regional settings
### $Excel.Application.International(3) = ,
### $Excel.Application.International(5) = ;
$query.TextFileOtherDelimiter = $Excel.Application.International(5)
### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()
### Save & close the Workbook as XLSX. Change the output extension for Excel 2003
$Workbook.SaveAs($outputXLSX,51)
$excel.Quit()
# Cleaner
$inputCSV = $null
$outputXLSX = $null
}
## To exclude an item, use the '-exclude' parameter (wildcards if needed)
#remove-item -path $workingdir -exclude *Crab4dq.csv
# CLEANER
###############################
# SOURCE
###############################
# config file
$conf_file = $null
$conf_values = $null
# variables from config file
$main_path = $null
$tmp_path = $null
$reports_path = $null
# PROGRAM
###############################
$workingdir = $null
$csv = $null
$reportsdir = $null
the code reads all files but writes one to one. I need help and explanation on how to make a many-to-one option. I would like each CSV file to be saved as a separate sheet under its own name like:
users_all_inf.csv in excel\sheet1 => users_all_inf
active_users_last_logon_year_ago.csv in excel\sheet2 => active_users_last_logon_year_ago
nextfilename.csv in excel\next_sheet => nextfilename
so that all data will be available in one excel report.xlsx file.
I will be grateful for any hint or help in converting the code.
Finally my code looks like:
Clear-Host
# config file
$conf_file = "C:\SEARCHLIGHT\config\searchlight_conf.conf"
$conf_values = Get-Content $conf_file | Out-String | ConvertFrom-StringData
# variables from config file
$main_path = $conf_values.main_path
$tmp_path = $conf_values.tmp_path
$reports_path = $conf_values.reports_path
$system_name = $conf_values.system_name
$tmp_dir = $main_path + $tmp_path + "*" # source file
$outputfilename = $(get-date -f yyyyMMdd) + "_" + $system_name + "_report.xlsx" # destination file with date
# get list of csvs files
$csvs = Get-ChildItem $tmp_dir -Include *.csv
$y = $csvs.Count
Write-Host "Detected the following CSV files: ($y)"
foreach ($csv in $csvs) {
Write-Host " "$csv.Name
}
Write-Host Creating: $outputfilename
# Create a new Excel workbook
$excelapp = new-object -comobject Excel.Application
$excelapp.sheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
$sheet=1
$delimiter = ";" # delimiter used in the csv file
foreach ($csv in $csvs) {
#$row=1
#$column=1
$worksheet = $xlsx.Worksheets.Item($sheet)
$worksheet.Name = $csv.Name
# Build the QueryTables.Add command and reformat the data
$TxtConnector = ("TEXT;" + $csv)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)
$query.TextFileOtherDelimiter = $delimiter
$query.TextFileParseType = 1
$query.TextFileColumnDataTypes = ,1 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
# Execute & delete the import query
$query.Refresh()
$query.Delete()
$sheet++
} # end foreach ($csv in $csvs)
# Save & close the Workbook as XLSX
$output = $main_path + $reports_path + $outputfilename
$xlsx.SaveAs($output)
$excelapp.quit()
I found a solution that partially solves my problem:
# variables from config file
$main_path = $conf_values.main_path
$tmp_path = $conf_values.tmp_path
$reports_path = $conf_values.reports_path
$system_name = $conf_values.system_name
$tmp_dir = $main_path + $tmp_path + "*"
$csvs = Get-ChildItem $tmp_dir -Include *.csv
$y = $csvs.Count
Write-Host "Detected the following CSV files: ($y)"
foreach ($csv in $csvs)
{
Write-Host " "$csv.Name
}
$outputfilename = $(get-date -f yyyyMMdd) + "_" + $system_name + "_report.xlsx" #creates file name with date/username
Write-Host Creating: $outputfilename
$excelapp = new-object -comobject Excel.Application
$excelapp.sheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
$sheet=1
foreach ($csv in $csvs) {
$row=1
$column=1
$worksheet = $xlsx.Worksheets.Item($sheet)
$worksheet.Name = $csv.Name
$file = (Get-Content $csv)
foreach($line in $file) {
$linecontents=$line -split ',(?!\s*\w+")'
foreach($cell in $linecontents) {
$worksheet.Cells.Item($row,$column) = $cell
$column++
}
$column=1
$row++
}
$sheet++
}
$output = $main_path + $reports_path + $outputfilename
$xlsx.SaveAs($output)
$excelapp.quit()
this solves the problem many to one but in the worksheet all the data is stored in one column. At this moment I have got:
csv files:
data1;data2;data3;...
data1;data2;data3;...
report like:
| A | B |
|-----------------------|---|
| data1;data2;data3;... | |
|-----------------------|---|
| data1;data2;data3;... | |
i need help to make the data split into columns like:
| A | B | C | ... |
|-------|-------|-------|-----|
| data1 | data2 | data3 | ... |
|-------|-------|-------|-----|
| data1 | data2 | data3 | ... |
Please find the github link on using ImportExcel module.
https://github.com/dfinke/ImportExcel/tree/master/Examples
$outputFile = "C:\Temp\OutputExcelFile.xlsx" #Output File
$csvFiles = Get-childItem -Filter *.csv # Filtering CSV file in my present working dir
foreach ($csvFile in $csvFiles) {
#Import csv file and export it contents to Output excel file and rename the sheet.
Import-csv $csvFile | Export-Excel $outputFile -WorksheetName $csvFile.BaseName
}
Hope it helps.
I was able to find here the code for Word Document files, how could I use /adjust the same set of code to run Excel files
Thanks
$objWord = New-Object -comobject Word.Application
$objWord.Visible = $false
$list = Get-ChildItem "C:\Users\john\foldername\*.*" -Include *.doc*
foreach($item in $list){
$objDoc = $objWord.Documents.Open($item.FullName,$true)
$objSelection = $objWord.Selection
$wdFindContinue = 1
$FindText = "1911"
$MatchCase = $False
$MatchWholeWord = $true
$MatchWildcards = $False
$MatchSoundsLike = $False
$MatchAllWordForms = $False
$Forward = $True
$Wrap = $wdFindContinue
$Format = $False
$wdReplaceNone = 0
$ReplaceWith = "456"
$wdFindContinue = 1
$ReplaceAll = 2
$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, `
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,`
$Wrap,$Format,$ReplaceWith,$ReplaceAll)
$objDoc.Save()
$objDoc.Close()
}
$objWord.Quit()
Based on this answer, you could do something like this:
$folderPath = "C:\Users\john\foldername\*"
$fileType = "*.xls*"
$excel = New-Object -ComObject Excel.Application
$textToReplace = #{
# "TextToFind" = "TextToReplaceWith"
"This1" = "That1"
"This2" = "That2"
"This3" = "That3"
}
Function findAndReplace($wsheet, $FindText, $ReplaceWith) {
#simple Replace to execute on all columns of a Worksheet object
$wsheet.Columns.Replace($FindText, $ReplaceWith) > $null
}
Function findAndReplaceMulti($wsheet, $lookupTable) {
#apply multiple Replace on the same Worksheet object
$lookupTable.GetEnumerator() | ForEach-Object {
findAndReplace $wsheet $_.Key $_.Value
}
}
Function findAndReplaceWholeWb($wbook, $lookupTable) {
#apply multiple Replace in all Worksheets
$wbook.Worksheets | ForEach-Object {
findAndReplaceMulti $_ $lookupTable
}
}
Get-ChildItem -Path $folderPath -Recurse -Filter $fileType | ForEach-Object {
$excel.Visible = $False
Write-Host "Processing `"$($_.Name)`"..."
$wbook = $excel.Workbooks.Open($_.FullName)
findAndReplaceWholeWb $wbook $textToReplace
$wbook.Close($True)
}
$excel.Quit()
$excel = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
I have 20 csv files. Each are unrelated. How do I combine them together into one xlsx file with 20 sheets, each named after the csv files.
$root = "C:\Users\abc\Desktop\testcsv"
$CSVfiles = Get-ChildItem -Path $root -Filter *.csv
$xlsx = "C:\Users\abc\Desktop\testxl.xlsx" #output location
$delimiter = "," #delimiter
#Create a excel
$xl=New-Object -ComObject Excel.Application
$xl.Visible=$true
#add a workbook
$wb=$xl.WorkBooks.add(1)
ForEach ($csv in $CSVfiles){
#name the worksheet
$ws=$wb.WorkSheets.item(1)
$ws.Name = [io.path]::GetFileNameWithoutExtension($csv)
$TxtConnector = ("TEXT;" + $csv)
$Connector = $ws.QueryTables.add($TxtConnector,$ws.Range("A1"))
$query = $ws.QueryTables.item($Connector.name)
$query.TextFileOtherDelimiter = $delimiter
$query.TextFileParseType = 1
$query.TextFileColumnDataTypes = ,1 * $ws.Cells.Columns.Count
$query.AdjustColumnWidth = 1
# Execute & delete the import query
$query.Refresh()
$query.Delete()
$wb.SaveAs($xlsx,51)
}
# Save & close the Workbook as XLSX.
$xl.Quit()
This way, change the first line to the folder where you store those 20 CSV files and then
$path="c:\path\to\folder" #target folder
cd $path;
$csvs = Get-ChildItem .\* -Include *.csv
$y=$csvs.Count
Write-Host "Detected the following CSV files: ($y)"
foreach ($csv in $csvs)
{
Write-Host " "$csv.Name
}
$outputfilename = $(get-date -f yyyyMMdd) + "_" + $env:USERNAME + "_combined-data.xlsx" #creates file name with date/username
Write-Host Creating: $outputfilename
$excelapp = new-object -comobject Excel.Application
$excelapp.sheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
$sheet=1
foreach ($csv in $csvs)
{
$row=1
$column=1
$worksheet = $xlsx.Worksheets.Item($sheet)
$worksheet.Name = $csv.Name
$file = (Get-Content $csv)
foreach($line in $file)
{
$linecontents=$line -split ',(?!\s*\w+")'
foreach($cell in $linecontents)
{
$worksheet.Cells.Item($row,$column) = $cell
$column++
}
$column=1
$row++
}
$sheet++
}
$output = $path + "\" + $outputfilename
$xlsx.SaveAs($output)
$excelapp.quit()
cd \ #returns to drive root
https://stackoverflow.com/a/51094040/5995160 answer is too slow when dealing with csv's with a ton of data, I modified this solution to use https://github.com/dfinke/ImportExcel. This has greatly improved the performance of this task, at least for me.
Install-Module ImportExcel -scope CurrentUser
$csvs = Get-ChildItem .\* -Include *.csv
$csvCount = $csvs.Count
Write-Host "Detected the following CSV files: ($csvCount)"
foreach ($csv in $csvs) {
Write-Host " -"$csv.Name
}
$excelFileName = $(get-date -f yyyyMMdd) + "_" + $env:USERNAME + "_combined-data.xlsx"
Write-Host "Creating: $excelFileName"
foreach ($csv in $csvs) {
$csvPath = ".\" + $csv.Name
$worksheetName = $csv.Name.Replace(".csv","")
Write-Host " - Adding $worksheetName to $excelFileName"
Import-Csv -Path $csvPath | Export-Excel -Path $excelFileName -WorkSheetname $worksheetName
}
This solution assumes that the user has already changed directories to where all the csv's live.
See below for a solution with uses the OpenText method.
At least two things to note:
I'm assuming your workbook creates a single sheet by default. if creates more than that, you will need to modify the script so that these additional sheets are deleted from the end result.
The way you specify TextFileColumnDataTypes is quite clever. You will need to modify it and feed the array to the FieldInfo argument below. See the documentation linked above for the kind of array it is expecting.
$CSVfiles = Get-ChildItem -Path $root -Filter *.csv
$xlsx = "C:\Users\abc\Desktop\testxl.xlsx" #output location
#Create a excel
$xl = New-Object -ComObject Excel.Application
$xl.Visible=$true
#add a workbook
$wb = $xl.WorkBooks.add(1)
# how many worksheets do you have in your original workbook? Assuming one:
$ws = $wb.Worksheets.Item(1)
ForEach ($csv in $CSVfiles){
# OpenText method does not work well with csv files
Copy-Item -Path $csv.FullName -Destination ($csv.FullName).Replace(".csv",".txt") -Force
# Use OpenText method. FieldInfo will need to be amended to suit your needs
$xl.WorkBooks.OpenText(`
($file.FullName).Replace(".csv",".txt"), # Filename
2, # Origin
1, # StartRow
1, # DataType
1, # TextQualifier
$false, # ConsecutiveDelimiter
$false, # Tab
$false, # Semicolon
$true, # Comma
$false, # Space
$false, # Other
$false, # OtherChar
#() # FieldInfo
)
$tempBook = $xl.ActiveWorkbook
$tempBook.worksheets.Item(1).Range("A1").Select() | Out-Null
$tempBook.worksheets.Item(1).Move($wb.Worksheets.Item(1)) | Out-Null
# name the worksheet
$xl.ActiveSheet.Name = $csv.BaseName
Remove-Item -Path ($csv.FullName).Replace(".csv",".txt") -Force
}
$ws.Delete()
# Save & close the Workbook as XLSX.
$wb.SaveAs($xlsx,51)
$wb.Close()
$xl.Quit()
I open a CSV file in Excel and run this macro to change the background color. I am trying to convert this part of code to PowerShell.
lrow = Range("G" & Rows.Count).End(xlUp).Row
Set MR = Range("G2:G" & lrow)
For Each cell In MR
If UCase(Trim(cell.Value)) = "FALSE" Then
cell.Interior.ColorIndex = 3
End If
Next
Any help converting this code to PowerShell.
Thanks
SR
You could write something like this:
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $true
$objExcel.DisplayAlerts = $false
$filePath = "c:\logs\2015-04-23.csv"
$xlsFilePath = Get-Item -Path $filePath | % { Join-Path (Split-Path $_ -Parent) "$($_.BaseName).xls" }
$workBook = $objExcel.Workbooks.Open($filePath)
$workSheet = $WorkBook.sheets | select -First 1
$xlup = -4162
$lrow = $workSheet.cells.Range("G" + $workSheet.Rows.Count).End($xlup).Row
$workSheet.cells.Range("G2:G" + $lrow) | % {
$value = $_.Text
if($value.ToUpper() -eq "TRUE"){
$_.Interior.ColorIndex = 3
}
}
$WorkBook.SaveAs($xlsFilePath, 18)
$objExcel.Quit()
If you have a very large file, it is faster to search values using powershell then updating the Excel sheet. The following example looks a bit funny but executes much faster.
$filePath = "c:\logs\2015-04-23.csv"
$rowAliases = 97..122 | foreach { ([char]$_).ToString().ToUpper() }
$selectedRow = "G"
$selectedName = (Get-Content $filePath -ReadCount 1 -TotalCount 1).Split(",")[$rowAliases.IndexOf($selectedRow)]
$startRow = 2
$rowCount = 1;
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $true
$objExcel.DisplayAlerts = $false
$xlsFilePath = Get-Item -Path $filePath | % { Join-Path (Split-Path $_ -Parent) "$($_.BaseName).xls" }
$workBook = $objExcel.Workbooks.Open($filePath)
$workSheet = $WorkBook.sheets | select -First 1
Import-Csv -Path $filePath | % {
if($rowCount -ge $startRow){
[string]$value = $_ | select -ExpandProperty $selectedName
if($value.ToUpper() -eq "TRUE"){
$workSheet.cells.Item($rowCount + 1, $selectedIndex + 1).Interior.ColorIndex = 3
}
}
$rowCount ++
}
$WorkBook.SaveAs($xlsFilePath, 18)
$objExcel.Quit()
I have such a code for exporting Excel file with two worksheets into two csv files.The problem is that I am currently exporting whole worksheets and I want to export only these 3 columns from my loop.How can I save them? They must be in order because I want to import it later to AD.
Function ExportWSToCSV ($excelFileName , $csvLoc){
#Sample use in a console: ExportWSToCSV -excelFileName "Test_Peoplesoft.xls" -csvLoc "y:\Application Data\CSVFiles\"
$CultureOld = [System.Threading.Thread]::CurrentThread.CurrentCulture
#Original culture info
$CultureUS = [System.Globalization.CultureInfo]'en-US'
#US culture info
$excelFile = "y:\Application Data\Test_Peoplesoft.xls"
#Loc of Excel file .xls , #csvLov - Loc of output files in format .csv
[System.Threading.Thread]::CurrentThread.CurrentCulture = $CultureUS
$E = New-Object -ComObject Excel.Application
$E.Visible = $false
$E.DisplayAlerts = $false
$wb = $E.Workbooks.Open($excelFile)
$intRow = 2
$intRowMax =($ws.UsedRange.Rows).count
$elements = $email -or $costcode -or $leader
Do{
foreach($ws in $wb.sheets.item("Inactive")){
if($elements -ne $null ){
$email = $ws.Cells.Item($intRow, 4).Value()
$costcode = $ws.Cells.Item($intRow, 15).Value()
$leader = $ws.Cells.Item($intRow, 20).Value()
}else{Write-Host "Null Value in one of the attributes"}
}
<#
foreach($ws in $wb.sheets.item("Inactive")){
$email = $ws.Cells.Item($intRow, 4).Value()
$costcode = $ws.Cells.Item($intRow, 15).Value()
$leader = $ws.Cells.Item($intRow, 20).Value()
}
#>
$user = $email + "_" + $costcode + "_" + $leader
write-host $intRow " " $user
$intRow++
}While ($ws.Cells.Item($intRow,1).Value() -ne $null)
foreach ($ws in $wb.Worksheets)
{
Write-Host "Processing Worksheet: " $ws.Name
$n = $csvLoc + $excelFileName + "_" + $ws.Name
#Name variable - Output file loc + excel file name + worksheet name
$ws.SaveAs($n + ".csv", 6)
#Saving file to .csv
}
$E.Quit()
[System.Threading.Thread]::CurrentThread.CurrentCulture = $CultureOld
}
Something like this should work:
First, setup an array for containing our list of exported users like so:
$exportList = #()
(place before you start looping the rows)
Then loop through the rows on your worksheet with your do while loop and add a user object to add the your export list like so
# Create userObj with the required properties
$userObj = New-Object System.Object
$userObj | Add-Member -Type NoteProperty -Name Email -Value $email
$userObj | Add-Member -Type NoteProperty -Name CostCode -Value $costcode
$userObj | Add-Member -Type NoteProperty -Name Leader -Value $leader
# Add $userObj to our list to be exported
$exportList += $userObj
And ofcourse export it to .csv
$exportList | Export-Csv $pathToCsvFile