Skip to content

New Practices for PowerShell Core #68

@Jaykul

Description

@Jaykul

There are going to be a few new things which we need to keep in mind to make our scripts work across multiple platforms. Windows, Nano, Linux, FreeBSD and OSX, ARM and IoT ...

Best Practices for Scripts and Modules:

  1. Don't put aliases into scripts. Aliases are (currently) different on each platform. Double-check using a tool like ResolveAlias.
  2. Add the shebang to scripts: #!/usr/bin/env pwsh (or the more fragile: #!/usr/bin/pwsh -noprofile)
  3. Save scripts with Unix style line endings, or the shebang will not work.
    Mac and Windows both accept \n but the Unix shell interpreter will choke on the carriage return in the shebang. If you don't add the shebang, this doesn't matter. Note that you can always fix it:
    Set-Content $scriptPath ((Get-Content $scriptPath -raw) -replace "\r") -Encoding utf8
  4. Always encode in utf-8.
  5. Be careful with paths. Use forward slashes. Use Join-Path and Split-Path
  6. ONLY use the new -PSEdition value allowed for #requires or module manifests, when you need to restrict to Core, not for Desktop, since it only works in PowerShell 5.1+
  7. ALWAYS use three digits for versions (i.e. 5.0.0, not 5.0) because they may be parsed as SemanticVersion which currently doesn't work unless you provide the patch version explicitly.
  8. [System.Environment]::CurrentDirectory doesn't in .Net Core. But if you need to call path-sensitive .Net APIs, you need to use [System.IO.Directory]::SetCurrentDirectory( (Get-Location -PSProvider FileSystem).ProviderPath ) to update the environment. Note that PowerShell sets the working directory fine when launching apps...

Finally: Test the code on Linux and Nano, if possible. There are differences.

ProTips

Use this in your profile: $PSDefaultParameterValues["Out-File:Encoding"] = "UTF8" to help with 1.

Don't forget you can install PowerShell 6 alphas side-by-side on Windows (they install to Program Files, and don't use the same profile or module paths). You don't have to set up docker or a VM to get started. It's just that in that scenario, you have access to things you won't have access to on Unix (like Set-ExecutionPolicy), so you should test elsewhere before publishing.

Cmdlet Differences

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions