Printing all Excel files in a folder using PowerShell - powershell

I have a PowerShell script that I wrote a few years ago and it worked great...until it didn't.
$shell = New-Object -com Shell.Application
$filepath = 'C:\Billing\Clients'
$shell.Namespace($filepath).Items() |
% { $_.InvokeVerb('Print') }
In the C:\Billing\Clients folder I copy ~100 Excel files. Each of these Excel files need to be printed, in the alphabetical order of the file name.
This was working great until this month. I guess an update to Excel changed things.
Now the script tries to open and print all of the Excel files at the same time. Previously it printed the files in serial.
This was awesome. Now it brings my system to it's knees and documents are printed in a random order.
Any ideas on how I can invoke the Print operation and wait for it to complete prior to calling the Print operation on the next file?

I have used this in the past to pull files into excel and print them. You will need to ensure your default print settings are set first or use $xl.ActivePrinter = "PRINTERNAME AS EXCEL SEES IT" to set it first.
#Open Excel
$xl = new-object -comobject excel.application
#don't show the window
$xl.visible = $false
#get all of your files
get-childitem "C:\SOME\Path" "*.xlsx" | foreach-object {
#open file
$wb = $xl.Workbooks.Open($_.FullName)
#print with defaults
$wb.PrintOut()
#close without saving any changes
$wb.Close($false)
}
#all done so close excel
$xl.Quit()

Related

Reading a text file line by line

I'm new to power shell and can't seem to get this script correct.
$WshShell = New-Object -comObject WScript.Shell
$users = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users.txt'
$users1 = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users1.txt'
$Shortcut = $WshShell.CreateShortcut("\\Fssrv\homeshares$\$users1\$users.lnk")
$Shortcut.TargetPath = "\\asrv1\users\$users"
$Shortcut.Save()
Every time it goes to "users.txt" it tries to read it as a complete file. Instead i would like for it to read as followed:
User1
User2
User3
I just can't seem to get this to work.
RE-EDIT:
What I’m trying to accomplish:
We went from one storage server to a new storage server.
ASRV1 to FSSRV
I want to create a shortcut from asrv1 to fssrv. Along with the upgrade we are also changing domains and changing everyone windows user names.
For example my user name was fMunoz and it was changed to fMunoz00.
I want to pull from a text file > users.txt with all the old usernames, and create shortcuts to the new user names storage file those users names are in a txt file called users1.txt.
If I understand your request, you want to create shortcuts in each home directory of the people in Users1.txt
This means you will need to complete multiple ForEach loops to cycle through both txt files.
$WshShell = New-Object -comObject WScript.Shell
$users = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users.txt'
$users1 = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users1.txt'
# For every line in $users1, Do something
Foreach($User in $users1) {
# For every line in $users, Do something
Foreach($Name in $users) {
$Shortcut = $WshShell.CreateShortcut("\\Fssrv\homeshares$\$User\$Name.lnk")
$Shortcut.TargetPath = "\\asrv1\users\$Name"
$Shortcut.Save()
}
}
I want to thank everyone for helping me.
I came up with a different solution for my problem. The way i fixed this issue was by creating an excel sheet w/ 2 columns.
OLD USERS | NEW USERS
I then created a mail merge using microsoft word. Then i continued with the following code in powershell to start my loop:
$WshShell = New-Object -comObject WScript.Shell
Once my loop was started with i then utilized mail merge to take <> from the excel sheet and replaced it with the insert it into my code. Also took <> and did the same.
$Shortcut = $WshShell.CreateShortcut("\Fssrv\homeshares$\«New_Users»\«Old_Users»_Z Drive.lnk")
$Shortcut.TargetPath = "\asrv1\users\«Old_Users»"
$Shortcut.Save()
I hope this can help anyone else trying to accomplish something similar.
Yet again, Thanks & Good Luck...

Edit powershell script to merge 2 docx into one PDF

i have found this script online. It converts docx files to pdf. The thing is, it creates one pdf for each docx. I need to edit this script, to merge 2 docx files into one single PDF file. I have zero knowledge of powershell, but i know batch in linux.
$documents_path = Split-Path -parent $MyInvocation.MyCommand.Path
$word_app = New-Object -ComObject Word.Application
Get-ChildItem -Path $documents_path -Filter *.doc? | ForEach-Object {
$document = $word_app.Documents.Open($_.FullName)
$pdf_filename = "$($_.DirectoryName)\$($_.BaseName).pdf"
$document.SaveAs([ref] $pdf_filename, [ref] 17)
$document.Close()
}
$word_app.Quit()
This is the design of the script you are using.
Use the more direct approach by merging the .docx files first, then convert to PDF. This means you have to understand the MSWord object model and how to code for it. You're going to have to pick a starting .docx the append other word data to the end.
So, do a search for how to merge Word files. Get that worked out, then you can just use PowerShell to make them .pdfs.
With zero knowledge of PowerShell, you should really take a few quick online training session to get an handle on it all, before you get yourself in a very frustrating position.
Go to the Microsoft Virtual Academy and YouTube and do a search for 'beginning PowerShell'

Count the excel rows using the folder path

