Learn Easier Way to Build Command for PowerShell.exe

Doctor Scripto

Summary: Learn how to parse a here-string with Windows PowerShell.

Honorary Scripting Guy, Sean Kearney, is here to show you a neat little trick.

Anyone who has ever scheduled a PowerShell task knows that if you want to launch a cmdlet directly in PowerShell, you would launch it like this:

PowerShell.exe –ExecutionPolicy Bypass –command ‘Get-ChildItem’

No challenge there. It also does not end there. You can add some down-right complex stuff in there, for example:

PowerShell.exe –executionpolicy Bypass –command ‘Set-ExecutionPolicy Bypass;Import-Module DeployImage; New-WindowsPeImage’

This is an example of something I was playing with in the DeployImage module when launching PowerShell automatically.

Then again, in many cases, a script would be much easier to run if you knew where the script actually was. The challenge I ran into was trying to put together really complex command while typing it in the parameter.

Then it dawned on me, “Why not write it as a script to make sure it works?” Yeah, that was pretty obvious. But how would I flip it back to a command for the PowerShell.exe? This is where a here-string is perfect!

Here I have an example of something that I was actually doing. I needed to take the following script and flip it to a command in the PowerShell.exe.

Set-ExecutionPolicy -executionpolicy Bypass

$USBDisk=(Get-Disk | Where-Object { $_.BusType -eq ‘USB’ -and ‘$_.IsActive’ })

$DriveLetter=($USBDisk | Get-Partition).DriveLetter

Set-Location ($DriveLetter+’:\DeployImage\’)

Import-Module ($DriveLetter+’:\DeployImage\DeployImage.Psd1)’

I then stored it as a here-string:

$PowerShellScript=@’

Set-ExecutionPolicy -executionpolicy Bypass

$USBDisk=(Get-Disk | Where-Object { $_.BusType -eq ‘USB’ -and ‘$_.IsActive’ })

$DriveLetter=($USBDisk | Get-Partition).DriveLetter

Set-Location ($DriveLetter+’:\DeployImage\’)

Import-Module ($DriveLetter+’:\DeployImage\DeployImage.Psd1)’

‘@

Now all we need is to find where each line terminates and switch it with a semicolon.

We can examine each byte in the here-string in the following manner:

[byte][char]($PowerShellScript)[10]

We would eventually notice that two characters at the end of each line are:

  • Ascii 13 (Return)
  • Ascii 10 (Linefeed)

Although we can’t see or type these, we can represent these as a string in the following manner:

$CRLF=[char][byte]13 + [char][byte]10

Armed with this, we can now do something really neat—use the Replace method and switch out each carriage return/linefeed with a semicolon:

$PowerShellCommand=$PowerShellScript.replace($CRLF,’;’)

You can now use this in whatever fashion suits you—even if that means dropping it into the clipboard!

Have fun and enjoy!

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, always remember that with great PowerShell comes great responsibility.

Sean Kearney, Honorary Scripting Guy, Cloud and Datacenter Management MVP

0 comments

Discussion is closed.

Feedback usabilla icon