"Unable to get the Open property of the Workbooks class" when automated - excel

I have some PowerShell scripts that invoke SQL commands, take the results and put them into a CSV file, then the CSV file is put into an excel workbook and it's emailed out to a distribution list. I had no issues running these reports through Windows Scheduled tasks on my older Windows 2008 server running SQL 2008. But I have migrated over to Windows 2016 running SQL 2016. Now when I run this process through Scheduled tasks I get the following error:
Unable to get the Open property of the Workbooks class
At C:\PowerShell\scrpits\ArtiReport3.ps1:607 char:1
+ $workbook = $excel.Workbooks.Open($csvFilePath)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
If I run the PowerShell script manually I have no issues and everything runs fine. I'm using the same login to run the scripts manually as I do through scheduled tasks. Here is the script.
$query = "*SQL Query runs here*"
#Edit these peramters for the server this will be running on#
$smtpServer = "*server*";
$smtpFrom = "I3Reports#server.com";
$smtpTo = "*email list here*”
$messageSubject = "I3 Report";
#create anonymus loging for sending e-mail#
$User = "anonymous";
$PWord = ConvertTo-SecureString -String "anonymous" -AsPlainText -Force
$Creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user, $pword
$date = (Get-Date).AddDays(-1).ToString('yyyy-MM-dd')
$date = $date+"_I3Report.xls";
$csvFilePath = "c:\Scripts\queryresults.csv"
$excelFilePath = "c:\scripts\$date"
$instanceName = "*server*"
Import-Module "sqlps"
$results = Invoke-Sqlcmd -QueryTimeout 7200 -Query $query -ServerInstance $instanceName
# Output to CSV
$results | export-csv $csvFilePath -Delimiter " " -NoTypeInformation
#this line will remove all the quotation marks from the csv file
(Get-Content $csvFilePath) | % {$_ -replace '"', ""} | out-file -FilePath $csvFilePath -Force
# Convert CSV file to Excel
$excel = New-Object -ComObject excel.application
$excel.visible = $False
$excel.displayalerts=$False
$workbook = $excel.Workbooks.Open($csvFilePath) #<-- Program fails here
$workSheet = $workbook.worksheets.Item(1)
#$workSheet.cells.item(3,3) = "HOPLA"
#for freezing pane#
$workSheet.application.activewindow.splitcolumn = 0
$workSheet.application.activewindow.splitrow = 1
$workSheet.Range("A2").application.activewindow.freezepanes = $true
$resize = $workSheet.UsedRange
$resize.EntireColumn.AutoFit() | Out-Null
$xlExcel8 = 43
$workbook.SaveAs($excelFilePath, $xlExcel8)
$workbook.Close()
$excel.quit()
$excel = $null
send-mailmessage -from $smtpFrom -to $smtpTo -subject "$messageSubject" -body "Attachment" -Attachments $excelFilePath -smtpServer $smtpServer -Credential $creds;
As mentioned this works when I run it in PowerShell manually, but through scheduled tasks it gets that error and it references the section I noted in the code. I've been working on this for days and I can't seem to figure out what is causing the issue. Any help or suggestions is welcomed. Thanks for taking the time.

I found the solution to this problem here
Powershell Excel Automation - Save/Open fails in Scheduled Task
Creating the folders and gaining access to the directories that they are in did it for me.

Related

I cant get powershell to run in task scheduler

