Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Windows PowerShell Scripting (Second Edition)

You're reading from   Mastering Windows PowerShell Scripting (Second Edition) One-stop guide to automating administrative tasks

Arrow left icon
Product type Paperback
Published in Oct 2017
Publisher Packt
ISBN-13 9781787126305
Length 440 pages
Edition 2nd Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Chris Dent Chris Dent
Author Profile Icon Chris Dent
Chris Dent
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Preface 1. Introduction to PowerShell FREE CHAPTER 2. Working with PowerShell 3. Modules and Snap-Ins 4. Working with Objects in PowerShell 5. Operators 6. Variables, Arrays, and Hashtables 7. Branching and Looping 8. Working with .NET 9. Data Parsing and Manipulation 10. Regular Expressions 11. Files, Folders, and the Registry 12. Windows Management Instrumentation 13. HTML, XML, and JSON 14. Working with REST and SOAP 15. Remoting and Remote Management 16. Testing 17. Error Handling

PowerShell on Linux

PowerShell for Linux is, at least at the time of writing, in alpha. The current release is still worth installing even if only to see what having a unified shell may look like.

What about Cygwin?
PowerShell is not the first to give a hint of a single shell across different operating systems. However, until PowerShell matured, it was a serious challenge to manage Windows and Microsoft-based systems from the command line alone.

Some familiarity with Linux is assumed during this process.

Installing PowerShell

