Hostwinds Tutorials

Search results for:


Table of Contents


What is PowerShell?
Why Linux PowerShell?
Installing Linux PowerShell
Additional Linux PowerShell Examples
Conclusion

Using PowerShell with Linux

Tags: Cloud Servers,  Dedicated Server 

What is PowerShell?
Why Linux PowerShell?
Installing Linux PowerShell
Additional Linux PowerShell Examples
Conclusion

What is PowerShell?

PowerShell is a cross-platform solution commonly used for automating the management of computer systems but it can be used for general coding as well. PowerShell is made up of a command-line shell, a scripting language, and a configuration management framework. PowerShell runs on Windows, Linux, and the macOS operating systems. Because of fundamental differences in operating systems, some PowerShell commands (called cmdlets) do not make sense. For example, the PowerShell Get-Acl cmdlet is not applicable for Linux systems in that the Linux file system does not use NTFS access control lists (ACLs). To view a list of the available Linux PowerShell cmdlets, run Get-Command.

Why Linux PowerShell?

In Linux, the output of one command can be piped into another command. For example:

ls | sort -r | more

This reverse sorts the contents of the current directory and paginates the list (if necessary). That is, the data stream output of the ls command is piped to the sort command whose data stream output is then piped to the more command. The PowerShell analog of this is as follows:

Get-ChildItem | Sort-Object -Descending | Out-Host -Paging

Which begs the question, why would you want to use PowerShell over the native version? One key reason is that objects, and not simple data streams, are piped between PowerShell cmdlets. For example, there's no need to parse text to extract information from another output stream. And because PowerShell objects generally have a plethora of properties associated with them, you can do some fairly powerful things relatively easily. For example, say you would like to find the PID of the cron service. A first attempt might be as follows:

ps -aux | grep cron

This results in output similar to the following:

root      1041  0.0  0.1 126384  1584 ?        Ss   22:25   0:00 /usr/sbin/crond -n
root      3519  0.0  0.0 123360   728 ?        Ss   23:01   0:00 /usr/sbin/anacron -s
root      4089  0.0  0.0 112808   976 pts/1    R+   23:09   0:00 grep --color=auto cron

The cron PID appears to be 1041 although it's hard to tell without seeing the table headers. Assuming this is the case, we need to access the second column in the first line. The first step might be to reduce excessive whitespace:

ps -aux | grep cron | tr -s ' '

This yields:

root 1041 0.0 0.1 126384 1584 ? Ss 22:25 0:00 /usr/sbin/crond -n
root 3519 0.0 0.0 123360 728 ? Ss 23:01 0:00 /usr/sbin/anacron -s
root 4167 0.0 0.0 112808 972 pts/1 R+ 23:11 0:00 grep --color=auto cron

Now we can isolate the second column with cut:

ps -aux | grep cron | tr -s ' ' | cut -d ' ' -f 2

Which produces:

1041
3519
4274

Finally, we can grab the first line, as follows, to get the desired result, namely 1041:

ps -aux | grep cron | tr -s ' ' | cut -d ' ' -f 2 | head -1

Using the fact that PowerShell cmdlets output objects rather than data streams, the PowerShell version of the above is simply:

(Get-Process -Name crond).Id

In this case, Get-Process -Name crond returns an object representing the cron process. This object has a series of useful properties, one of which is the process Id (or PID). To access a property of a PowerShell object, you can wrap it in parentheses and then use standard "dot" notation, as shown.

Installing Linux PowerShell

To install PowerShell on your favorite flavor of Linux, refer to Microsoft's Installing PowerShell on Linux. If your Linux distribution is not listed, consider Alternate ways to install PowerShell on Linux.

As an example, the following four commands install the latest version of PowerShell on Centos 7:

# Optionally update all software packages:
  sudo yum -y update
  
# Register the Microsoft repository:
  curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum.repos.d/microsoft.repo
    
# Install PowerShell:
  sudo yum -y install powershell
    
# Start PowerShell:
  pwsh

As can be seen, installing PowerShell is straightforward.

Additional Linux PowerShell Examples

