Powershell script

Hello for some reason bat scripts work but ps1 scripts don't. Is there something special that needs to be done for powershell scripts?

I have the below script running as a gateway update event script and the ps1 and bat files are located in the same location. The delete tag increments for bat but not ps1

import time
try:
	time.sleep(5)
#	gitEXE = "C:\\Program Files\\Inductive Automation\\Ignition\\data\\git-auto-commit.bat"
	gitEXE = "C:\\Program Files\\Inductive Automation\\Ignition\\data\\git-auto-commit.ps1"
	logger.warn(str(system.file.fileExists(gitEXE))) 
	system.util.execute([gitEXE])
	val = system.tag.readBlocking("[Ignition_Remote_IO_Gateway]aTestSharedFolder/delete")[0].value
	system.tag.writeBlocking("[Ignition_Remote_IO_Gateway]aTestSharedFolder/delete", val+1)
except Exception as e:
	logger.warn(str(e))```

Do you get an error ?

Nothing shows up in the console log or the logger on the gateway page with the except statement.

Normally Powershell scripts have some tighter default execution policies that you might need to inspect/adjust. See here for some starter information: about Execution Policies - PowerShell | Microsoft Learn

@pascal.fragnoud, @kcollins1 I found an error. It was outside the logger I created.

Error executing project update script.

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "<[Data_Management] Update Script>", line 9, in File "<[Data_Management] Update Script>", line 9, in at java.base/java.lang.ProcessBuilder.start(Unknown Source) at java.base/java.lang.ProcessBuilder.start(Unknown Source) at java.base/java.lang.Runtime.exec(Unknown Source) at java.base/java.lang.Runtime.exec(Unknown Source) at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.execute(SystemUtilities.java:146) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.io.IOException: java.io.IOException: Cannot run program "C:\Program Files\Inductive Automation\Ignition\data\git-auto-commit.ps1": CreateProcess error=193, %1 is not a valid Win32 application

You might have to use powershell.exe to invoke the target .ps1 script. ref: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe?view=powershell-5.1

I'm executing

	system.util.execute([
		"powershell.exe",
		"-File 'C:\Program Files\Inductive Automation\Ignition\data\git-auto-commit.ps1'"
	])

but it doesn't seem to be doing anything with no errors and I don't see the afile.txt in the data folder.

git-auto-commit.ps1 (simple create file)

New-Item afile.txt

I also tried

	import subprocess
	proc = subprocess.Popen(["powershell.exe -File 'C:\Program Files\Inductive Automation\Ignition\data\git-auto-commit.ps1'"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
	proc = subprocess.Popen(['powershell.exe', "-File 'C:\Program Files\Inductive Automation\Ignition\data\git-auto-commit.ps1'"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
	output = proc.stdout.read()
	logger.warn(output)

but both those proc didn't work. First proc gave "[Errno 2] No such file or directory" and second proc gave "-File : The term '-File' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + -File 'C:\Program Files\Inductive Automation\Ignition\data\git-auto-c ... + ~~~~~ + CategoryInfo : ObjectNotFound: (-File:String) , CommandNotFou ndException + FullyQualifiedErrorId : CommandNotFoundException"

Thank you guys for the help so far

You're not structuring your commands correctly. Everywhere there's a space in a raw command line:
powershell.exe -File 'C:\Program Files\Inductive Automation\Ignition\data\git-auto-commit.ps1'
You need a new entry in the list you pass to system.util.execute or subprocess:

system.util.execute([
		"powershell.exe",
		"-File",
		"'C:\Program Files\Inductive Automation\Ignition\data\git-auto-commit.ps1'"
	])
1 Like

You are almost certainly going to need to double up your backslashes, as those are escape characters in python string constants.

2 Likes

Or use r"something\\" to ignore escape characters, unless this doesn't work in jython :X

1 Like

Thank you everyone for the help!!! This worked

	system.util.execute([
		"powershell.exe",
		"-File",
		"C:\\Program Files\\Inductive Automation\\Ignition\\data\\git-auto-commit.ps1"
	])

I didn't need the single quotes in the path

2 Likes

New to ignition here, and I'm curious if anyone has any ideas on getting Perspective to launch an RDP session through a powershell script? with the system.util.execute() method?

Perspective runs in a browser. You can't run PowerShell scripts from a browser for security reasons.

1 Like

Why? What are you trying to accomplish?

Thanks Transistor, I may just build it in Vision then!

Irose, in my deployment the perspective host consolidates about 30 SCADAs into one place so operators can easily respond to alarms without having to check each of these local SCADAs individually. Part of my design limits the functionality of the host to read only for safety & compliance. When live operations demand it, the operator must pull up the local SCADA & operate there. This is accomplished via RDP.

The idea is a gateway script that would act as a shortcut, pulling up an RDP more rapidly for convenience and in the event that we have a gateway crash a quick script to automatically launch all 30 RDPs would be very useful as many of our reporting requirements are time sensitive & unfortunately we do not have robust hardware making this host prone to crashes and endless performance related issues.

Looking forward to hearing your ideas, thanks for the help.

@arccitect - Tip: to have someone notified of a response either hit the Reply button under their post or use the @username syntax in the post.
Thanks for the feedback.

1 Like

Can't really do anything about this, because if the gateway crashes, you...well...can't use it.

You can't run a Powershell script from a browser, but there is nothing stopping the Gateway from executing a file on the gateway. So, I would use a Gateway Message Handler to run system.util.execute()

Of course, that won't help someone who isn't looking at the gateway computer, so there really isn't a way to launch a new session from the gateway on client hardware.

Consider using a Microsoft URI scheme for Remote Desktop. Probably works out of the box in MS Edge:

If you have a Linux server with docker available, you could use guacamole for this. I've got some potential projects needing VNC and Guacamole supports VNC and RDP in a web browser, so you could launch a URL to the guacamole client connection, or embed it in a view or popup.

1 Like

@lrose that makes sense.. Face meet palm! Either way it would be very useful to launch a single client session to expedite emergency operations since all manipulations must be performed in the local SCADA. I've already implemented a way to rapidly pull up our password manager for just such, and I'm curious if there may be a way to utilize an authenticated keeper commander session to accomplish this while obfuscating passwords in concert with @pturmel's suggestion for URI:

@michael.flagler I desperately wish I was just working solely with Linux... It would make life for me & my team a lot easier in many ways... That would be a brilliant feature, and is truly an excellent suggestion. I'm curious if there is a way to do something similar within the constraints of using Windows?