Excel is not refreshing using refreshall method in powershell script - excel

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.

Related

Powershell Excel SaveAs requires confirmation

I use below script to convert bunch of xls files to xlsx.
$folderpath = %tempPath%
$filetype ="*xls"
Add-Type -AssemblyName Microsoft.Office.Interop.Excel
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
write-host $xlFixedFormat
$excel = New-Object -ComObject excel.application
$excel.visible = $true
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()
}
$excel.Quit()
$excel = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
It used to work perfectly running on VM.
Unfortunately with changing folder path I realised there are popup windows to confirm saving that didn't come up before and the script gets stuck on that.
Any simple corrections that could prevent that error?
"scriptError": {
"localizedName": "Error",
"value": "Unable to get the SaveAs property of the Workbook class\r\nAt C:\\Users\\~
"variableName": "ScriptError"
}
Here's an example of how I set the path when saving an Excel file using PowerShell. I set the path using a combination of the Get-Location cmdlet, Get-Date cmdlet and the file name, which is stored in a string variable for use when saving the script.
Add-Type -AssemblyName Microsoft.Office.Interop.Excel
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
$htFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlHtml
$Date = get-date -format R
$CurrentLocation = Get-Location
$CurrentDir = Get-location
$Timestamp = get-date -format d
$xlsx = [String] $CurrentLocation + "\MyNewExcelStuff-" + $Timestamp + ".xlsx"
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$excel.DisplayAlerts = $False
$workbook = $excel.Workbooks.add()
$sheet1 = $workbook.worksheets.Item(1)
$sheet1.name = "Stuff"
$Sheet1.Cells.Item(1,1) = "Reporting Stack Stuff"
$title = $Sheet1.Range("A1:K1")
$title.Select()
$title.MergeCells = $true
$title.VerticalAlignment = -4108 # Centre (vertically) heading
$title.HorizontalAlignment = -4108 # Centre (horizontally) heading
$Title.Interior.ColorIndex = 0
$Excel.ActiveWorkbook.SaveAs($xlsx, $xlFixedFormat)
Start-Sleep -s 2
$Excel.Quit()
$Excel = $Null
You should use $workbook.Close($false).

Powershell, close Excel

I have the following code and it works perfectly except it's not closing Excel properly. It's leaving an Excel process running.
Is there a way to close Excel properly without killing the process?
Since i'm using other Excel files while running this script i can not kill all active Excel processes.
I think i tried everything i found online.
$WorkDir = "D:\Test\QR_ES\RG_Temp"
$BGDir = "D:\Test\QR_ES\3_BG"
$File = "D:\Test\QR_ES\4_Adr_Excel\KD_eMail.xlsx"
$SentDir = "D:\Test\QR_ES\RG_Temp\Sent\Dunning"
chdir $WorkDir
$firstPageList = Get-ChildItem "$WorkDir\1*.pdf" -File -Name
ForEach ($firstPage in $firstPageList)
{
$secondPage = "$BGDir\BG_RG.pdf"
$output = "Dunn-$firstPage"
invoke-command {pdftk $firstPage background $secondPage output $output}}
del 1*.pdf
gci $WorkDir\Dunn-*.pdf | rename-item -newname {$_.Name.Substring(5)} -Force
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $false
$Workbook = $Excel.workbooks.open($file)
$DunnList = Get-ChildItem "$WorkDir\1*.pdf" -File -Name
ForEach ($Dunn in $DunnList)
{
$Worksheets = $Workbooks.worksheets
$Worksheet = $Workbook.Worksheets.Item("KD_eMail")
$Range = $Worksheet.Range("A1").EntireColumn
$DunnSearch = $Dunn.Substring(0,5)
$SearchString = $DunnSearch
$Search = $Range.find($SearchString)
$Recipient = $Worksheet.Cells.Item($Search.Row, $Search.Column + 1)
$Msg = "<span style='font-family:Calibri;font-size:12pt;'>Test</span>"
$Outlook = New-Object -ComObject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")
$namespace.Logon($null, $null, $false, $true)
$EmailFrom = ('test#test.com')
$account = $outlook.Session.Accounts.Item($EmailFrom)
$Mail = $Outlook.CreateItem(0)
$Mail.HTMLBody = $Msg
$Mail.Subject = "OP - $SearchString"
$Mail.To = $Recipient
function Invoke-SetProperty {
param(
[__ComObject] $Object,
[String] $Property,
$Value
)
[Void] $Object.GetType().InvokeMember($Property,"SetProperty",$NULL,$Object,$Value)
}
Invoke-SetProperty -Object $mail -Property "SendUsingAccount" -Value $account
$Mail.Attachments.Add("$WorkDir\$Dunn")
$Mail.Save()
$Mail.close(1)
$Mail.Send()}}
$workbook.close($false)
$Excel.Quit()
chdir $WorkDir
del 1*.pdf
See this post:
https://stackoverflow.com/a/35955339/5329137
which is not accepted as an answer, but I believe is the full, correct way to close Excel.
This is what did it for me:
$FilePID = (Get-Process -name Excel | Where-Object { $_.MainWindowTitle -like 'FileName.xlsx*' }).Id
$Workbook.Save()
$Workbook.close($false)
Stop-Process $FilePID
Elaborating on #ASD's answer, since the MainWindowTitle doesn't (always) include the file suffix (.xlsx) you may have to strip that when comparing it to the filename. I'm using -replace to use a Regex match of everything before the last dot.
$excelPID = (Get-Process -name Excel | Where-Object { $_.MainWindowTitle -eq $fileName -replace '\.[^.]*$', '' }).Id
$workbook.Close()
Stop-Process $excelPID

