Open Source PowerShell – Part 3


Summary: Pass and return data correctly between Bash and Open Source PowerShell.

Hey, Scripting Guy! Question Could you show me some examples of actually passing and returning values between PowerShell and Bash?

Hey, Scripting Guy! Answer Honorary Scripting Guy, Sean Kearney, is here today and we’ll do exactly that. It isn’t difficult to actually to do this either, but there are two things to keep in mind to make all of this easier.

When working with data:

  • PowerShell lives in the world of Objects
  • Bash lives in the world of text

If you keep this in mind, much of the challenge is in just understanding that when PowerShell parameters are set, they should be typed correctly by using the appropriate .NET class.

You’ll also need to keep in mind that when returning objects to Bash (or any other text-based environment like even CMD or VBScript in Windows as an example), the result should be a string.

Look at this simple script in PowerShell as an example. The script does the following:

  • Receives three parameters
  • Does a simple Write-Host to the screen to echo the values

Returns an exit code of 42 (Well, we have to have a little fun here!)

param
(
$user,
$birthday,
$age
)

Write-Output “The Username is $user”
Write-Output “Their Birthday is on $birthday”
Write-Output “The age of the user is $age”

Exit 42

We can start this PowerShell script from Bash (We’ll call it fooparam.ps1), and pass three values in the following manner:

Results of the executed script

What you can see is some basic parameter passing. Out of the box, it works quite fine.

But, consider this. Perhaps later in the script the value for $Birthday is meant to be processed as a proper [datetime] or that PowerShell is expecting an actual Integer. A well written script should normally deal with this.

In PowerShell, it is very easy to forget this sometimes because it can automatically see a ‘123’ and realize that is an [int].  Or, that ‘Loud Noisy Parrot’ is a [string]. We don’t normally need to pull off any extra effort to make it happen.

In Bash (like in VBScript), all of the output is just text. It has no clue about the difference between [System.Management.Automation.PSCredential] or [String]. Bash only receives and sends text.

In PowerShell, you’ll need to make sure the correct definition and validation of parameters is in there.   But, that’s the part that most of us will be missing.

It’s the actual returning of data that can trip us up. Take, for example, this little Script that simply returns some assigned variables to the screen.

$c=New-Object System.Management.Automation.PsCredential -ArgumentList ('me',(Convertto-Securestring -asPlainText -force 'badpass'))

$Date=Get-Date
$Name='John Smith'

Return [pscustomobject]@{Credential=$c;Date=$Date;Name=$name}

If you ran this script directly from Bash, you’d see the output in default string values. For example, DateTime produces a full suite of the date and time as it’s default String object.

In the case where Object is more complex than a simple string, we get the default .NET class name, such as System.Management.Automation.PSCredential.

Bash returns the default .NET class name as string values

But, this can be dealt with quite easily. When returning an Object to Bash, ensure that you clean up the String output to what Linux/macOS might be expecting. A Password or the User ID (or perhaps both) might be required for the Bash script that calls up PowerShell.

It could also be that the calling environment only wants the exact date in “Month Day Year” format. Our challenge is quite simple. Validate and clean up the output to correct strings.

Here is the sample script that’s slightly modified to clean up the output for the calling Bash system.

$c=New-Object System.Management.Automation.PsCredential -ArgumentList ('me',(Convertto-Securestring -asPlainText -force 'badpass'))

$Date=Get-Date
$Name='John Smith'

$Password=$c.getnetworkcredential().
$ShortDate=Get-Date $Date -format ‘MM/dd/yyyy’
$LowerName=$Name.tolower()

Return [pscustomobject]@{Credential=$Password;Date=$ShortDate;Name=$Lowername}

Bash returns credential, date, and name

With very little change to the script, we can keep the string output clean and useful for the Bash environment.

Stop by next time as we look at getting PowerShell remote to work between Linux and Windows.

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

Comments (0)

Skip to main content