One key technique is determining what properties a PowerShell object actually has. This can easily be accomplished with the Get-Member cmdlet. For example, to determine the properties of a PowerShell process object, you can use:

Get-Process | Get-Member -Force

This reveals that there's a Path property for process objects. Thus, we can use it to list the top 10 processes, with respect to CPU usage, as follows:

Get-Process | Sort-Object -Property CPU | Select-Object -Property Name, Path, CPU -Last 10

This produces output similar to the following:

Name           Path                                CPU
----           ----                                ---
xfwm4          /usr/bin/xfwm4                     1.95
systemd        /usr/lib/systemd/systemd           3.63
rngd           /usr/sbin/rngd                     7.39
xfce4-terminal /usr/bin/xfce4-terminal            9.35
xrdp           /usr/sbin/xrdp                    22.05
ksoftirqd/0                                      26.21
pwsh           /opt/microsoft/powershell/7/pwsh  27.37
rcu_sched                                        45.44
Xvnc           /usr/bin/Xvnc                     59.27
NetworkManager /usr/sbin/NetworkManager         955.19

Although useful, we may want to calculate an overall system usage metric. A first cut might be to simply sum the non-paged memory (NPM), page memory (PM), working set (WS), and CPU usage values. That is, we define our overall usage metric as follows:

OverallUsage = NPM + PM + WS + CPU.

In PowerShell, this can be accomplished as follows:

Get-Process | Select-Object -Property @{Label = 'OverallUsage'; Expression = {$_.NPM + $_.PM + $_.WS + $_.CPU}}

The @{} hash table (i.e., key/value pairs) allows us to define a property called OverallUsage whose definition is the expression shown above. In this expression, $_ represents a pipeline object. In this case, an individual process object that Get-Process returns (one per running Linux process). We then sum the four properties. This results in the following (first few lines):

    OverallUsage
    ------------
          520192
       815104.03
          794624
         1093632
      4902912.01
      3330048.37

Now we can combine these two concepts as follows:

Get-Process | Select-Object -Property Name, Path, @{Label = 'OverallUsage'; Expression = {$_.NPM + $_.PM + $_.WS + $_.CPU}} | Sort-Object -Property OverallUsage -Bottom 10

This produces a top 10 overall usage table, similar to the following:

Name                Path                             OverallUsage
----                ----                             ------------
Thunar              /usr/bin/thunar                    14073856.2
xfce4-power-manager /usr/bin/xfce4-power-manager       15970304.3
xfce4-panel         /usr/bin/xfce4-panel               16195584.9
xfdesktop           /usr/bin/xfdesktop                17588224.59
tuned               /usr/bin/python2.7                18898945.66
yum-cron            /usr/bin/python2.7                 22335488.2
xfce4-terminal      /usr/bin/xfce4-terminal            23642123.4
xrdp                /usr/sbin/xrdp                    26570776.34
Xvnc                /usr/bin/Xvnc                     82710598.14
pwsh                /opt/microsoft/powershell/7/pwsh 298852382.66

And if you prefer to display rounded usage values, you can use:

Get-Process | Select-Object -Property Name, Path, @{Label = 'OverallUsage'; Expression = {[Math]::Round($_.NPM + $_.PM + $_.WS + $_.CPU)}} | Sort-Object -Property OverallUsage -Bottom 10

The [Math]::Round() function is used to round the individual sums to their nearest whole values.

Conclusion

There are plenty of scenarios where standard Linux commands make more sense than PowerShell cmdlets, and in a number of cases, the other way around but what's particularly appealing is that you can use both paradigms together. As a simple example, consider:

Get-Process | Select-Object -Property Name, Path, Responding, Id |  grep cron

This produces:

anacron    /usr/sbin/anacron    True   3018
crond      /usr/sbin/crond      True   1033
yum-cron   /usr/bin/python2.7   True   4760

The third column indicates whether or not the process is responsive.

As you can see, PowerShell and the combination of PowerShell with Linux commands provide ample opportunity for solving and simplifying various problems and tasks.

Written by Karlito Bonnevie  /  April 26, 2022