Close specific Excel file using Powershell - powershell

What would be the appropriate PowerShell cmdlet to use to kill a specific Excel file. The command
Stop-Process -Name "excel"
closes all open Excel applications.
Thanks in advance!

Actually, excel opens .xlsx files in one instance of excel.exe
Kill the excel.exe will kill all opening workbooks. The MainWindowTitle only shows the active workbook, so you will not able to match passive workbooks by the property.
A better way to close a specific workbook is to acquire the excel instance by com object.
Close the workbook matched the Name (file name) or FullName (file path)
$excel = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
$excel.DisplayAlerts = $false
$excel.Workbooks | %{if($_.Name -imatch "excel file name"){$_.Close()}}

Try this out:
Get-Process excel –ea 0 | Where-Object { $_.MainWindowTitle –like ‘*report.csv*’ } | Stop-Process
Here's the official guide from MS:
Stop-Process

$Application = New-Object -ComObject excel.application
$Application.Visible=$True
$workbook = $application.Workbooks.open("C:\mySheet.xlsx")
Start-Sleep -Seconds 5
$workbook.close($false)
The problem is that the window remains open while the dokument is closed.
Hope it still helps.
BR

Related

How to use Aspose Cells dll in Powershell Script

I'm new to powershell, I want to perform some operations on excel. I'm able to do that by using Com Object. But i dont want to use Com Object , instead of that im trying to use aspose cells dll.
Could you please help how can i import or add this dll in my powershell script.
Below is code by using Com Object , i want to re-write it using aspose dll.
$Source = 'D:\Test' # the path to where the Excel files are
# create an Excel COM object
$excel = New-Object -ComObject Excel.Application
# find Excel files in the Source path and loop through.
# you may want to add the -Recurse switch here if the code should also look inside subfolders
$result = Get-ChildItem -Path $Source -Filter '*.xlsx' -File | ForEach-Object {
$workBook = $excel.Workbooks.Open($_.FullName)
$workSheet = $Workbook.Sheets.Item(1)
$count = 0
$label = $workSheet.Range('$A:$B').Find('*Animal count:*')
if ($label) {
# get the numeric value for the cell next to the label
# empty cells will translate to 0
$count = [int]$workSheet.Cells.Item($label.Row, $label.Column +2 ).Value()
}
# output a PSObject with the full filename and the animal count value
[PsCustomObject] #{
'File' = $_.FullName
'AnimalCount' = $count
}
$workBook.Close()
}
# quit Excel and clean up the used COM objects
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workSheet) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workBook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
# output on screen
$result | Format-Table -AutoSize
#output to CSV file
$result | Export-Csv -Path 'D:\Test\AnimalCount.csv' -UseCulture -NoTypeInformation
e
Generally, you can use .NET libraries in PowerShell. Aspose.Cells for .NET is written in managed C#.NET, so it is a .NET assembly that can also be used in PowerShell environment (just to similar way as you use a custom .NET library) using standard approach. For example, please visit this link on how to use a .NET assembly in PowerShell. Please note, you have to accommodate/convert to PowerShell scripts by yourself.
Regarding your COM interop. sample code segments, please visit the following documents’ links using Aspose.Cells APIs for your reference for different tasks you are performing:
e.g.
(How to open different MS Excel file formats.)
https://docs.aspose.com/display/cellsnet/Opening+Different+Microsoft+Excel+Versions+Files
(How to find or search data in the worksheet)
https://docs.aspose.com/display/cellsnet/Find+or+Search+Data
(How to convert to CSV file format)
https://docs.aspose.com/display/cellsnet/Different+Ways+to+Save+Files#DifferentWaystoSaveFiles-SavingTextFileswithCustomSeparator
Hope, this helps a bit.
PS. I am working as Support developer/ Evangelist at Aspose.

how to bring forward an IE window with powershell

