Powershell Function Start-Proc

The gentlemen over at the Power Scripting Podcast recently posted a tip on how to start processes in Powershell.

I had run into the same problem they had. How do you pass in both an executable and its arguments to the Start method of a System.Diagnostics.Process object.

Something like this works fine in Powershell:

[System.Diagnostics.Process]::Start(“calc”)

But as soon as you try to pass in something like “ipconfig /all” the thing blows up.

Turns out you can pass in arguments a couple of ways. The Powerscripting guys noted that if you pass in the argument of the executable as a second argument to Start, it will work great.

[System.Diagnostics.Process]::Start(“ipconfig”,”all”)

However, there is another way if you want to get a little bit more fancy and do things like hide windows or redirect output from StdOut or StdErr.

You can use a System.Diagnostic.ProcessStartInfo object. Using get-member we can take a look at all the options we have for such a thing.

   1: PS 124 >  $si = New-Object System.Diagnostics.ProcessStartInfo
   2: PS 125 >  $si | gm  -type property | select Name
   3:  
   4: Name
   5: ----
   6: Arguments
   7: CreateNoWindow
   8: Domain
   9: EnvironmentVariables
  10: ErrorDialog
  11: ErrorDialogParentHandle
  12: FileName
  13: LoadUserProfile
  14: Password
  15: RedirectStandardError
  16: RedirectStandardInput
  17: RedirectStandardOutput
  18: StandardErrorEncoding
  19: StandardOutputEncoding
  20: UserName
  21: UseShellExecute
  22: Verb
  23: Verbs
  24: WindowStyle
  25: WorkingDirectory

Lots of goodness here that we can play with. Once you build up the ProcessStartInfo object, you pass that whole object in as the arg to the Start method of system.diagnostics.process.

I put together a quick function to show how this could be used more generically.

   1: function Start-Proc  {
   2:     param (
   3:             [string]$exe = $(Throw "An executable must be specified"),
   4:             [string]$arguments,
   5:             [switch]$hidden,
   6:             [switch]$waitforexit
   7:             )    
   8:     
   9:     # Build Startinfo and set options according to parameters
  10:     $startinfo = new-object System.Diagnostics.ProcessStartInfo 
  11:     $startinfo.FileName = $exe
  12:     $startinfo.Arguments = $arguments
  13:     if ($hidden){
  14:                 $startinfo.WindowStyle = "Hidden"
  15:                 $startinfo.CreateNoWindow = $TRUE
  16:                 }
  17:     $process = [System.Diagnostics.Process]::Start($startinfo)
  18:     if ($waitforexit) {$process.WaitForExit()}
  19:     
  20: }
  21:  
  22:  Start-Proc calc
  23:  Start-Proc calc -waitforexit
  24:  Start-Proc -exe ipconfig -arguments /all
  25:  Start-Proc ipconfig /all
  26:  Start-Proc ipconfig /all -hidden

I used the alias Start-Proc so that it would not collide with the PSCX Cmdlet Start-Process.

They have done the same writing their CmdLet  in C#, but with all kinds of options.

   1: PS 130 >  gcm Start-Process | fl *
   2:  
   3:  
   4: DLL              : C:\Program Files (x86)\PowerShell Community Extensions\Pscx.dll
   5: Verb             : Start
   6: Noun             : Process
   7: HelpFile         : Pscx.dll-Help.xml
   8: PSSnapIn         : Pscx
   9: ImplementingType : Pscx.Commands.StartProcessCommand
  10: ParameterSets    : {[[-Path] <String>] [[-Arguments] <String>] [-Verb <String>] [-WorkingDirectory <String>] [-Credential <PSCredential>] [-NoShellExecute] [-NoWindow]
  11:                    [-WindowStyle <ProcessWindowStyle>] [-LoadUserProfile] [-WaitTimeout <Int32>] [-Boost] [-Priority <ProcessPriorityClass>] [-Verbose] [-Debug] [-Error
  12:                    Action <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] [-WhatIf] [-Confirm], [[-ScriptBlock] <ScriptBlock>
  13:                    ] [-NoProfile] [-WorkingDirectory <String>] [-Credential <PSCredential>] [-NoShellExecute] [-NoWindow] [-WindowStyle <ProcessWindowStyle>] [-LoadUser
  14:                    Profile] [-WaitTimeout <Int32>] [-Boost] [-Priority <ProcessPriorityClass>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <St
  15:                    ring>] [-OutVariable <String>] [-OutBuffer <Int32>] [-WhatIf] [-Confirm]}
  16: Definition       : Start-Process [[-Path] <String>] [[-Arguments] <String>] [-Verb <String>] [-WorkingDirectory <String>] [-Credential <PSCredential>] [-NoShellExecute]
  17:                     [-NoWindow] [-WindowStyle <ProcessWindowStyle>] [-LoadUserProfile] [-WaitTimeout <Int32>] [-Boost] [-Priority <ProcessPriorityClass>] [-Verbose] [-D
  18:                    ebug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] [-WhatIf] [-Confirm]
  19:                    Start-Process [[-ScriptBlock] <ScriptBlock>] [-NoProfile] [-WorkingDirectory <String>] [-Credential <PSCredential>] [-NoShellExecute] [-NoWindow] [-W
  20:                    indowStyle <ProcessWindowStyle>] [-LoadUserProfile] [-WaitTimeout <Int32>] [-Boost] [-Priority <ProcessPriorityClass>] [-Verbose] [-Debug] [-ErrorAct
  21:                    ion <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] [-WhatIf] [-Confirm]
  22:  
  23: Name             : Start-Process
  24: CommandType      : Cmdlet
  25: Visibility       : Public
Advertisements

2 Responses to “Powershell Function Start-Proc”

  1. Hal Rottenberg Says:

    Thanks for the elaboration! We’ll be sure to tip the hat your way in the next show.

  2. PowerScripting Podcast Episode 21, "One-half of Jeffrey Snover" « PowerScripting Podcast Says:

    […] Andy’s post about Start a process […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: