I'm trying to get a solution to select specific Excel Add-ins with a script.
I was able to catch all the information about Excel.Application and change "Installed" property to $true, but it comes back to $false when the code stops running. Anybody knows a different solution or a way to save the Excel property?
$excel = New-Object -ComObject Excel.Application
$excel.Addins | Where-Object { $_.Title -eq "NameOfAdd-ins" } | ForEach-Object {
$_.Installed = $true
}
$_.Installed property should stay $true after Run-Time
Related
I have the below code that opens a spreadsheet, deletes all connections and "Saves" a new file.
$a = New-Object -COM "Excel.Application"
$a.Visible = $false
$b = $a.Workbooks.Open("F:\Scripts\All Users.xlsx")
do
{
$b.Connections.Item(1).Delete()
$Count = $b.Connections.Count()
} until($Count -eq 0)
$b.SaveAs("F:\Scripts\Users Home Drive Search.xlsx")
$b.Close()
I would like to know two things:
How do I get the sheet to RefreshAll connections? I've tried "$b.Connections.refreshall()" but the refreshall() doesn't exist.
How do I quit Excel application? I ran "New-Object -COM "Excel.Application" | Get-Member -MemberType Methods" and I don't see a quit or exit method.
RefreshAll() is a method of the WorkBook object, so use that to refresh the external connections:
$b.RefreshAll()
To exit Excel and remove the used COM objects from memory, use
$a.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($b)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($a)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
BTW, I would use more descriptive variable names, so $excel instead of $a and $workbook instead of $b to avoid confusion later on.
I have an Excel that is using Power Query to get data from a API. What I would like to do is have this data update every day without having to open the excel myself. So I enabled the setting within excel to Refresh data when opening the file.
So I am trying to create a PowerShell script which open the excel, waits for the query to refresh, and then saves the excel. However I cant get it to wait update the query has refreshed before saving and closing.
code:
$Excel = New-Object -COM "Excel.Application"
$Excel.Visible = $true
$Workbook = $Excel.Workbooks.Open("G:\...\jmp-main-2020-07-17.xlsx")
While (($Workbook.Sheets | ForEach-Object {$_.QueryTables | ForEach-Object {if($_.QueryTable.Refreshing){$true}}}))
{
Start-Sleep -Seconds 1
}
$Excel.Save()
$Excel.Close()
I think your while loop is wrong. You should probably loop over the worksheets in the workbook and for each of them loop over the QueryTables. Then enter a while loop to wait until the Refreshing property turns $false
foreach ($sheet in $Workbook.Sheets) {
$sheet.QueryTables | ForEach-Object {
while ($_.QueryTable.Refreshing) {
Start-Sleep -Seconds 1
}
}
}
As aside: you should clear the COM object you have created after finishing with them to free memory:
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
I am using Windows Task Scheduler to open Excel file and VBA inside that Excel file to close it after data is refreshed.
No PowerShell script needed.
I was able to get #Theo's example working with some small tweaks. Not sure why but the QueryTables property did not have my collection of queries for the sheet however using the ListObjects property did.
$file = "path\to\file.xlsx"
$Excel = New-Object -COM "Excel.Application"
$Excel.Visible = $false
$Workbook = $Excel.Workbooks.Open($file)
foreach ($sheet in ($Workbook.Sheets)) {
$sheet.ListObjects | ForEach-Object{$_.QueryTable.Refresh() | out-null}
$sheet.ListObjects | ForEach-Object{
while ($_.QueryTable.Refreshing) {
Start-Sleep -Seconds 1
}
}
}
And to properly save and exit out of the excel you would use
$Workbook.Save()
$Workbook.Close()
$Excel.Quit()
I'm rather new with PowerShell scripting so please be patient with me :)
I have multiple excel file with OLAP Query connections connecting to Power BI Datasets, following are the script;
$libraryPath = "C:\Repos\AUSD\3.0\Test"
$excel = new-object -comobject Excel.Application
$excel.Visible = $false
# Give delay to open
Start-Sleep -s 3
$allExcelfiles = Get-ChildItem $libraryPath -recurse -include “*.xls*”
foreach ($file in $allExcelfiles)
{
$workbookpath = $file.fullname
Write-Host "Updating " $workbookpath
# Open the Excel file
$excelworkbook = $excel.workbooks.Open($workbookpath)
$connections = $excelworkbook.Connections
# This will Refresh All the pivot tables data.
$excelworkbook.RefreshAll()
# The following script lines will Save the file.
$excelworkbook.Save()
$excelworkbook.Close()
Write-Host "Update Complete " $workbookpath
}
$excel.quit()
It is working fine if following options;
$excel.Visible is true
However this is going to be scheduled in the server and hopefully this could be done in the background, hence the $excel.Visible = $false
This causing the following error;
I suspect this is due to the Automatic sign in which happen when the Excel are open, due to its not being open, its failing the sign in process.
How do I bypass or rather set the credentials/permission right?
I have a bunch of Excel files each of which has a number of Workbook Connections. Each of these workbook connections has a properties with a Definition, which contains a "Connection String" and also a "Command text"
I would like to retrieve the connection string and command text values through PowerShell but cannot see the function to do this
I have got as far as the following snippet, any advice appreciated...
$excelObj = New-Object -ComObject Excel.Application
$excelObj.Visible = $false
$workbook = $excelObj.Workbooks.Open($xlsxLocation)
foreach ($connect in $workbook.Connections)
{
Write-Host $connect.Name
# This is where I need the connection string and the command text, for this connection.
}
I ran a search for "vba connections command text" which returned Extracting Excel Data Connection Command Text. Then I was able to adapt your code to:
$xlsxLocation="C:\Temp\MyFile.xlsx"
$excelObj = New-Object -ComObject Excel.Application
$excelObj.Visible = $False
$excelObj.DisplayAlerts = $False
$workbook = $excelObj.Workbooks.Open($xlsxLocation)
foreach ($worksheet in $workbook.Worksheets){
foreach ($listobject in $worksheet.ListObjects) {
$commandtext = $listobject.QueryTable.CommandText
if (-not ([string]::IsNullOrWhiteSpace($commandtext))) {
Write-Host $commandtext
}
}
}
$workbook.Close($False) # closed do not save
$excelObj.DisplayAlerts = $True
$excelObj.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelObj) | Out-Null
Remove-Variable excelObj | Out-Null
The last two lines of code will dispose the Excel resourse when you terminate the script.
I started messing around with Excel on PowerShell, specially because I had to go through 138 files changing every instance of $B$1 to TEXT($B$1,"0000") and I didn't want to do that manually.
Found a couple of resources online and changed the formula but when I try .Save(), PowerShell seems to just sit there, waiting for something I have no idea what.
PS C:\> $excel = New-Object -com Excel.Application
PS C:\> Get-ChildItem '\\UNC\Path\to\folder' <Common file string>*.xls -Recurse | Select-Object -First 1 | % {
>> $workbook = $excel.Workbooks.Open($_.Fullname)
>> $workbook.Save()
>> }
Any ideas on what could be the problem?
When Excel hangs in this regard I would suspect it is waiting for you to do something. The easiest was to confirm this is setting the visibility to True.
$excel.Visible = $true
That would just show you the dialog that was hidden from you previously. As discussed in comments it appears you got a message from the Compatibly Checker. Once you know what it is and are willing to suppress it then just have the following
$excel.Visible = $false
$excel.displayAlerts = $false