I have the following powershell command that will run on users pc on a scheduled basis, based on a REST API Call to know if they havent submitted the timesheet.
It works fine, but I would like to put the IE window as the main window at that moment.
$msgBoxInput = [System.Windows.MessageBox]::Show('You havent submitted the timesheet. Please do it now','xyz is watching you','OK','Error')
$IE=new-object -com internetexplorer.application
$IE.navigate2("www.microsoft.com")
$IE.visible=$true
Is it doable with powershell? in an easy way
It should be doable.
Have a look at this example:
## Find all Active Windows Titles
$windows=Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle
## Find Specific name
$WindowTitle=($windows | ? {$_ -match "Internet Explorer"} ).MainWindowTitle
## Add Type and Focus Activate the Window
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate($WindowTitle)
You just have to make sure that you have the correct MainWindowTitle.
Hope it helps

How to avoid powershell going into wait mode automatically

I have a powershell script which automates the upload of a report. After the file upload dialog box opens in Internet Explorer, My code tries to get it's id and then send keys and send the file address and sendkeys enter. But unfortunately as soon as the file upload dialog box pops up my script doesn't proceed further and waits there. If I hit close (in the file upload dialog) then the script continues. Is there any way by which I can tell powershell to not wait for anything?
Here's my code :-
$dummy = get-process iexplore | where {$_.mainWindowTitle -eq "ArkAngelWeb - Hitachi Systems Security Inc. - Internet Explorer"} | select -expand id
Sleep 1
$temp = $ie.Document.documentElement.getElementsByClassName("v-button-caption") | Where-Object {$_.innerHTML -eq "Select file"}
$temp.click()
Sleep 2
$swshell=New-Object -ComObject wscript.shell
$fileUploadDialog = get-process iexplore | where {$_.mainWindowTitle -eq "ArkAngelWeb - Hitachi Systems Security Inc. - Internet Explorer" -and $_.Id -ne
$dummy.Id} | select -expand id
$swshell.AppActivate($fileUploadDialog.Id)
$swshell.SendKeys("H");
$swshell.SendKeys("{TAB}")
$swshell.SendKeys("C:\Users\ratns1\Desktop\TEST_FILE.txt")
$swshell.SendKeys("~")
Thanks
This is the issue with SendKeys, timing, UI controls, etc.
You are popping a model dialog box, and that is what's causing the wait.
By design, your script will not continue until you dismiss it. This is the design for dialogs.
PoSH notwithstanding, it is your use case that is the catch 22, not PoSH itself.
Take a look at the Wasp module to take the load off all the sendkey and Window lookup stuff off your plate.
Occasionally, the only way of automating processes is to send
keystrokes or mouse clicks to UI elements. A good and free PowerShell
extension is called "WASP" and is available here:
http://wasp.codeplex.com/
Once you install the module (do not forget to unblock the ZIP file
before you unpack it, via right-click, Properties, Unblock), the WASP
module provides the following cmdlets:
Get-WindowPosition
Remove-Window
Select-ChildWindow
Select-Control
Select-Window
Send-Click
Send-Keys
Set-WindowsActive
Set-WindwowPosition
Here is a simple automation example using the Windows calculator:
Import-Module WASP
# launch Calculator
$process = Start-Process -FilePath calc -PassThru
$id = $process.Id
Start-Sleep -Seconds 2
$window = Select-Window | Where-Object { $_.ProcessID -eq $id }
# send keys
$window | Send-Keys 123
$window | Send-Keys '{+}'
$window | Send-Keys 999
$window | Send-Keys =
# send CTRL+c
$window | Send-Keys '^c'

Use PowerShell to generate a list of files and directories

