export the pipeline to a csv file - excel

I am trying to figure out how to export to a csv file. I have no problem exporting it to excel, yet when I try to export it to a csv file I screw it up. I left out the ad pull.
Foreach($result in $results){
$User = $result.GetDirectoryEntry()
$DistinguishedName = $USER.DistinguishedName -replace "'", "''"
$CN = $USER.CN -replace "'", "''"
$name = $USER.name -replace "'", "''"
$userAccountControl = $USER.userAccountControl
$extensionAttribute7 = $User.extensionattribute7 -replace "'", "''"
$extensionAttribute1 = $User.extensionattribute1 -replace "'", "''"
$operatingSystem = $USER.operatingSystem -replace "'", "''"
$pwdLastSet = [datetime]::FromFileTimeUtc((ConvertADSLargeInteger $USER.pwdLastSet[0]))
if( ( [datetime]"1900-01-01" - $pwdLastSet ).Days -gt 0 )
{
$pwdLastSet = [datetime]"1900-01-01"
}
Populate General Sheet(1) with information
foreach ($objItem in $result){
$Sheet1.Cells.Item($intRow, 1) = $CN
$Sheet1.Cells.Item($intRow, 2) = $operatingSystem
$Sheet1.Cells.Item($intRow, 3) = $pwdLastSet
$Sheet1.Cells.Item($intRow, 4) = $DistinguishedName
$Sheet1.Cells.Item($intRow, 5) = $extensionAttribute7
$Sheet1.Cells.Item($intRow, 6) = $extensionAttribute1
}

Simply pipe $result into a ForEach-Object loop and select the relevant properties from the object and export:
$results | % { $_.GetDirectoryEntry() } |
select CN, operatingSystem, pwdLastSet, DistinguishedName,
extensionattribute7, extensionattribute1 |
Export-Csv 'C:\output.csv' -NoType
You can use calculated properties to replace properties with modified versions of themselves:
$results | % { $_.GetDirectoryEntry() } |
select #{n='CN';e={$_.CN -replace "'","''"}},
#{n='operatingSystem';e={$_.operatingSystem -replace "'","''"}},
#{n='pwdLastSet';e={
$d = [DateTime]::FromFileTimeUtc($_.pwdLastSet[0])
if ( $d.Date -lt [DateTime]"1900-01-01" ) {
[DateTime]"1900-01-01"
} else {
$d
}
}},
#{n='DistinguishedName';e={$_.DistinguishedName -replace "'","''"}},
#{n='extensionattribute7';e={$_.extensionattribute7 -replace "'","''"}},
#{n='extensionattribute1';e={$_.extensionattribute1 -replace "'","''"}} |
Export-Csv 'C:\output.csv' -NoType

I'd make an array, fill it with objects based on what you have in your script, then you can loop through that to fill out the spreadsheet, and can also use it to export to CSV.
$Users = #()
Foreach($result in $results){
$User = $result.GetDirectoryEntry()
$pwdLastSet = [datetime]::FromFileTimeUtc((ConvertADSLargeInteger $USER.pwdLastSet[0]))
if( ( [datetime]"1900-01-01" - $pwdLastSet ).Days -gt 0 )
{
$pwdLastSet = [datetime]"1900-01-01"
}
$Users+=[PSCustomObject][Ordered]#{
User = $User
DistinguishedName = $USER.DistinguishedName -replace "'", "''"
CN = $USER.CN -replace "'", "''"
name = $USER.name -replace "'", "''"
userAccountControl = $USER.userAccountControl
extensionAttribute7 = $User.extensionattribute7 -replace "'", "''"
extensionAttribute1 = $User.extensionattribute1 -replace "'", "''"
operatingSystem = $USER.operatingSystem -replace "'", "''"
pwdLastSet = $pwdLastSet
}
}
For($intRow=1;$intRow -le $Users.count;$intRow++){
$Sheet1.Cells.Item($intRow, 1) = $Users[$intRow-1].CN
$Sheet1.Cells.Item($intRow, 2) = $Users[$intRow-1].operatingSystem
$Sheet1.Cells.Item($intRow, 3) = $Users[$intRow-1].pwdLastSet
$Sheet1.Cells.Item($intRow, 4) = $Users[$intRow-1].DistinguishedName
$Sheet1.Cells.Item($intRow, 5) = $Users[$intRow-1].extensionAttribute7
$Sheet1.Cells.Item($intRow, 6) = $Users[$intRow-1].extensionAttribute1
}
$Users | Export-Csv C:\Path\To\NewFile.csv -NoTypeInformation

