Archive for the “Powershell Community Extension” Category

I have had a custom prompt for quite some time now. I am pretty sure I got started with by using the custom prompt from the PowerShell Community Extensions.

I have tweaked it here and there and apparently at some point I dropped the part of the default prompt that used $NestedPromptLevel.

This wasn’t a problem until I was reading about some great debugging techniques in PowerShell in Action by Bruce Payette which used the Nested Prompt feature.

This was quickly fixed with the following:

   1: if ($NestedPromptLevel -gt 0) {$myPrompt = "PS-nested >>"}
   2: Write-Host ($myPrompt)  

Now my nested prompt works quite well. When I hit S to suspend, I get dropped into my custom nested prompt.

   1: PS 10 >  notepad
   2: PS 11 >  gps notepad | kill -confirm
   3:  
   4: Confirm
   5: Are you sure you want to perform this action?
   6: Performing operation "Stop-Process" on Target "notepad (4512)".
   7: [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): S
   8: PS-nested >> gps notepad
   9:  
  10: Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
  11: -------  ------    -----      ----- -----   ------     -- -----------
  12:      57       6     2000       9884    78     0.08   4512 notepad
  13:  
  14:  
  15: PS-nested >>
  16: PS-nested >>
  17: PS-nested >>
  18: PS-nested >> exit
  19:  
  20: Confirm
  21: Are you sure you want to perform this action?
  22: Performing operation "Stop-Process" on Target "notepad (4512)".
  23: [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): Y
  24: PS 14 >

Note to self: when messing with defaults, don’t delete stuff when you don’t know what they are for.

 

Andy

Comments No Comments »

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

Comments 5 Comments »