This installation is based on PowerShell 6, alpha 12 as the latest at the time of writing. The package can be downloaded from GitHub with yum, which will also install the dependencies (https://github.com/PowerShell/PowerShell/releases/latest):

  1. The following command will install PowerShell and any dependencies (libicu, libunwind, and uuid):
sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.12/powershell-6.0.0_alpha.12-1.el7.centos.x86_64.rpm 

alpha 12 is the latest release but it may not be when you read this.

  1. PowerShell can be immediately started by running the following command:
powershell 
  1. Create a few files in the home directory as a test:
Set-Location ~ 
1..10 | ForEach-Object { New-Item $_ -ItemType File } 
  1. The previous command creates 10 empty files named 1 to 10 (with no file extension). Ensure that the new files are now visible using Get-ChildItem:
Get-ChildItem 
ls versus Get-ChildItem:
On Windows, ls (list) in PowerShell is an alias for Get-ChildItem. On Linux, ls is the original command. See Get-Alias -Definition Get-ChildItem to view what still is.

Where are the PowerShell files?

Several of the following used paths are specific to the installed release (in this case, alpha 12).

As with PowerShell on Windows, the PSHOME variable shows where PowerShell itself has been installed:

PS> $PSHOME 
/opt/microsoft/powershell/6.0.0-alpha.12 

The paths for module installation may be viewed using the environment variables:

PS> $env:PSMODULEPATH -split ':' 
/home/psuser/.local/share/powershell/Modules 
/usr/local/share/powershell/Modules 
/opt/microsoft/powershell/6.0.0-alpha.12/Modules 
Case sensitivity
Linux has a much higher regard for case than Windows. Environment variables, file paths, executables, and so on, are case sensitive. The previously used variable name must be written in uppercase.
Use Get-ChildItem to list all of the environment variables using the following command:
Get-ChildItem env:

Changing the shell

Once installed, PowerShell is visible in the list of available shells:

chsh -l 

Set PowerShell as the default shell for the current user:

chsh 
New shell [/bin/bash]: /usr/bin/powershell 

Profiles

The current user profile on Linux resides under the home directory:

~/.config/powershell 

Two profiles can be created: CurrentUserCurrentHost (Microsoft.PowerShell_profile.ps1) and Current User (profile.ps1). Inspecting the automatic variable, $PROFILE shows the first of these:

  1. The directory will need to be created prior to use; the following command creates it:
New-Item ~/.config/powershell -ItemType Directory 
  1. Create a simple profile file by sending a string to a file:
‘Write-Host “Welcome to PowerShell” -ForegroundColor Green’ |
Out-File .config/powershell/profile.ps1
  1. The AllUser profile may be created under PowerShell's installation directory, in this case, alpha 12, as this is the version I have installed:
/opt/microsoft/powershell/6.0.0-alpha.12 
  1. Writing to this area of the filesystem requires the root privileges:
sudo vi /opt/microsoft/powershell/6.0.0-alpha.12/profile.ps1 
  1. Inside vi, press i to enter insert mode and then type the following:
Write-Host 'This is the system profile' -ForegroundColor Yellow 
  1. Once completed, press Esc, then type :wq to save and quit vi.
  2. As with PowerShell on Windows, this will be executed before a user-level profile that shows the following in the console when the shell is started:
This is the system profile 
Welcome to PowerShell 

Multiplatform scripting

PowerShell on Linux (and macOS) has a long way to go to reach maturity. Our experience writing for these systems has to make a similar journey.

One of the most important facets is that Linux and macOS run PowerShell Core. It lacks some features we may have become used to when writing for Windows.

Line endings

Windows editors, including ISE, tend to use a carriage return followed by linefeed (\r\n or `r`n) at the end of each line. Linux editors use linefeed only (\n or `n).

Line endings are less important if the only thing reading the file is PowerShell (on any platform). However, if a script is set to executable on Linux, a sha-bang must be included and the line-ending character used must be linefeed only.

For example, a created as follows named test.ps1 must use \n to end lines:

#!/usr/bin/env powershell 
Get-Process 

The first line is the sha-bang and lets Linux know which parser to use when executing the shell script.

Once created, chmod may be used to make the script executable outside of PowerShell:

chmod +x test.ps1 

After being made executable, the script may be executed from bash with the full path or a relative path:

./test.ps1 
Editor defaults
PowerShell ISE uses carriage return followed by line feed (\r\n). This behavior is by design and cannot be changed.
Visual Studio Code uses \r\n for line endings by default. This may be changed in User Settings by adding the following command:
"files.eol": "\n"

File encoding

Windows editors, including ISE, tend to save files using what is commonly known as ANSI encoding; this is more correctly known as Windows-1252.

As Windows-1252 is a Microsoft native format, it may be more appropriate to save files in a universally accepted format such as UTF8.

Editor defaults
PowerShell ISE defaults to saving files in UTF8 with a Byte Order Mark (BOM).
Visual Studio Code saves files using UTF8 (without a BOM) by default. The setting may be changed in User Settings by adding "files.encoding": "utf8bom".

Path separator

Testing shows that PowerShell on Linux is forgiving about path separators; that is, Microsoft Windows uses the backslash (\), where Linux uses a forward slash (/).

If anything outside of PowerShell (including native commands) is to be used, a correct separator should be chosen.

The Join-Path command will merge path elements using the correct separator for each platform. Manual path construction (based on merging strings) should be avoided.

Example

The following function uses the System.Net.NetworkInformation namespace to discover IPv4 address information. This allows us to return the same thing whether it is run on Windows or Linux.

If it were Windows only, we might have used WMI or the Get-NetIPConfiguration command. Creating something to work on both operating systems is more challenging:

function Get-IPConfig { 
    [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | ForEach-Object { 
        $ipProperties = $_.GetIPProperties() 
             
        $addresses = $ipProperties.UnicastAddresses | 
            Where-Object { 
                $_.Address.AddressFamily -eq 'InterNetwork' 
            } | ForEach-Object { 
                "$($_.Address) $($_.IPv4Mask)" 
            } 
 
        $gateway = $ipProperties.GatewayAddresses.Address | 
            Where-Object { 
                $_.AddressFamily -eq 'InterNetwork' -and  
                $_ -ne '0.0.0.0' 
            } 
 
        [PSCustomObject]@{ 
            Name      = $_.Name 
            Id        = $_.Id 
            Addresses = $addresses 
            Gateway   = $gateway 
        } 
    } | Where-Object { $_.Addresses } 
} 
Get-IPConfig 
You have been reading a chapter from
Mastering Windows PowerShell Scripting (Second Edition) - Second Edition
Published in: Oct 2017
Publisher: Packt
ISBN-13: 9781787126305
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image