It’s a beautiful week here in January, we’ve had temperatures nearing near the 60’s and it’s been beautiful outside. According to the weather man, it will be colder (like winter is supposed to be) but hey: I’ll take what I can get.
I want to address several different ways to execute Windows Executables today. I typically try not to do this in Powershell, honestly. I like to create ways to do what I’m doing in another fashion- but sometimes instead of re-inventing the wheel it’s impossible, and I do like automation and saving time more.
So here are a few methods to go about executing .exe files within Powershell, and my experience in using these methods. NOTE: These are not ALL methods. I may bring a few others up later, but these are the ones I found myself researching the most.
1) Directly through Powershell- This is if it already has an environment variable or things that are within the windows\system32. These are typically a handful of programs, things that are included within the OS suite when loaded. For instance, ping.exe is located within the environment variable, so you can simply call it within a Powershell console by typing: ping myhostwhatever. If you are trying to simplify your work and think that moving the executable you are trying to run with Powershell into the system32 directory, think twice about your security posture and patching and read on!
2) Invoke-Command- This method is a commandlet within Powershell. This commandlet uses WinRM (WinRM), which is usually never enabled on the machines I work on. I know there are tons of articles, methods and even approved methods to enable it, but my security bound heart screams no to me. The only way I would do it is if the infrastructure permanently clicked the “on” switch, so I write my code according to knowing that I can’t use it. However, I digress from the subject. The Invoke-Command can be used to execute commands on the remote (or local) system. So, you can do things like copy scripts to remote machines, then use Invoke-Command to execute them, run commands on the remote computer such as ‘ipconfig /all’ for a simple example and it would return back to the machine. It is super convenient if you have it enabled in your environment.
3) Invoke-Expression- Invoke-Expression is very similar to the Invoke-Command except for it’s not. Invoke-Expression will execute whatever you pass to it. So you can run it on the remote machine to do things like zip files, unzip files, troubleshoot things like group policy, domain policies, etc. This also takes WinRM, so keep that in mind if you find something that works awesome on your local machine but then go to test it in your domain.
4) Invoke-Item- Invoke Item to me is like a magic trick gone bad. It’s like you are sitting at a child’s birthday party and the magician is trying to produce a rabbit from his hat, but 22 rabbit’s come out. Invoke-Item will open a file with the associated program that Windows assigned. So, if you use it to open up a text file Invoke-item something.txt that file will open visually with notepad in front of your eyes. The true bad magician trick though, if you have a whole folder of 300 text documents and you navigate to the directory and type: Invoke-Item *.txt Then all 300 text documents open at once. I’ve only ever used this on a local machine and have no idea if it can be used remotely, except in partnering with Invoke-Command (as you wouldn’t use it with Invoke-Expression because you use Invoke-Expression for things that don’t have builtin commandlets.) EDIT: I did some research and this in fact can be used remotely, I personally wouldn’t recommend it unless you are in Computer 101 with your friends.
5) The Mighty ‘&’ Symbol- I like the ‘&’ ability within Powershell. Within Powershell the & is called the call operator and it allows you to execute a command, script or function. This for all intensive purposes will do exactly what you want. It’s quick and dirty and as long as you structure it good, you will have no problem. If you want to simply run an executable with Powershell, you can execute: & “d:\scriptlocation\awesomeprogram.exe” and it will run it. Very quick and dirty, but with no real troubleshooting or logic built in.
6) [Diagnostics.Process] Start()- Now THIS is a nice way to perform a task in clean method. One of my favorite reasons for using Powershell is creating .NET usage on the fly just by calling it. No need to build up variables, as in C# because Powershell does all the work for you. You can read about the .NET class here and I suggest looking into it. You can build a complete process for executing an executable, complete with error control and everything.
$sdp.StartInfo.UseShellExecute = $
$sdp.WaitForExit() ## LOVE this WaitForExit
I love the “Wait for exit” portion of this, because you can execute it and it will wait until the code as completed before it moves on. Perfect for logic and/or loops!