Sendkeys to VSCode with Powershell: only works 1st time, 2nd time, why do I get an error about nodejs? - node.js

When I paste this in Powershell Console, it works
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('Untitled-1')
Sleep 1
$wshell.SendKeys('Hello World 1~')
Sleep 1
$wshell.SendKeys('Hello World 2~')
But if I paste second time, I have a weird message about nodejs whereas It has nothing to do with what I'm doing ?!
Update: I suspect Electronjs so I add it in tag :)

Related

Excel Crashes when trying to run powershell command

I am having an issue trying to run a complex HTTP Request through a powershell command from a VBA function.
VBA Code Below: The powershell script runs fine from inside powershell
Public Function PS_GetOutput(id As String) As String
'Setup the powershell command properly
psCommand = "powershell -command " & "C:\Users\promney\temp1\curlCommand.ps1 " & id
'Execute the command
CreateObject("WScript.Shell").Run psCommand, 3, True
'Get an instance of the clipboard to capture the save value
End Function
The PS1 file should grab the html and put a string on the clipboard. Instead, the PS window opens as a blue field, then it and excel crash completely and immediately. What am I doing wrong here?
Note: I would include the PS script but that is a lot of possibly sensitive info to scrub and I'm pretty sure the issue is in the VBA, since it works fine unless called from excel.

PowerShell trying to convert to an integer instead of a string

My problem is that PowerShell wants to convert "=" into an integer, when trying to use it to make a new string. I made sure that my resulting variable would also be a string. Here's my task:
I have a little Excel table like this:
___________|VLANID1|VLANID2|VLANID3|
SwitchName1| 1-7| 12-16| 8-11| ← Ports 1-7 of Switch1 are configure for VLAN1...
SwitchName2| 1-7| 12-16| 8-11|
Out of this table I want to save each port in an .ini file with the VLAN it is configured too, aka:
[SwitchName1]
1=VLANID1
2=VLANID3
...
And here's my code which I loop until there are no ports, and then no more switches.
$split = $global:Ports -split("-") #$Ports is the Value with the saved excel cell (7-11)
$split[0]..$split[1] | ForEach-Object {
$vlan = $global:Switches.Cells.Item(1, $global:SSpallte).Text
[string]$inistring = "`n" + $_ + "=" + $vlan #<- Here it tries to convert "=" into integer
Add-Content -Path $global:portsini -Value $inistring
}
I even tried converting every variable which I use to make $inistring to a string before, it still doesn't work. Also, both $_ and $vlan have a Value and are not $null.
The Error states that "=" cannot be converted into the type "System.Int32".
So, im not quite sure what the problem was, but my way to solve it was to restart my environment. I am programming in the PowerShell ISE which I have sometimes seen "caching" variables. This restart of the ISE made the program work again.
And no, I didn't change anything beforehand.
In the end I'm happy that my problem is no more, but I'm still wondering why the error got triggered by the "=".

How can I stop Excel processes from running in the background after a PowerShell script?