timeout to powershell script

I've a script in Powershell that update Excel files with connections to SQL databases. The script works fine but the problem is if one connection doesn't work the script can't continue. Is there a way to put like a timeout or something so that can continue after a wile?
Here is the script that I have:
$libraryPath = "C:\temp\Excel\"
$excel = new-object -comobject Excel.Application
# Give delay to open
Start-Sleep -s 5
$allExcelfiles = Get-ChildItem $libraryPath -recurse -include “*.xlsx”
foreach ($file in $allExcelfiles)
{
$workbookpath = $file.fullname
Write-Host "Updating " $workbookpath
# Open the Excel file
$excelworkbook = $excel.workbooks.Open($workbookpath)
$connections = $excelworkbook.Connections
foreach ($c in $connections)
{
if ($c.DataFeedConnection -ne $null)
{
$conn = $c.DataFeedConnection.Connection
# Use regex to search and replace part of connection string
$new = $conn -replace 'ProjectName eq ''(.*)''', "ProjectName eq '$title'"
$c.DataFeedConnection.Connection = $new
Write-Host "Connection replaced."
}
}
Start-Sleep -s 5
# This will Refresh All the pivot tables data.
$excelworkbook.RefreshAll()
# The following script lines will Save the file.
Start-Sleep -s 50
$excelworkbook.Save()
$excelworkbook.Close()
}
$excel.quit()
Thanks
You could run the your script as a job, and if the job exceeds a given period terminate it.
$timeout_in_sec = 10
$excel_update = {
$libraryPath = "C:\temp\Excel\"
$excel = new-object -comobject Excel.Application
# Give delay to open
Start-Sleep -s 5
$allExcelfiles = Get-ChildItem $libraryPath -recurse -include “*.xlsx”
foreach ($file in $allExcelfiles)
{
$workbookpath = $file.fullname
Write-Host "Updating " $workbookpath
# Open the Excel file
$excelworkbook = $excel.workbooks.Open($workbookpath)
$connections = $excelworkbook.Connections
foreach ($c in $connections)
{
if ($c.DataFeedConnection -ne $null)
{
$conn = $c.DataFeedConnection.Connection
# Use regex to search and replace part of connection string
$new = $conn -replace 'ProjectName eq ''(.*)''', "ProjectName eq '$title'"
$c.DataFeedConnection.Connection = $new
Write-Host "Connection replaced."
}
}
Start-Sleep -s 5
# This will Refresh All the pivot tables data.
$excelworkbook.RefreshAll()
# The following script lines will Save the file.
Start-Sleep -s 50
$excelworkbook.Save()
$excelworkbook.Close()
}
$excel.quit()
}
$job = Start-Job -Name 'thing' -ScriptBlock $excel_update
Wait-Job -Timeout $timeout_in_sec -Job $job
if ($job.State -eq 'Running') { Stop-Job -Job $job }
Remove-Job -Job $job
Change $timeout_in_sec to whatever suites your needs.

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

Resources