PowerShell how to open multiple instances of Excel - excel

My script is opened an Excel sheet from SPO and after the reading from the file and then I closing it.
The issue is when I run this script from 2 instances of PS (Ctrl + T)
While the first script is running all good but when the second script running I get a pop up message that the file is already opened
This is the script that read from the excel
Connect-PnPOnline -Url $SharePointSiteURL
$ExcelObject = New-Object -ComObject Excel.Application
$ExcelWorkBook = $ExcelObject.Workbooks.Open($SharePointSiteURL)
$ExcelWorkSheet = $ExcelWorkBook.Sheets.Item("VIP List")
QuitExcel
function QuitExcel {
# when done, quit Excel and remove the used COM objects from memory (important)
$ExcelWorkBook.Close()
$ExcelObject.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelWorkSheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelWorkBook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelObject)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
Disconnect-PnPOnline

While First script is accessing xls, definitely the second script which is accessing the same xls would cause an issue because it is in use. Alternate is to make a copy of the same xls on runtime and use it.

Related

Powershell Run Excel Macros

hello im trying to open an excel document then open an excel Macro Document, then have powershell run the specific macro that i want and let the macro do its magic and call it a day.
the script i have is this:
# start Excel
$excel = New-Object -comobject Excel.Application
#open file
$FilePath = 'C:\Users\Username\Desktop\ExcelWorkbook.xlsm'
$workbook = $excel.Workbooks.Open($FilePath)
#make it visible (just to check what is happening)
$excel.Visible = $true
#access the Application object and run a macro
$app = $excel.Application
$app.Run("Macro")
$excel.Quit()
#Popup box to show completion - you would remove this if using task scheduler
$wshell = New-Object -ComObject Wscript.Shell $wshell.Popup("Operation Completed",0,"Done",0x1)
So my issue is im getting the error "all macros may be disabled"
what code do i use to make them enabled, i'm having issues with that.
$app it's not defined, so try to replace $app.Run("Macro") with $Excel.Run("Macro")

Keeping the excel opened before it completely refreshed through powershell?

