PowerShell script in a .bat file

How do you put PowerShell code into a batch/cmd file without having to also have a separate .ps1 file?

I got this question recently from one of our field guys and thought I would blog about the trick publicly.

This is actually very simple:

  1. Take the PowerShell script.
  2. Remove all the comments ( everything that starts with #).
  3. Put ; at the end of each line.
  4. Remove all line breaks.
  5. Supply the string you get as the -command parameter for powershell.exe.

The reason for all of this is that powershell.exe (the executable which allows you to run any PowerShell code allows you to either start an external .ps1 script file (which often creates additional complexity of having to maintain and ship 2 files) or execute a single line of PowerShell code as the -command parameter. Hence the requirement to flatten the script and turn something like this:

#iterate numbers 1 through 10
1..10 | foreach-object {
# just output them
"Current output:"
$_
}

into:

powershell.exe -command "1..10 | foreach-object { "Current output:"; $_; }

See also this blog post by MoW on making PowerShell pass its exit code to command files.

Tags: , , ,

3 Responses to “PowerShell script in a .bat file”


  1. 1 Stuart June 27, 2008 at 11:59 am

    As far as I can see, the double quotes will get the command interpreter confused, so you will have to escape them – as in

    powershell.exe -command “1..10 | foreach-object { \”Current ou
    tput:\”; $_; }”

    If you don’t escape them you get the message:

    The term ‘Current’ is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.
    At line:1 char:33
    + 1..10 | foreach-object { Current <<<< output:; $_; }

    You also missed off the closing double quote, but that didn’t seem to make a difference.

    Thanks for the post though, it could be useful for short scripts.

  2. 2 Andy June 28, 2008 at 12:47 am

    powershell.exe -command “1..10 | foreach-object { ‘Current output:’; $_; }”

  3. 3 Bruce Payette June 29, 2008 at 12:27 am

    One way to completely avoid the quoting problem is to use the -encoded parameter on powershell.exe. This takes a Base64 encoded string, decodes it and then executes it. For example, we’ll put some code in a script block (since it will be syntax checked) instead of a simple string:

    PS (41) > $code = {
    >> #iterate numbers 1 through 10
    >> 1..10 | foreach-object {
    >> # just output them
    >> “Current output:”
    >> $_
    >> }
    >>
    >> }
    >>

    Now encode the command:

    PS (42) > $encoded = [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($code))

    The result of this looks like:

    PS (43) > $encoded
    MQAuAC4AMQAwACAAfAAgAGYAbwByAGUAYQBjAGgALQBvAGIAagBlAGMAdAAgAHsACgAjACAAagB1AHMAdAAgAG8AdQB0AHAAdQB0ACAAdABoAGUAbQAKACI
    AQwB1AHIAcgBlAG4AdAAgAG8AdQB0AHAAdQB0ADoAIgAKACQAXwAKAH0ACgA=

    Then run it:

    (CXT: win7) (STA-ISS) (44) > powershell -encoded MQAuAC4AMQAwACAAfAAgAGYAbwByAGUAYQBjAGgALQBvAGIAagBlAGMAdAAgAHsACgAjACA
    AagB1AHMAdAAgAG8AdQB0AHAAdQB0ACAAdABoAGUAbQAKACIAQwB1AHIAcgBlAG4AdAAgAG8AdQB0AHAAdQB0ADoAIgAKACQAXwAKAH0ACgA=

    BTW – PowerShell has built-in support for this so when you call powershell from powershell with a scriptblock, the script block is automatically encoded and passed to the child process:

    (CXT: win7) (STA-ISS) (46) > powershell { “Hi there. Today is ” + (get-date).DayOfWeek }
    Hi there. Today is Saturday

    -bruce
    ——————–
    Principal Developer, Windows PowerShell Team
    Microsoft


Leave a Reply




View Dmitry Sotnikov's profile on LinkedIn

Follow Dmitry Sotnikov at Twitter

My Recent Tweets

Archives

See you at:

Legal

The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer Quest Software or anyone else for that matter. All trademarks acknowledged.

© 2007 Dmitry Sotnikov

Pages

 

June 2008
M T W T F S S
« May   Jul »
 1
2345678
9101112131415
16171819202122
23242526272829
30