I cant get powershell to run in task scheduler - excel

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

Related

Automatically convert xls files to xlsx

I have a software that just allows me to download my data in xls files but I want to use it as an xlsx file.
Currently I have an excel macro when I click on a button it converts all my xls files in xlsx but I want to automate this task so I don't have to open the excel file and click on the button.
I was thinking of a script that start when I log in windows or something like that, and it converts automatically my xls file when I download it. But I'm not very good with scripts so anyone can help me with that ? It's on windows 7 and 10.
Thank you for your help.
Edit:
Here is my Powershell script, now I have to automate it so that it runs automatically when I download a new .xls file, I know I can use the task scheduler but how can I do that automation on en event like adding a new xls file to a folder ? Or maybe we can do it in powershell ?
My script:
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbook
write-host $xlFixedFormat
$excel = New-Object -ComObject excel.application
$excel.visible = $false
$folderpath = "C:\Users\Mgtspare\Downloads\"
$filetype ="*xls"
Get-ChildItem -Path $folderpath -Include $filetype -recurse |
ForEach-Object `
{
$path = ($_.fullname).substring(0, ($_.FullName).lastindexOf("."))
"Converting $path"
$workbook = $excel.workbooks.open($_.fullname)
$path += ".xlsx"
$workbook.saveas($path, $xlFixedFormat)
$workbook.close()
remove-item $_.fullname
}
$excel.Quit()
$excel = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
UPDATE:
I changed my script to have a new script faster and I put a watcher so I run the script when a new xls file is downloaded, I will use task manager to run this script when I log in windows so it can watch without doing anything.
Here is my new script:
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users\Mgtspare\Downloads"
$watcher.Filter = "*.xls"
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
$watcher.Path *.xls | rename-item -newname { [io.path]::ChangeExtension($_.name, "xlsx") }
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
while ($true) {sleep 5}
Issue:
My script run in the ISE but when i want to run it in cmd or with the right click on my script file and run with with powershell I have this issue
You must provide a value expression on the right-hand side of the '*' operator.
The below script automatically runs each morning with Task Manager
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users\Mgtspare\Downloads"
#$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
Get-ChildItem -Path C:\Users\Mgtspare\Downloads *.xls | rename-item -newname { [io.path]::ChangeExtension($_.name, "xlsx") }
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher 'Created' -SourceIdentifier 'FileCreated' -Action $action
while ($true) {sleep 1000}

Powershell script for setting Multi User Editing in excel for numerous files?

I've written a code that tries to go through my company server and set all the excel files, under a certain folder, to shared so that multiple people can edit them at once. This has been a problem for a very long time here and I thought I had a nice code to fix this but I can't seem to access the property correctly. Can anyone help?
$ErrorActionPreference = "Stop"
$root = "P:\A N G"
$excelFiles = Get-ChildItem -path $root -File "*.xlsx" -Recurse
foreach ($excelFile in $excelFiles.FullName)
{
$excel = New-Object -ComObject Excel.Application
$excelWorkBook = $excel.Workbooks.Open($excelFile)
if (!$excelWorkBook.MultiUserEditing)
{
Write-Host $excelFile
$excelWorkBook._SaveAs([Microsoft.Office.Interop.Excel.XlSaveAsAccessMode]::xlShared)
$excelWorkBook.Close
}
}
With some help from a friend I managed to come up with a solution actually.
$ErrorActionPreference = "Stop"
$root = "P:\A N G"
$excelFiles = Get-ChildItem -path $root -File "*.xlsx" -Recurse
foreach ($excelFile in $excelFiles.FullName)
{
$excel = New-Object -ComObject Excel.Application
$excelWorkBook = $excel.Workbooks.Open($excelFile)
if (!$excelWorkBook.MultiUserEditing)
{
Write-Host $excelWorkBook.FullName
$accessMode = [Microsoft.Office.Interop.Excel.XlSaveAsAccessMode]::xlShared
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
$excelWorkBook.SaveAs($excelWorkBook.FullName,$xlFixedFormat,$null,$null,$null,$null,$accessMode,$null,$null,$null,$null,$null)
$excelWorkBook.Close
}
}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)

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

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.

How to use powershell to run personal macro with different paths

I am trying to create automatically a report out of an excel file. I already analyzed one specific file and the report is saved local.
Now I want to use this macro to run it on other files. Therefore I have to change the path in the powershell.
Now I want to run the macro automatically (let`s say at 1am) with powershell.
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open("C:\Users\fami\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB")
$FilePath = "C:\Users\fami\Desktop\example.xls"
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $false
$worksheet = $workbook.worksheets.item(1)
$excel.Run("PERSONAL.XLSB!run")
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
Only the $FilePath needs to be variable.
You just need to use a Parameter for the $FilePath variable instead of hard coding it. Like this:
param([string]$FilePath)
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open("C:\Users\fami\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB")
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $false
$worksheet = $workbook.worksheets.item(1)
$excel.Run("PERSONAL.XLSB!run")
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
Then you would schedule the script and specify the -FilePath paramater like so:
powershell.exe -file C:\folder\yourscript.ps1 -FilePath "C:\Users\fami\Desktop\example.xls"
EDIT: To read a list of files from a text file (with one file on each line) would be this.
param(
[string]$FileList,
[string]$PersonalXLSB="C:\Users\fami\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB",
[string]$RunMacro="PERSONAL.XLSB!run"
)
$Files = Get-Content $FileList
foreach ($FilePath in $Files) {
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open($PersonalXLSB)
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $false
$worksheet = $workbook.worksheets.item(1)
$excel.Run($RunMacro)
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
}
I've also moved the PersonalXLSB and Macro to Params, as they have a value set this will be used as default if you don't specify anything else. It's most basic form is like this:
powershell.exe -file C:\folder\yourscript.ps1 -FileList "C:\folder\name.text"
You can change the other params like this:
powershell.exe -file C:\folder\yourscript.ps1 -FileList "C:\folder\name.text" -RunMacro="PERSONAL.XLSB!macroname"

Calling Excel macros from PowerShell with arguments

Using Powershell it's rather easy to call Excel macro's from a script, for example with a script like this:
$excel = new-object -comobject excel.application
$excelFiles = Get-ChildItem -Path C:\fso -Include *.xls, *.xlsm -Recurse
Foreach($file in $excelFiles)
{
$workbook = $excel.workbooks.open($file.fullname)
$worksheet = $workbook.worksheets.item(1)
$excel.Run("CreateChart")
$workbook.save()
$workbook.close()
}
$excel.quit()
However, I didn't manage to call a macro with some arguments. Is this possible or is the best way to write a config file that the macro will read when called?
You can run a macro with arguments like this:
$excel.Run('CreateChart', 'arg1', 'arg2', ...)

Resources