I am using this powershell script to open an excel, run a macro to refresh all, save and close.
This is working fine but the excel is saving and closing before refreshing the excel completely.
Is there a way i can add a wait statement so that it can wait until the workbook is completely refreshed.
$objectExcel = new-object -c excel.application
$objectExcel.displayAlerts = $false # don't prompt the user
$objectExcel.visible = $True;
#$objectExcel.visible = $True;
$Classeur = $objectExcel.workbooks.open("\\gbrmiteufs01.eu.xerox.net\SWG01\XOG-BORG\EBIP\POS Data\POS
Data.xlsm", $null, $false)
$objectExcel.run("Workbook_RefreshAll")
$objectExcel.run("RemoveODBC") # another custom macro for removing data connecion
$Classeur.save()
$Classeur.close()
$objectExcel.quit()

How do I prevent Excel from attempting to connect to its links when opening a file with links in Powershell?

I have a PS script that runs from the Task Scheduler. When a .xlsm file is added to a watched folder it opens this file and gathers specific data from it, then outputs it to a CSV. The problem I've been having recently is with XLSM files that have links to an external SharePoint site. Any time these files are opened with the script it just hangs. If I try to open the file manually Excel first asks me to "Enable Content", then once I click to enable a prompt to input my credentials to connect to the SharePoint site associated with the link.
I can confirm after breaking the link and then running the script that the problem is resolved, so it is definitely this link that is hanging the script up. I've tried looking into methods to break the link before opening the file, but I was not able to gather much. All the resources I could find were in references to updating links via Powershell, not breaking them.
Here are the pieces of my code related to opening the file:
$watchedfolder = "C:\Watched"
$filedirectory = Get-ChildItem $watchedfolder | Where-Object {($_.Extension -eq ".xlsm")} | Select-Object -ExpandProperty Name
foreach ($file in $filedirectory){
$sheetName = "Daily Dash"
#OPEN EXCEL WORKBOOK
$objExcel = New-Object -ComObject Excel.Application
$workbook = $objExcel.Workbooks.Open("C:\Watched\$file")
$sheet = $workbook.Worksheets.Item($sheetName)
$objExcel.Visible = $false
$objExcel.DisplayAlerts = $false
$rowMax = ($sheet.UsedRange.Rows).count
I am unsure of what I can add to this opening portion of my script that will prevent the attempt to connect to the SharePoint site. Any recommendations?
I cannot test this at the moment, but you need to do the settings for the Excel object before opening the file.
Setting the AskToUpdateLinks property to $false should do what you ask for.
#OPEN EXCEL WORKBOOK
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $false
$objExcel.DisplayAlerts = $false
$objExcel.AskToUpdateLinks = $false
$workbook = $objExcel.Workbooks.Open("C:\Watched\$file")
$sheet = $workbook.Worksheets.Item($sheetName)
$rowMax = ($sheet.UsedRange.Rows).count

How to open CSV in Excel using Powershell while supplying a list seperator

Hi I'm using a simple Powershell script to convert CSV files to XLSX files. However Excel ignores the list seperator and puts all data in the first column.
The list seperator is configured correctly (Start > Control Panel > Regional and Language Options -> Additional Settings)
Manually opening the files from Windows Explorer works fine.
However, when opening the CSV in Excel using:
Function Convert-toExcel {
$xl = new-object -comobject excel.application
$xl.visible = $true
$Workbook = $xl.workbooks.OpenText("$csvfile")
$Worksheets = $Workbooks.worksheets
}
Everything is put into the first column...
Accoriding to Powershell the list seperator is configured correctly:
(Get-Culture).textinfo
ListSeparator : ,
Try adding the DataType argument to the OpenText method. It appears to take magic arguments.
VBA:
Workbooks.OpenText filename:="DATA.TXT", dataType:=xlDelimited, tab:=True
I would guess in powershell it accepts a hash, so:
$xl.Workbooks.OpenText(#{Filename = $CSVFile; dataTyype = "xlDelimited", other = $true; otherchar=':' })
However, I've no way to test this currently.
The following script works for me. The one change in functionality I made was that I set Excel.visible to false.
Function Export-CSVToXLS {
Param(
[String]$CsvFileLocation
,[String]$ExcelFilePath
)
If (Test-Path $ExcelFilePath )
{
Remove-Item -Path $ExcelFilePath
}
$FixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
$Excel = New-Object -ComObject excel.application
$Excel.visible = $false
$Excel.Workbooks.OpenText($CsvFileLocation)
$Excel.ActiveWorkbook.SaveAs($ExcelFilePath,$FixedFormat)
$Excel.Quit()
Remove-Variable -Name Excel
[gc]::collect()
[gc]::WaitForPendingFinalizers()
}
Export-CSVToXLS -CsvFileLocation "C:\Temp\CSV.csv" -ExcelFilePath "C:\Temp\XLS.xlsx"
I compiled this based off of information on the following webpages:
http://blogs.technet.com/b/heyscriptingguy/archive/2010/09/09/copy-csv-columns-to-an-excel-spreadsheet-by-using-powershell.aspx
https://social.technet.microsoft.com/Forums/en-US/919459dc-3bce-4242-bf6b-fdf37de9ae18/powershell-will-not-save-excel-file?forum=winserverpowershell
Your original code works fine. My guess is your delimiter in excel just isn't a ",". I've seen this go wrong loads of time. The ps culture has nothing to do with it
Use `t (Powershell code for the tab character) instead of , (a comma).
Excel defaults at opening to using text to columns import with tab as the separator.

Macros missing when opening Excel file with PowerShell

The purpose of the PowerShell script I am trying to write is - Open an excel document and run a macro. (The macro is stored in the Personal Workbook file - personal.xlsb and it runs successfully)
The problem -
When the excel file is opened via PowerShell code, it opens fine but when the macro is run by calling Run("NameOfMacro"), I get an error stating macro not found. I try to find the macro in the opened excel file and it does not appear in the macro list. This seems to be because the personal.xlsb file is not loading.
So I close the excel file, open it manually, but the macro is still missing. I then manually open the personal.xlsb file and notice that the macro exists however the macro still does not appear in the excel file or any other excel file I open thereafter.
After a frustrating hour trying to understand why is the personal.xlsb file stopped loading suddenly. I noticed another thing - if I kill the excel.exe process that was started by the PowerShell code (via task manager window) and then open any excel document the macro is available!!
So I have narrowed down the issue to this - The macros are not available because the Personal.xlsb is NOT opened/loaded WHEN I open excel file via PowerShell.
Does anyone have an idea why is this happening and what do I need to do to resolve this?
Code reference
$excel = New-Object -comobject Excel.Application
$FilePath = "D:\DailyReport.xls"
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $true
$worksheet = $workbook.worksheets.item(1)
$excel.Run("SelectDataFromReport")
Error I get -
Exception calling "Run" with "31" argument(s): "Cannot run the macro 'SelectDataFromReport'. The macro may not be available in this workbook or all macro
s may be disabled."
At line:18 char:11
+ $excel.Run <<<< ("SelectDataFromReport")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
By the way, I use the 64 bit PowerShell console by default but I also tried running the code using 32 bit console but it didn't make a difference.
In excel I have added the location as a trusted location and i have allowed excel files to be opened by default in edit mode.
you can call the macro within the personal.xlsb like so:
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open("$env:USERPROFILE\Application Data\Microsoft\Excel\XLSTART\PERSONAL.XLSB")
$FilePath = "D:\DailyReport.xls"
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $true
$worksheet = $workbook.worksheets.item(1)
$excel.Run("PERSONAL.XLSB!SelectDataFromReport")
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
$x1 = New-Object -comobject Excel.Application
$wb = $x1.workbooks.open("$env:C:\teste\testamacro.xlsm")
$FilePath = "c:\teste\testamacro"
$workbook = $x1.Workbooks.Open($FilePath)
$x1.Visible = $true
$worksheet = $workbook.worksheets.item(1)
$x1.Run("testamacro.xlsm!SelectDataFromReport")
$wb.Close() $workbook.save()`
$workbook.close()
$x1.quit()

Resources