Related

Improve multithreading and primary issue excel keeps closing

Primary issue is does anyone know why excel keeps closing? It is random and I do not know how to fix this issue.
My only thougths is to push everything into an array and do one final dump into excel at the end. but hoping for a better option. Or an improvement on how I am coding to help resolve this.
Everything appears to work except for excel randomly closing while processing the printers.
I have this script in multi-threaded form and in single threaded form and i get the same results.
only difference is multi-thread I get more results into the excel file.
Secondary question #2:
i have been reading about a dotnet workspace multithreading option that should be much faster. I am experimenting with but no success yet. Can I get an example where 2 parameters/arguments are passed to each job, with the results returned?
https://adamtheautomator.com/powershell-multithreading/
$Runspace = [runspacefactory]::CreateRunspace()
$PowerShell = [powershell]::Create()
$PowerShell.Runspace = $Runspace
$Runspace.Open()
$PowerShell.AddScript({Start-Sleep 5})
$PowerShell.BeginInvoke()
Back to Primary Issue:
Here is my current Script:
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string[]]$PrintServers = #("Rictx-print-p01","Rictx-print-p02","Rictx-cprint-p1","MHOH-CPRINT-P1","MTHOH-PRINT-P03","CORTX-PRINT-P01","PENFL-PRINT-P01","cdc-print","CN110","DA110","ito100","MarOH-PRINT-P01","mthoh-print-p01","mthoh-print-p02","PO100","SV-OHBA-001","SV-OHBUR-01","SV-OHBUR-02","SV-OHDS-001","sv-ohne-001","SV-OHPA-001","sv-ohtm-001","TE110"),
[string]$SaveAsPath = "\\rictx-script-p2\log\PrintServerReport\PrintServerInfo.xlsx", #\\rictx-script-p2\LOG\PrintServer\RICTX-PRINT-P02
[bool]$CloseReportFile = $false,
[bool]$RemoveSpecialCharacters = $true,
$ConcurrentJobProcess = 50
)
. \\rictx-script-p2\Scripts\Class\Log_Class_v3.ps1
# . \\rictx-script-p2\Scripts\Class\PrinterDetailClass.ps1
. \\rictx-script-p2\Scripts\Module\test\test-applicationrunning.ps1
#Excel Line Increment
$script:intRow = 0
#Prepare where file is being saved
if ($SaveAsPath.Substring(0,2) -eq '\\')
{
$Script_OutputLocationsUNCorDrive = ("\\$((Split-Path -Path "$SaveAsPath" -Parent))").Substring(2, ("\\$((Split-Path -Path "$SaveAsPath" -Parent))").IndexOf(("\\$((Split-Path -Path "$SaveAsPath" -Parent))").Split("\")[5]) + (("\\$((Split-Path -Path "$SaveAsPath" -Parent))").Split("\")[5]).Length -2)
$Script_OutputLocationsFolderPath = ("\\$((Split-Path -Path "$SaveAsPath" -Parent))").Substring(("\\$((Split-Path -Path "$SaveAsPath" -Parent))").IndexOf(("\\$((Split-Path -Path "$SaveAsPath" -Parent))").Split("\")[5]) + (("\\$((Split-Path -Path "$SaveAsPath" -Parent))").Split("\")[5]).Length)
}
else
{
$Script_OutputLocationsUNCorDrive = Split-Path -Path "$SaveAsPath" -Qualifier
$Script_OutputLocationsFolderPath = "$(Split-Path -Path $SaveAsPath -NoQualifier)".Substring(0,"$(Split-Path -Path $SaveAsPath -NoQualifier)".Length - (Split-Path -Path "$SaveAsPath" -Leaf).Length -1)
}
$Script_Log = ([log_class]::new())
$Script_Log.UNCorDrive = $Script_OutputLocationsUNCorDrive
$Script_Log.Folders_From_Root_to_Folder_Contaning_the_Log = "$Script_OutputLocationsFolderPath"
$Script_Log.LogFileName = Split-Path -Path $SaveAsPath -Leaf
$Script_Log.AddDatetoFileName = $true
$Script_Log.Enabled = $True
#$Script_Log.LogWrite("$TSQL")
#rename the saved file into a unique file name
$SaveAsPathFinal = "$($Script_Log.LogFolderPath)$($Script_Log.LogFileName).xlsx"
$PrintersInfo_Scriptblock =
{
Param
(
#$TestOnlyPingableComputers = $true,
[String]$PrinterName, $PrintServer
)
#####################################################################################################################################################
# Get Printer Information #
#####################################################################################################################################################
. \\rictx-script-p2\Scripts\Class\PrinterDetailClass.ps1
Write-host $PrinterName
write-host $PrintServer
write-host "Gathering Information"
$PrinterInfo = [PrinterDetailClass]::new($PrinterName, $PrintServer)
$A=1
return $PrinterInfo
}
FUNCTION processCompletedJobs
{
#####################################################################################################################################################
# Send Printer Information to Excel #
#####################################################################################################################################################
[array] $data = #()
$jobs = Get-Job -State Completed
#$JobsProcessed =
foreach( $job in $jobs )
{
$PrinterInfo = Receive-Job $job -Wait -AutoRemoveJob
#If ($Printer.Name -notlike "Microsoft XPS*")
#{
#$PrinterInfo = [PrinterDetailClass]::new($Printer.Name,$PrintServer)
$Sheet.Cells.Item($intRow, 1) = $PrinterInfo.Server
$Sheet.Cells.Item($intRow, 2) = $PrinterInfo.Name
$Sheet.Cells.Item($intRow, 3) = $PrinterInfo.Location
$Sheet.Cells.Item($intRow, 4) = $PrinterInfo.Comment
$Sheet.Cells.Item($intRow, 5) = $PrinterInfo.IPAddress
$Sheet.Cells.Item($intRow, 6) = $PrinterInfo.MAC
$Sheet.Cells.Item($intRow, 7) = $PrinterInfo.PingbyIP
$Sheet.Cells.Item($intRow, 8) = $PrinterInfo.PingbyPrinterName
$Sheet.Cells.Item($intRow, 9) = $PrinterInfo.Shared
$Sheet.Cells.Item($intRow, 10) = $PrinterInfo.ShareName
$Sheet.Cells.Item($intRow, 11) = $PrinterInfo.PortName
$Sheet.Cells.Item($intRow, 12) = $PrinterInfo.SNMPEnabled
$Sheet.Cells.Item($intRow, 13) = $PrinterInfo.SNMPCommunityString
$Sheet.Cells.Item($intRow, 14) = $PrinterInfo.PortNumber
$Sheet.Cells.Item($intRow, 15) = $PrinterInfo.PrinterStatus
#$Sheet.Cells.Item($intRow, 16) = "Removed"
$Sheet.Cells.Item($intRow, 16) = $PrinterInfo.PrinterModel
$Sheet.Cells.Item($intRow, 17) = $PrinterInfo.DriverName
$Sheet.Cells.Item($intRow, 18) = $PrinterInfo.DriverVersion
$Sheet.Cells.Item($intRow, 19) = $PrinterInfo.Driver
$Sheet.Cells.Item($intRow, 20) = $PrinterInfo.PageTotalCount
$Sheet.Cells.Item($intRow, 21) = $PrinterInfo.PageColorCount
$Sheet.Cells.Item($intRow, 22) = $PrinterInfo.PageBlackCount
$Sheet.Cells.Item($intRow, 23) = $PrinterInfo.PageDuplexCount
$Sheet.Cells.Item($intRow, 24) = $PrinterInfo.PageTotalCountAlt
$Sheet.Cells.Item($intRow, 25) = $PrinterInfo.PageCopyBlackCount
$Sheet.Cells.Item($intRow, 26) = $PrinterInfo.PageCopyColorCount
$script:intRow ++ #move to the next in excel
}
}
# Create new Excel workbook
$Excel = New-Object -ComObject Excel.Application
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbook
$Excel.Visible = $True
$Excel = $Excel.Workbooks.Add()
$Sheet = $Excel.Worksheets.Item(1)
$Sheet.Name = "Printer Inventory"
#======================================================
$Sheet.Cells.Item(1,1) = "Print Server"
$Sheet.Cells.Item(1,2) = "Printer Name"
$Sheet.Cells.Item(1,3) = "Location"
$Sheet.Cells.Item(1,4) = "Comment"
$Sheet.Cells.Item(1,5) = "IP Address"
$Sheet.Cells.Item(1,6) = "MAC"
$Sheet.Cells.Item(1,7) = "Ping by IP"
$Sheet.Cells.Item(1,8) = "Ping by Printer Name"
$Sheet.Cells.Item(1,9) = "Shared"
$Sheet.Cells.Item(1,10) = "Share Name"
$Sheet.Cells.Item(1,11) = "Port Name"
$Sheet.Cells.Item(1,12) = "SNMP Enabled"
$Sheet.Cells.Item(1,13) = "SNMP Community String"
$Sheet.Cells.Item(1,14) = "Port Number"
$Sheet.Cells.Item(1,15) = "Printer Status"
#$Sheet.Cells.Item(1,16) = "Printer State - Removed"
$Sheet.Cells.Item(1,16) = "Printer Model"
$Sheet.Cells.Item(1,17) = "Driver Name"
$Sheet.Cells.Item(1,18) = "Driver Version"
$Sheet.Cells.Item(1,19) = "Driver"
$Sheet.Cells.Item(1,20) = "Page Total Count"
$Sheet.Cells.Item(1,21) = "Page Color Count"
$Sheet.Cells.Item(1,22) = "Page Black Count"
$Sheet.Cells.Item(1,23) = "Page Duplex Count"
$Sheet.Cells.Item(1,24) = "Page Total Count Alt"
$Sheet.Cells.Item(1,25) = "Page Copy Black Count"
$Sheet.Cells.Item(1,26) = "Page Copy Color Count"
#=======================================================
$script:intRow = 2
$WorkBook = $Sheet.UsedRange
$WorkBook.Interior.ColorIndex = 40
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True
$PrintServerCounter = 0
#=======================================================
ForEach ($PrintServer in $PrintServers)
{
#####################################################################################################################################################
# Print Servers #
#####################################################################################################################################################
$PrintServerCounter++
Write-Progress -Activity "Processing Print Server:" -Status "Querying $($PrintServer) PRINTSERVER: $PrintServerCounter of $($PrintServers.Count)" -PercentComplete (($PrintServerCounter/$PrintServers.Count) * 100)
Write-Verbose "$(Get-Date): Working on $PrintServer..."
#$Script_Log.LogWrite("$(Get-Date): Working on $PrintServer...")
$Printers = Get-WmiObject Win32_Printer -ComputerName $PrintServer
Write-Host $Printer.name -ForegroundColor Green
$PrinterCounter = 0
ForEach ($Printer in $Printers)
{
#####################################################################################################################################################
# Printers #
#####################################################################################################################################################
$PrinterCounter++
Write-Progress -Activity "Processing Print Server:" -Status "Querying $($Printer.Name) on $PrintServer PRINTER: $PrinterCounter of $($Printers.Count)" -PercentComplete (($PrinterCounter/$Printers.Count) * 100)
Write-Verbose "$(Get-Date): Working on $Printer..."
#$Script_Log.LogWrite("$(Get-Date): Working on $Printer...")
#Write-Host $Printer.name -ForegroundColor Green
$runningjobs = if ( ((get-job | ? { $_.State -eq "running" }) -ne $null) )
{
if ( ((get-job | ? { $_.State -eq "running" }).Count -ne $null) )
{
(get-job | ? { $_.State -eq "running" }).Count
}
else
{0}
}
else
{0}
$completedjobs = (get-job -State Completed).count
while ( ($runningjobs -gt $ConcurrentJobProcess) -or ($completedjobs -gt $ConcurrentJobProcess) )
{
#do nothing
processCompletedJobs
$Excel = $Excel.SaveAs("$SaveAsPathFinal”,1)
#$Excel.SaveAs ($SaveAsPathFinal, $xlFixedFormat, AccessMode:=xlExclusive,ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges)
$completedjobs = (get-job -State Completed).count
$runningjobs = if ( ((get-job | ? { $_.State -eq "running" }) -ne $null) )
{
if ( ((get-job | ? { $_.State -eq "running" }).Count -ne $null) )
{
(get-job | ? { $_.State -eq "running" }).Count
}
else
{0}
}
else
{0}
}
if ($Printer.Name -notlike "Microsoft*")
{
Start-Job -ScriptBlock $PrintersInfo_Scriptblock -ArgumentList ($Printer.Name),$PrintServer -Name "$($PrintServer)_$($Printer.Name)"
get-job | FL
}
}
$WorkBook.EntireColumn.AutoFit() | Out-Null
}
#####################################################################################################################################################
# Completing Printer Information Gathering #
#####################################################################################################################################################
$runningjobs = if ( ((get-job | ? { $_.State -eq "running" }) -ne $null) )
{
if ( ((get-job | ? { $_.State -eq "running" }).Count -ne $null) )
{
(get-job | ? { $_.State -eq "running" }).Count
}
else
{0}
}
else
{0}
while ($runningjobs -gt 0)
{
write-progress -Activity "Completing Printer Information Gathering" `
-Status "Progress: $($runningjobs) to be COMPLETED" `
-PercentComplete (((get-job).count-$runningjobs)/(get-job).count*100)
processCompletedJobs
$Excel = $Excel.SaveAs("$SaveAsPathFinal”,1)
$runningjobs = if ( ((get-job | ? { $_.State -eq "running" }) -ne $null) )
{
if ( ((get-job | ? { $_.State -eq "running" }).Count -ne $null) )
{
(get-job | ? { $_.State -eq "running" }).Count
}
else
{0}
}
else
{0}
}
$intRow ++
$Sheet.Cells.Item($intRow,1) = "Printer inventory completed"
$Sheet.Cells.Item($intRow,1).Font.Bold = $True
$Sheet.Cells.Item($intRow,1).Interior.ColorIndex = 40
$Sheet.Cells.Item($intRow,2).Interior.ColorIndex = 40
Write-Verbose "$(Get-Date): Completed!"
$Excel = $Excel.SaveAs("$SaveAsPathFinal”,1)
$Excel = $Excel.Saved = $True
if ($CloseReportFile)
{
$Excel.Close()
}

How to export printer information from a server to text file [duplicate]

This question already has answers here:
PowerShell select range of cells from Excel file and convert to CSV
(2 answers)
Closed 2 years ago.
Quick description of what I am looking for.
We have customers that run our software and on the server there are anywhere up to 80 Zebra QLN420 printers all assigned Static IP Addresses. Looking for a script that will export needed printers information should we when we have to upgrade their existing services. I have found a powershell script that work wonderful that exports to csv file. The issue is that Excel isn't install on any of the customers servers.
So what I am looking to do is export instead to a text file using a comma between each field. I am not a powershell coder by any means.
I also found prnport.vbs on Windows that will display most of the information I need in Port Name, Hostaddress, port number but doesn't return the PrinterName.
Here is the powershell that exports to Excel.
Param (
string]$Printservers = "myServer"
)
# Create new Excel workbook
cls
$Excel = New-Object -ComObject Excel.Application
#==========$Excel.Visible = $True
$Excel = $Excel.Workbooks.Add("C:\Makeports\Something.xls")
$Sheet = $Excel.Worksheets.Item(1)
$Sheet.Name = "Printer Inventory"
#======================================================
$Sheet.Cells.Item(1,1) = "Print Server"
$Sheet.Cells.Item(1,2) = "Printer Name"
$Sheet.Cells.Item(1,3) = "Location"
$Sheet.Cells.Item(1,4) = "Comment"
$Sheet.Cells.Item(1,5) = "IP Address"
$Sheet.Cells.Item(1,6) = "Driver Name"
$Sheet.Cells.Item(1,7) = "Driver Version"
$Sheet.Cells.Item(1,8) = "Driver"
$Sheet.Cells.Item(1,9) = "Shared"
$Sheet.Cells.Item(1,10) = "Share Name"
#=======================================================
$intRow = 2
$WorkBook = $Sheet.UsedRange
$WorkBook.Interior.ColorIndex = 40
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True
#=======================================================
# Get printer information
ForEach ($Printserver in $Printservers)
{ $Printers = Get-WmiObject Win32_Printer -ComputerName $Printserver
ForEach ($Printer in $Printers)
{
if ($Printer.Name -notlike "Microsoft XPS*")
{
$Sheet.Cells.Item($intRow, 1) = $Printserver
$Sheet.Cells.Item($intRow, 2) = $Printer.Name
$Sheet.Cells.Item($intRow, 3) = $Printer.Location
$Sheet.Cells.Item($intRow, 4) = $Printer.Comment
If ($Printer.PortName -notlike "*\*")
{ $Ports = Get-WmiObject Win32_TcpIpPrinterPort -Filter "name = '$($Printer.Portname)'" -ComputerName $Printserver
ForEach ($Port in $Ports)
{
$Sheet.Cells.Item($intRow, 5) = $Port.HostAddress
}
}
####################
$Drivers = Get-WmiObject Win32_PrinterDriver -Filter "__path like '%$($Printer.DriverName)%'" -ComputerName $Printserver
ForEach ($Driver in $Drivers)
{
$Drive = $Driver.DriverPath.Substring(0,1)
$Sheet.Cells.Item($intRow, 7) = (Get-ItemProperty ($Driver.DriverPath.Replace("$Drive`:","\\$PrintServer\$Drive`$"))).VersionInfo.ProductVersion
$Sheet.Cells.Item($intRow,8) = Split-Path $Driver.DriverPath -Leaf
}
####################
$Sheet.Cells.Item($intRow, 6) = $Printer.DriverName
$Sheet.Cells.Item($intRow, 9) = $Printer.Shared
$Sheet.Cells.Item($intRow, 10) = $Printer.ShareName
$intRow ++
}
}
$WorkBook.EntireColumn.AutoFit() | Out-Null
}
$intRow ++
$Sheet.Cells.Item($intRow,1) = "Printer inventory completed"
$Sheet.Cells.Item($intRow,1).Font.Bold = $True
$Sheet.Cells.Item($intRow,1).Interior.ColorIndex = 40
$Sheet.Cells.Item($intRow,2).Interior.ColorIndex =
Any help to export it to a comma delimited file?
Here is how I got what I was looking for.
$Printservers = "myServer"
$OutPutFile = (Get-Location).Path + "\allprinters8.dat"
New-Item $OutPutFile -ItemType file
$writer = [System.IO.Streamwriter] $OutputFile
$Text = 'Print Server,Printer Name,Ip Address,Driver Name'
$writer.writeline($Text)
ForEach ($Printserver in $Printservers)
{ $Printers = Get-WmiObject Win32_Printer -ComputerName $Printserver
ForEach ($Printer in $Printers)
{
if ($Printer.Name -notlike "Microsoft XPS*")
{
$Text = $PrintServer + "," + $Printer.Name
If ($Printer.PortName -notlike "*\*")
{ $Ports = Get-WmiObject Win32_TcpIpPrinterPort -Filter "name = '$($Printer.Portname)'" -ComputerName $Printserver
ForEach ($Port in $Ports)
{
$Text =$Text +"," + $Port.HostAddress + "," + $Printer.driverName
$writer.writeline($Text)
}
}
}
}
}
$writer.close()

Error append line to excel file with powershell

I am getting error-messages, if i am running this code. I want to read users active directory data such as username, name, mail and append these informations to an xlsx file for license-tracking and ordering.
$user = Read-Host "Username"
$data = Get-ADUser -Identity $user -Properties * | select SamAccountName,AdminDisplayName,EmailAddress
$user = $data.SamAccountName
$name = $data.AdminDisplayName
$mail = $data.EmailAddress
$clo = Read-Host "Alter Computername (Nur bei Übertrag)"
$cln = Read-Host "Neuer Computername"
if ($clo -ne '') {
$out = "Übertrag: $($user), $($name), $($mail), Alter PC: $($clo), neuer PC: $($cln)"
}else {
$kst = Read-Host "Kostenstelle"
$out = "$($user), $($name), $($mail), PC: $($cln), KST: $kst"}
$excel_file_path = '"##PATHTOFILE#CENSORED#\test.xlsx"'
## Instantiate the COM object
$Excel = New-Object -ComObject Excel.Application
$ExcelWorkBook = $Excel.Workbooks.Open($excel_file_path)
$ExcelWorkSheet = $Excel.WorkSheets.item("Tabelle1")
$ExcelWorkSheet.activate()
## Find the first row where the first 7 columns are empty
$row = ($ExcelWorkSheet.UsedRange.Rows | ? { ($_.Value2 | ? {$_ -eq $null}).Count -eq 7 } | select -first 1).Row
$ExcelWorkSheet.Cells.Item($row,1) = 'COLUMN 1 Text'
$ExcelWorkSheet.Cells.Item($row,2) = 'COLUMN 2 Text'
$ExcelWorkSheet.Cells.Item($row,3) = 'COLUMN 3 Text'
$ExcelWorkSheet.Cells.Item($row,4) = "$out"
$ExcelWorkSheet.Cells.Item($row,5) = 'COLUMN 5 Text'
$ExcelWorkBook.Save()
$ExcelWorkBook.Close()
$Excel.Quit(
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel))
Stop-Process -Name EXCEL -Force
The following instruction does not return any value for $row for me:
$row = ($ExcelWorkSheet.UsedRange.Rows | ? { ($_.Value2 | ? {$_ -eq $null}).Count -eq 7 } | select -first 1).Row
I tried to browse the worksheet until a row where the first 7 columns are empty is found, using a loop. It seems to be working.
$lastrow = $ExcelWorkSheet.UsedRange.Rows.Count
for ($row = 1; $row -le $lastrow; $row ++) {
$test = $true
foreach ($col in 1..7) {$test = $test -and ($ExcelWorkSheet.Cells.Item($row,$col).Value2 -eq $null)}
if ($test) {break}
}

Loop through and replace backslash in filename (string)

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('\', '_')
}

PowerShell: Change 2 specific string into .ini

I'm searching to replace 2 occurrences of a specific string but each by one data different.
Here the file with 2 lines :
[SERVER1]
NAME = SERVER1\SQLEXPRESS
ODBCLINK = idms
USER = idms
PSW = idms
[SERVER2]
NAME = SERVER2\SQLEXPRESS
ODBCLINK = backupidms
USER = idms
PSW = idms
For the moment I have that code:
Get-Content ".\test.ini") | ForEach-Object { $_ -replace ".+\SQLEXPRESS" , "Name = $hostname\SQLEXPRESS" } | Set-Content ".\test.ini"
The goal is to have that :
[SERVER1]
NAME = Paris\SQLEXPRESS
ODBCLINK = idms
USER = idms
PSW = idms
[SERVER2]
NAME = Nantes\SQLEXPRESS
ODBCLINK = backupidms
USER = idms
PSW = idms
I read these 2 strings, Paris and Nantes, from another file.
Test1 and TEst2 can be ALieoej and PAodj45p. it's arbitrary choice
I think i need a script to search one line with sqlexpress into, and change it by one data, and the second time where i find it, replace it by another data
Seems like this may be what you are looking for. This will CREATE the test.ini file instead of editing it as you asked.
Set-Content -Value "Test1
Test2" -Path computers.txt
(Get-Content ".\computers.txt") | ForEach-Object {"Name = $_\SQLEXPRESS" } | Set-Content ".\test.ini"
Where computers.txt is your source of computers that have SQL Express instances.
Hi i found myself a solution :
rm $fichierDest
$content = get-content $fichierSource
$i = 0
while($i -lt $content.Length - 1)
{
$line = $content[$i]
$line2 = $content[$i+1]
if($line -match "SERVER1")
{
$line2 = $line2 -Replace ".+\SQLEXPRESS" , "Name = TEST1\SQLEXPRESS"
add-content $fichierDest $line
add-content $fichierDest $line2
$i += 2
}
elseif($line -match "SERVER2")
{
$line2 = $line2 -Replace ".+\SQLEXPRESS" , "Name = TEST2\SQLEXPRESS"
add-content $fichierDest $line
add-content $fichierDest $line2
$i += 2
}
else
{
add-content $fichierDest $line
$i++
}
}

Resources