I am trying to run the following Powershell script via the Task Scheduler but although it gives me a successful run (0x0), nothing happens. If I run the script manually from the same machine as a standard user the script executes without any issue.
$folderpath = "\\shared_path\excel.xls"
Add-Type -AssemblyName Microsoft.Office.Interop.Excel
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbook
write-host $xlFixedFormat
$excel = New-Object -ComObject excel.application
$excel.visible = $false
$filetype ="*xls"
Get-ChildItem -Path $folderpath -Include $filetype -recurse |
ForEach-Object `
{
$path = ($_.fullname).substring(0, ($_.FullName).lastindexOf("."))
$workbook = $excel.workbooks.open($_.fullname)
$path += ".xlsx"
$excel.DisplayAlerts = $false;
$workbook.saveas($path, $xlFixedFormat)
$workbook.close()
}
$excel.Quit()
$excel = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
Just to clarify, I have tried different options in task scheduler such as running it under arguments like "-WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -File "C:\Temp\powershell.ps1" or SYSTEM and currently logged on user but nothing made a difference.
My system is a domain joined Windows 10 with unrestricted access to the shared location (Everyone access)
Any ideas?
I usually configure Task Scheduler to run a PowerShell script with the following settings:
New Action
Action: "Start a program".
Program/script: "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
Add arguments (optional): .\ScriptName.ps1 -Arg1 Value1
Start in (optional): Path\to\Script\Directory

How to convert Excel xlsx file to xls file in batch by PowerShell

I am having multiple .xlsx file genrated from SAP BO4.2
But user reads .xls only so wanted to write some script which will convert .xlsx to .xls
Referred-
https://gallery.technet.microsoft.com/How-to-convert-Excel-xlsx-d9521619
and tried to use same for .xls
$ErrorActionPreference = 'Stop'
Function Convert-xlsInBatch
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][String]$Folder
)
$ExcelFiles = Get-ChildItem -Path $Folder -Filter *.xlsx -Recurse
$excelApp = New-Object -ComObject Excel.Application
$excelApp.DisplayAlerts = $false
$ExcelFiles | ForEach-Object {
$workbook = $excelApp.Workbooks.Open($_.FullName)
$xlsFilePath = $_.FullName -replace "\.xlsx$", ".xls"
$workbook.SaveAs($xlsFilePath, [Microsoft.Office.Interop.Excel.XlFileFormat]::xlExcel7)
$workbook.Close()
}
# Release Excel Com Object resource
$excelApp.Workbooks.Close()
$excelApp.Visible = $true
Start-Sleep 5
$excelApp.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelApp) | Out-Null
}
#
# 0. Prepare the folder path which contains all excel files
$FolderPath = "D:\XXX\AA\BB\Apr-2018"
Convert-XlsInBatch -Folder $FolderPath
Error I am getting-
PS D:\Batch Script> D:\Batch Script\ConvertExcelToXlsInBatch.ps1
New-Object : Retrieving the COM class factory for component with CLSID {00000000-0000-0000-0000-000000000000} failed
due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
At D:\Batch Script\ConvertExcelToXlsInBatch.ps1:27 char:14
+ $excelApp = New-Object -ComObject Excel.Application
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
+ FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand
Not sure if you've seen this solution. It's 4 years old but it seems to work.
https://superuser.com/questions/875831/using-powershell-is-it-possible-to-convert-an-xlsx-file-to-xls

Excel spawned from powershell script not quitting [duplicate]

This question already has answers here:
Excel, save and close after run
(6 answers)
Closed 4 years ago.
We're migrating databases so I'm using powershell to modify the hundreds of excel files that reference to old DB instance to the new one. This is all fine and works as intended. The problem I have is that the Excel application will not exit when I'm done. The process will just hang around as a background process and I need to go into task manager to kill it. Not a huge deal but it is annoying. Here is my script. I'm on powershell v5 and Office 2016.
param(
[string]$search_root=$(throw "missing search root parameter"),
[boolean]$test=$true
)
echo $search_root
$NAMEPOSTFIX = '-Updated'
$OLDCONN = 'Data Source=abc;'
$NEWCONN = 'Data Source=xyz;'
$filelist = Get-ChildItem -Path $search_root *.xls* -Recurse -Exclude '*Updated.*'
$Excel = New-Object -Com Excel.Application
$Excel.DisplayAlerts = $False
function update_con_xls{
param($file)
$Workbook = $Excel.Workbooks.Open($file)
foreach($con in $Workbook.Connections){
if ($con.OLEDBConnection -ne $null){
$con.OLEDBConnection.Connection = $con.OLEDBConnection.Connection.Replace($OLDCONN,$NEWCONN)
}
if ($con.ODBCConnection -ne $null){
$con.ODBCConnection.Connection = $con.ODBCConnection.Connection.Replace($OLDCONN,$NEWCONN)
}
}
$Workbook.Save()
$Workbook.saved = $true
$Excel.Workbooks.Close()
}
foreach ($file in $filelist) {
echo $file
if ($file.Extension -eq '.xls' -or $file.Extension -eq '.xlsx') {
$newfile = ($file.DirectoryName + '\' + $file.BaseName + $NAMEPOSTFIX + $file.Extension)
if($test){
echo $test
$newfile = ('C:\test\' + $file.Name) #for test run to copy coppy locally
}
Copy-Item $file.FullName -Destination $newfile
update_con_xls($newfile)
}
}
$Excel.Quit()
$Excel = $null
Maybe change:
$Excel.Workbooks.Close()
to :
$Excel= New-Object -ComObject Excel.Application;
$Workbook = $Excel.Workbooks.Open($file);
$Workbook.Save();
$Workbook.Close(); # <--- try
$Excel.Quit();
Remove-Variable -Name Excel;
I do not see anything here that could close your ODB and OLEDb connection trying to add:
$con.OLEDBConnection.Connection.Close();
$con.ODBCConnection.Connection.Close();
or
$con.OLEDBConnection.Close();
$con.ODBCConnection.Close();
after your work is finished.

Powershell script stops working when ran through task scheduler

I am running the script below as a scheduled task with the user logged on the server. It converts an xls file to csv using the Excel.Application COM object. The conversion works, but eventually breaks and I don't know why.
I have the task run the following command which should in theory allow it to run constantly:
powershell.exe -noexit -file "filename.ps1"
Any thoughts on what to try?
$server = "\\server"
$xls = "\path\XLS\"
$csv = "\path\CSV\"
$folder = $server + $xls
$destination = $server + $csv
$filter = "*.xls" # <-- set this according to your requirements
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true # <-- set this according to your requirements
NotifyFilter = [IO.NotifyFilters]"FileName, LastWrite"
}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$excelFile = $folder + $name
$E = New-Object -ComObject Excel.Application
$E.Visible = $false
$E.DisplayAlerts = $false
$wb = $E.Workbooks.Open($excelFile)
foreach ($ws in $wb.Worksheets) {
$n = "output_" + $name -replace ".XLS"
$ws.SaveAs($destination + $n + ".csv", 6)
}
$E.Quit()
}
I was doing something similar with word. I couldnt use Quit alone. I think using Quit hides Excel. Try releasing the com object by using:
$E.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($E)
Remove-Variable E
i dont know if you are opening the Excel application but if you are you can maybe use
$wb.close($false)
Let me know if it works...
Ref: https://technet.microsoft.com/en-us/library/ff730962.aspx?f=255&MSPPError=-2147217396

Excel is not refreshing using refreshall method in powershell script

I have PowerShell script which refreshs the excel from SharePoint to share drive location. I'm passing the credentials through .bat file but the credentials are not passing to excel when I use $excelworkbook.RefreshAll() method and prompting to enter the credentials again. IF I remove the parenthesis from refreshall then script will run but it is not refreshing the sheets data.
Your help will be appreciated.
Regards,
Raju
$excel = new-object -comobject Excel.Application
$excel.visible = $true
$fname = Split-Path $workbookpath -Leaf
storedp "$destpath" "Refreshing workbook"
$tempPath = "c:Temp\Autosys"
Copy-Item "$workbookpath" "$tempPath"
$excelworkbook = $excel.workbooks.Open("$tempPath\$fname")
$excelworkbook.RefreshAll()
while ($excelworkbook.ODBCConnection.Refreshing)
{
Start-Sleep -Seconds 1
}
$excelworkbook.save()
$excelworkbook.close()
$excel.quit()
$DSN = $args[0]
$DB = $args[1]
$DB_User = $args[2]
$DB_Password = $args[3]
$SQLServerPwd = $args[4]
$NetworkPwd = $args[5]
$SingleOrBulk = $args[6]
$Filename = $args[7]
$OutFilename = $args[8]
$Dated = $args[9]
$DateFormat = $args[10]
write-host "DSN = $DSN"
write-host "DB = $DB"
write-host "DB_User = $DB_User"
write-host "DB_Password = $DB_Password"
write-host "SQLServerPwd = $SQLServerPwd"
write-host "NetworkPwd = $NetworkPwd"
write-host "SingleOrBulk = $SingleOrBulk"
write-host "Filename = $Filename"
write-host "OutFilename = $OutFilename"
$pass= $NetworkPwd | ConvertTo-SecureString -AsPlainText -Force
$cred=New-Object System.Management.Automation.PSCredential('test#prod',$pass)
New-PSDrive -Name P -PSProvider FileSystem -Root "\\testprod.md.net\GroupShares\Global\PA" -Credential $cred
$cred=New-Object System.Management.Automation.PSCredential('test#dev',$pass)
I have solved my problem by putting the connection details in internet explorer in local connections tab.

Resources