Create Simple PowerShell Host

by Aug 12, 2016

PowerShell 2 or better

There are sometimes a lot of good reasons why you’d like to run a script by a different host. powershell.exe might be blocked by an AppLocker policy, or you’d like to run a PowerShell script invisible, without displaying a console.

Any PowerShell host can execute PowerShell scripts, and thanks to Add-Type, it is easy to use PowerShell to compile such a host. When you run this code, you end up with a new console application called PSHost.exe on your desktop:

# this is the C# code for a simple PowerShell host
$code = @'
using System.Management.Automation;  
using System.Collections.ObjectModel;

namespace PowerSaw {  
  class Program {
    static void Main(string[] args) {
      if (args.Length == 0) return;
      using (PowerShell ps = PowerShell.Create()) {
        string code = System.IO.File.ReadAllText(args[0]);
        ps.AddScript(code);
        Collection<PSObject> psobject = ps.Invoke();
      }
    }
  }
}
'@

# parameters for compilation to a console EXE
$params = @{
  OutputAssembly = "$home\Desktop\PSHost.exe"
  OutputType = 'ConsoleApplication'
  ReferencedAssemblies = [PSObject].Assembly.Location
  TypeDefinition = $Code
}

# create an EXE file
Add-Type @params

# show EXE file
explorer.exe /select,$params.OutputAssembly

Now, you can use this simple host to run arbitrary PowerShell scripts. Simply pass the script path as argument to the EXE. Here is an example (assuming that you ran the above code and have PSHost.exe on your desktop):

$Desktop = "$home\desktop"
$ScriptPath = "$Desktop\getservices.ps1"
'Get-Service | Out-GridView -Wait' | Out-File -FilePath $ScriptPath -Encoding UTF8

& "$Desktop\pshost.exe" $ScriptPath

Note that the simple PowerShell host created in this example has no output logic. So use it to call PowerShell scripts that just do things, or pipe the results to some output platform such as Out-GridView. Note also that the host will close as soon as the script is done.

Twitter This Tip! ReTweet this Tip!