I'm writing a PowerShell script to make several directories and copy a bunch of files together to "compile" some technical documentation. I'd like to generate a manifest of the files and directories as part of the readme file, and I'd like PowerShell to do this, since I'm already working in PowerShell to do the "compiling".
I've done some searching already, and it seems that I need to use the cmdlet "Get-ChildItem", but it's giving me too much data, and I'm not clear on how to format and prune out what I don't want to get my desired results.
I would like an output similar to this:
Directory
file
file
file
Directory
file
file
file
Subdirectory
file
file
file
or maybe something like this:
+---FinGen
| \---doc
+---testVBFilter
| \---html
\---winzip
In other words, some kind of basic visual ASCII representation of the tree structure with the directory and file names and nothing else. I have seen programs that do this, but I am not sure if PowerShell can do this.
Can PowerShell do this? If so, would Get-ChildItem be the right cmdlet?
In your particular case what you want is Tree /f. You have a comment asking how to strip out the part at the front talking about the volume, serial number, and drive letter. That is possible filtering the output before you send it to file.
$Path = "C:\temp"
Tree $Path /F | Select-Object -Skip 2 | Set-Content C:\temp\output.tkt
Tree's output in the above example is a System.Array which we can manipulate. Select-Object -Skip 2 will remove the first 2 lines containing that data. Also, If Keith Hill was around he would also recommend the PowerShell Community Extensions(PSCX) that contain the cmdlet Show-Tree. Download from here if you are curious. Lots of powerful stuff there.
The following script will show the tree as a window, it can be added to any form present in the script
function tree {
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
# create Window
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Files"
$Form.Size = New-Object System.Drawing.Size(390, 390)
# create Treeview-Object
$TreeView = New-Object System.Windows.Forms.TreeView
$TreeView.Location = New-Object System.Drawing.Point(48, 12)
$TreeView.Size = New-Object System.Drawing.Size(290, 322)
$Form.Controls.Add($TreeView)
###### Add Nodes to Treeview
$rootnode = New-Object System.Windows.Forms.TreeNode
$rootnode.text = "Root"
$rootnode.name = "Root"
[void]$TreeView.Nodes.Add($rootnode)
#here i'm going to import the csv file into an array
$array=#(Get-ChildItem -Path D:\personalWorkspace\node)
Write-Host $array
foreach ( $obj in $array ) {
Write-Host $obj
$subnode = New-Object System.Windows.Forms.TreeNode
$subnode.text = $obj
[void]$rootnode.Nodes.Add($subnode)
}
# Show Form // this always needs to be at the bottom of the script!
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
}
tree
In Windows, navigate to the directory of interest
Shift+ right click mouse -> Open PowerShell window here
Get-ChildItem | tree /f > tree.log
The best and clear way for me is:
PS P:\> Start-Transcript -path C:\structure.txt -Append
PS P:\> tree c:\test /F
PS P:\> Stop-Transcript
You can use command Get-ChildItem -Path <yourDir> | tree >> myfile.txt this will output tree-like structure of a directory and write it to "myfile.txt"

PowerShell - Console Input using Explorer

Scenario: User is trying to upload a document from a PowerShell 3.0 script.
Current mechanism: Read-Host. Simple string prompt to request path/file.ext.
Desired behavior: A prompt ('Please choose the file to upload') and
Explorer is launched. The path/file the user selects is passed along to my script.
I can see how to launch Explorer of course, just can't figure how to tie the command line
prompt and the file selection with Explorer together.
Kind Regards,
Paul
Here's a simple script to do what you're wanting to do. Also you can use PowerGUI To compile the script and have the Powershell Window close Automatically close the powershell window after it's finished, but that's not needed.
$DestinationFolder = "L:\Users\caleb.berger\Desktop";
function Get-FileName($initialDirectory) {
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog;
$OpenFileDialog.initialDirectory = $initialDirectory;
$OpenFileDialog.filter = "All files (*.*)| *.*";
$OpenFileDialog.ShowDialog() | Out-Null;
$OpenFileDialog.filename;
}
Write-Host "Please Select The File To Upload:";
$SourceFile = Get-FileName -initialDirectory "c:\";
Write-Host "Copying File...";
Copy-Item -LiteralPath $SourceFile -Destination $DestinationFolder -Force;
Write-Host "Finished.";
Read-Host "Press Any Key To Continue";
You can learn more about how this works at:
http://blogs.technet.com/b/heyscriptingguy/archive/2009/09/01/hey-scripting-guy-september-1.aspx
His script is what I built this application off of.