No matter what I try, Excel 2013 continues to run in the background on Windows 10 no matter what commands I throw at the end of my PowerShell script. I've tried adding all suggestions I've found to the end of my script and the only Excel object I open continues to remain open. Here is what I have at the end of my script. Any other suggestions?
## Quit Excel and Terminate Excel Application process:
$xlsxwb.quit
$xlsxobj.Quit
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsxobj)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsxwb)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsxSh1)
Start-Sleep 1
'Excel processes: {0}' -f #(Get-Process excel -ea 0).Count
I ran into the same problem and tried various solutions without success. I got closer when I started releasing all of the COM objects I saved as variables, not just the ones for the workbook, worksheet, and Excel application.
For example, take the following example code:
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $False
$Workbook = $Excel.Workbooks.Open("C:\Temp\test.xlsx")
$Worksheet = $Workbook.Worksheets.Item(1)
$UsedRange = $Worksheet.UsedRange
$Range = $Worksheet.Range("A1:B10")
$Workbook.Close()
$Excel.Quit()
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($Range)
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($UsedRange)
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($Worksheet)
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook)
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
[GC]::Collect()
If you were to take out just one of the ReleaseComObject statements, the Excel process would remain open. In my code I release all the ones like ranges, tables, etc. first and then I do the worksheet, workbook, and finally the Excel application itself. Then because that only seemed to work like 90% of the time, I added the garbage collection command at the end and finally had a solution that seems to work every time without having to kill the process.
Note: My system is Windows 8.1 with PowerShell v5 and Office 2013.
Here's a simple example below. It will likely require some additional code for more complex procedures.
function _FullQuit {
while ( $this.Workbooks.Count -gt 0 ) {
$this.Workbooks.Item(1).Close()
}
$this.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($this)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
function New-Excel {
$object = New-Object -ComObject "Excel.Application"
$object | Add-Member -MemberType ScriptMethod -Name FullQuit -Value {_FullQuit}
$object
}
$xl = New-Excel
$wb1 = $xl.Workbooks.Open("C:\Data1.csv")
$wb2 = $xl.Workbooks.Open("C:\Data2.csv")
$xl.FullQuit()
Create Excel Application.
Make it visible
Get Process Id of the application.
Hide Excel Application.
Stop process my process id.
Sample Code
# Create Excel Application
$excel = New-Object -comobject Excel.Application
# Make it visiable
$excel.Visible = $true
# Get Windows handle of the application
$excelWinHwnd = $excel.Hwnd
# Get Process Id of the application
$process = Get-Process Excel | Where-Object {$_.MainWindowHandle -eq $excelWinHwnd}
$excelProcessId = $process.Id
# Hide the application : Run In background
$excel.Visible = $false
# Kill/Stop the process by id
Stop-Process -Id $excelProcessId
The above solutions did not work for me, in the sequence I needed the final step was .saveas(file.xlsx) which meant that the remaining unsaved document still popped a gui interface requiring user interaction to save/don't save/cancel.
I ended up with the following, which is admittedly rough, but worked for me.
At the beginning of the script:
$existingExcel = #()
Get-Process Excel | % {$existingExcel += $_.ID }
function Stop-Excel
{
Get-process EXCEL | % {IF($_.ID -notmatch $existingExcel){Stop-Process -ID $_.ID}}
}
and at the end of the script
Stop-Excel
This has the advantage of completely destroying any lingering excel processes without terminating any other live excel processes that may be in use by the users that run have to this script.
The disadvantages are that when you next load excel you are presented with a crashed excel document recovery dialogue.
Alternative answer:
I understand that my reply is late, still, consider following approach to get this done.
At the beginning, get the PIDs of any/all instances of excel.exe, using command:
tasklist /FI "imagename eq excel.exe"
Run the part of script that generates its instance of excel.exe. Use the command in step 1 to identify and save PID of newly generated instance of excel.exe (say wxyz), this will be different from already existing PIDs saved in step 1.
At the end of script, close the specific instance (with PID saved in step 2), using command:
TASKKILL /f /PID wxyz
where wxyz is 4 digit PID saved in step 2.
If nothing else works reliably, try to make the Excel application's DisplayAlerts to tru just before quitting.
$xlapp.DisplayAlerts=$true
$xlapp.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject([System.__ComObject]$xlapp)
$xlapp=$null
remove-variable xlapp
[GC]::Collect()
This always works for me.

Windows Script to Find String in Log File

I have IBM Cognos TM1 application running as Services on Windows Server 2008. When I start the Service, TM1 will write a log file named "tm1server.log" on "D:\TM1\log\". TM1 will continously write this log until the service is ready, which normally takes 3 hours until the service is ready. When the service is ready, TM1 will write "TM1 Server is ready" on the log.
I want to make a script that continously check the log file until the string "TM1 Server is ready" is written. When the string found, I want the script to run another script that will send email to me. I have made the script for sending email.
Can anybody help me?
Thanks and regards,
Kris
--edit--
i use findstr command to search the string:
findstr /d:d:\TM1\log\ "TM1 Server is ready" "D:\TM1\log\tm1server.log" >> result.log
but the result.log contains all of the contents of tm1server.log.
On my server, 'TM1 server is ready' is written each time the server starts. So I have many 'TM1 server is ready's in one file.
You could test the last returned 'TM1 server is ready' to see when it happened to see if it happened in the last 5 (or whatever) hours with something like:
PS E:\TM1_Server_Logs> (Get-Date(select-string .\tm1server.log -pattern '(?<timestamp>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}).*TM1 server is ready' | select -expand Matches | foreach {$_.groups["timestamp"].value} | Get-Date -format "yyyy-MM-dd HH:mm:ss" | Select-Object -last 1)).AddHours(-5) -ge (Get-Date).AddHours(-5)
That's a long one-liner, but it should work. If it returns true you could decide what to to next.
You can also try
findstr /C:"your token to find" "C:\targetFile.log"

powershell: if excel already running, get instance, otherwise start it - with exception handling

Using Powershell, I want to import some tab-separated Ascii files into MS Excel. I use a loop for doing so, and right now I have a simple solution that works:
for each file: start Excel , import tsv file, close Excel.
..assuming Excel is in the Path, it's the right version of Excel, Excel 2010
Now I want to switch to a more efficient version: keep excel open.
for each file: grab running instance of excel if there is one, if not, try to start excel. Process file. Keep excel open. At the end, keep it open ( I want to look at the excel files while the script is running, which could take a while. Annoyingly, in the current version of the script excel is being closed while I am looking at the output).
I haven't found a comprehensive solution for this, neither here nor elsewhere on the internet. With "comprehensive" I mean "Exception Handling". In Powershell, it's a bit confusing. There are two ways of dealing with exceptions: using trap and a try-catch block.
Here is my code, thrown together from several internet sources , how can I improve it?
I want to wrap it in a function, but COM objects as return values are problematic. (
What I want is a combination of "simple factory" and "singleton".)
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Excel")
try {
$excelApp = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
} catch [System.Runtime.InteropServices.COMException], [System.Management.Automation.RuntimeException]{
write-host
write-host $("TRAPPED: " + $_.Exception.GetType().FullName);
write-host $("TRAPPED: " + $_.Exception.Message);
write-host "Excel is not running, trying to start it";
$excelApp = New-Object -ComObject "Excel.Application"
if (-not $excelApp){
# excel not installed, not in path
Write-Error "Excel not running, and cannot be started, exiting."
# Todo: test if excel version is correct, e.g. english Excel 2007 or 2010., if not set outfile extension xls.
exit;
}
}
catch [System.Exception]{
write-host $("EXCEPTION: " + $_.Exception.GetType().FullName);
write-host $("EXCEPTION: " + $_.Exception.Message);c
Write-Error 'Something went wrong during creation of "Excel.Application" object, => Exit.'
exit;
}
It's been a while since you asked this, but I have run into the same problem. Your code appears to be only good example of a reasonable solution. I do question your concern, however. Specifically, once Excel is running is there a need to call this routine again in a function? That is, once Excel is open, then you can treat it as a service to open/close workbooks, access worksheets within them, and eventually $excelApp.Quit() the application (although in Powershell v1.0 the .Quit() won't exit the app... but that is OK since I am grabbing a running instance anyways).
The link below discusses a way of starting up and grabbing the PID of Excel instance in order to explicitly kill it if needed.
Discussion on Quiting/Killing Excel from within Powershell
All variables must be null. Excel.Workbooks - all open book.
Check count of Workbooks. If count = 0, quit. After close of Powershell Excel will be close too.
$Workbook.Close()
$WorkSheet = $null;
$Workbook = $null;
If($excelApp.Workbooks.Count -eq 0)
{$excelApp.Quit()}
$excelApp = $null;

Resources