I have one folder named customer , under that there are multiple folders based on each customer name and under each customer I have excel of sheets which contain information in row wise.
I would like to extract this file structure into excel containing file path and number of rows contained in each of the excel.
I could able to list file names using below procedure.
Press Win-E to open Windows Explorer and locate the folder for which you need a file list.
Hold the Shift key, right-click the folder and select Open Command Window Here. This only works with folders, not libraries.
Libraries point to a specific folder, so select the folder located
under the library icon. If the library points to a drive, right-click
the drive letter from the folder tree.
Type dir /b > dirlist.txt without quotes and press Enter. This creates a list containing file names only. To include file sizes and
dates, type dir > dirlist.txt instead. To also include files in
sub-directories, type dir /b /s > dirlist.txt to create a list of
files with the full directory structure name, such as
C:\folder\subdirectory\file.txt.
Open Microsoft Excel and press Ctrl-O to bring up the Open dialog window.
Navigate into the folder containing the files. Click the file type drop-down menu and select Text Files (.prn,.txt,*.cvs).
Double-click dirlist.txt to open it.
Click Finish in the Text Import Wizard window to use the default options and import the directory list into Excel.
Please help in counting the rows also.
Your question is ambigous. I removed unnecessary/wrong tags.
Excel files can have more than one sheet, so you have to iterate/recurse the files from given startfolder and also all sheets in the workbook. Output is a table with the asked properties. Should be easy to save as a csv.
$BaseFolder = "X:\Path\to\Customers"
$xlCellTypeLastCell = 11
$AllSheets = New-Object System.Collections.Generic.List[object]
$Excel = New-Object -com excel.application
$Excel.DisplayAlerts = "False"
$XLfiles = Get-ChildItem -Path $BaseFolder -Filter *.xls* -File -Recurse
ForEach ($XLfile in $XLfiles) {
$WorkBook = $Excel.workbooks.open($XLfile.FullName)
for ($i = 1; $i -le $WorkBook.sheets.count; $i++){
$Sheet = $WorkBook.Sheets.Item($i)
$LastRow = $Sheet.UsedRange.SpecialCells($xlCellTypeLastCell).Row
$Obj = [pscustomobject][ordered]#{
ExcelFPath= $XLfile.FullName
Customer = ($XLfile.Directory).Name
ExcelFile = $XLfile.Name
SheetNo = $i
RowCount = $LastRow
}
$AllSheets.add($obj)
}
$Excel.Workbooks.Close()
}
$AllSheets | Format-Table -auto
## $AllSheets | Out-Gridview

iTextSharp to merge PDF files in PowerShell

I have a folder which contains thousands of PDF files. I need to filter through these files based on file name (which will group these into 2 or more PDF's) and then merge these 2 more more PDF's into 1 PDF.
I'm OK with group the files but not sure the best way of then merging these into 1 PDF. I have researched iTextSharp but have been unable to get this to work in PowerShell.
Is iTextSharp the best way of doing this? Any help with the code for this would be much appreciated.
Many thanks
Paul
Have seen a few of these PowerShell-tagged questions that are also tagged with itextsharp, and always wondered why answers are given in .NET, which can be very confusing unless the person asking the question is proficient in PowerShell to begin with. Anyway, here's a simple working PowerShell script to get you started:
$workingDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path;
$pdfs = ls $workingDirectory -recurse | where {-not $_.PSIsContainer -and $_.Extension -imatch "^\.pdf$"};
[void] [System.Reflection.Assembly]::LoadFrom(
[System.IO.Path]::Combine($workingDirectory, 'itextsharp.dll')
);
$output = [System.IO.Path]::Combine($workingDirectory, 'output.pdf');
$fileStream = New-Object System.IO.FileStream($output, [System.IO.FileMode]::OpenOrCreate);
$document = New-Object iTextSharp.text.Document;
$pdfCopy = New-Object iTextSharp.text.pdf.PdfCopy($document, $fileStream);
$document.Open();
foreach ($pdf in $pdfs) {
$reader = New-Object iTextSharp.text.pdf.PdfReader($pdf.FullName);
$pdfCopy.AddDocument($reader);
$reader.Dispose();
}
$pdfCopy.Dispose();
$document.Dispose();
$fileStream.Dispose();
To test:
Create an empty directory.
Copy code above into a Powershell script file in the directory.
Copy the itextsharp.dll to the directory.
Put some PDF files in the directory.
Not sure how you intend to group filter the PDFs based on file name, or if that's your intention (couldn't tell if you meant just pick out PDFs by extension), but that shouldn't be too hard to add.
Good luck. :)

Make Excel Defined Names within a worksheet to be global

I wrote Powershell script to copy a worksheet from a workbook A to another workbook B. The worksheet contains define names for ranges within that sheet. Originally, the defined names are global in workbook A, ie. can be referenced from any worksheets within workbook A.
But now, after copy to worksheet B, the defined names are limited to that worksheet only. How to I programmatically (via Powershell script preferably) make all those named range global i.e. can be referenced from all worksheets within workbook B.
Some codes for clarity.
#Script to update SOP from 5.1 to 5.2
$missing = [System.Type]::missing
#Open files
$excel = New-Object -Com Excel.Application
$excel.Visible = $False
$excel.DisplayAlerts = $False
$newTemplate = "C:\WorkbookA.xls"
$wbTemplate = $excel.Workbooks.Open($newTemplate)
$oldSop = "C:\WorkbookB.xls"
$wbOldSop = $excel.Workbooks.Open($oldSop)
#Delete 'DATA' worksheet from old file
$wsOldData = $wbOldSop.Worksheets.Item("DATA")
$wsOldData.Delete()
#Copy new 'DATA' worksheet to old file
$wbTemplate.Worksheets.Item("DATA").Copy($missing,$wbOldSop.Worksheets.Item("STATUS"))
#Save
$wbOldSop.Save()
$wbOldSop.Close()
#Quit Excel
$excel.Quit()
I have this problem when copying worksheets with named ranges on them from directly in excel itself. I had this problem just last week. I couldn't find out why, and I suspect PowerShell really doesn't have anything to do about it. My only recourse seemed to be to drop and recreate the named ranges on the secondary sheets.