Notes on PowerShell

Posted in administration tools with tags administration dotnet powershell windows -

Summary

PowerShell is an object-oriented shell that is built on .NET, and the custom programming language that runs within that shell. Third-parties such as VMWare and Amazon Web Services provide modules to enable users to work with their products through PowerShell. You can also supplement the capabilities of PowerShell modules by directly accessing classes from the underlying installation of .NET, and by running standard commands and scripts from the host operating system.

PowerShell Editions

Windows PowerShell is the proprietary implementation of PowerShell that is shipped with most versions of Windows. It is sometimes referred to as the Desktop edition. Windows PowerShell is now frozen, and will be replaced by PowerShell Core.

PowerShell Core is the new implementation of PowerShell. It is built with .NET Core to be cross-platform and Open Source. Currently, PowerShell Core is a beta product. The finished version will become PowerShell 6. PowerShell Core 5.1 is a special edition that was shipped with Windows Nano Server.

Installing PowerShell

Windows

All of the recent versions of Windows desktop and server operating systems include versions of Windows PowerShell and the Integrated Script Environment (ISE) for editing PowerShell scripts. Windows 10 and Windows Server 2016 provide Windows PowerShell 5.1. ISE is deprecated in favour of Visual Studio Code, but is still supported.

To install the latest version of PowerShell 5 on older Windows systems, install the Windows Management Framework (WMF). WMF is a package of the latest version of PowerShell, along with PowerShell Desired State Configuration (DSC).

macOS and Linux

To use PowerShell on Linux and macOS systems, install .NET Core and PowerShell Core.

Follow these instructions to disable the telemetry in PowerShell Core. The PowerShell Core installer creates a directory called /usr/local/microsoft/, with one subdirectory per PowerShell installation.

Once PowerShell Core is installed, type powershell in a Terminal window to start a PowerShell session:

powershell

Extra Tools and Modules

The current versions of PowerShell include features to install extra modules from remote repositories. By default, the public PowerShell Gallery is configured as a repository.

To write and debug PowerShell scripts, install the Visual Studio Code editor and add the PowerShell Language Support.

Running Scripts

PowerShell files have the file extension of .ps1, regardless of the version of PowerShell.

The current directory is not on the PATH by default. This means that you must use relative or absolute paths when specifying a script to run, or when sourcing one script from within another.

The $args collection contains the input parameters from the script file.

By default, Windows PowerShell only runs interactive commands at the shell prompt. To run local unsigned scripts, but still require scripts from the Internet to be signed, set the policy to RemoteSigned:

Set-ExecutionPolicy RemoteSigned

Automating Windows Management with Ansible or Windows PowerShell DSC

The Ansible automation tool uses PowerShell to execute tasks on the Windows systems that it manages, with PowerShell Remoting and WinRM (Windows Remote Management) to communicate between the controller and the targets.

Windows PowerShell Desired State Configuration (DSC) provides extensions for managing multiple remote Windows systems using PowerShell, and also uses WinRM for communications. DSC does not need PowerShell Remoting to be enabled on the target systems, only WinRM.

Syntax

In PowerShell, the operations are abstract. The same syntax works on all of the types of items, which are .NET objects. Each abstract drive object provides particular types of item. Each command is a cmdlet that accepts items as inputs, and returns items as output.

This means that you construct pipelines by chaining PowerShell cmdlets together, and the items are sent from one cmdlet to another. The experience appears similar to UNIX shells, but is more flexible and consistent. For example, this code gets a list of the name of all of the services on the system that have the Status property with a value of Stopped:

Get-Service | Where-Object { $_.Status -like 'Stopped'} | Select-Object Name

To specify a positional parameter, use space-separated values after the function name. To set named parameters, specify them as switches.

PowerShell provides direct access to .NET classes. For example, this calls DateTime.Today():

$today = [datetime]::Today

The PowerShell language also supports the usual programming constructs, such as variables and loops. Exception handlers are known as traps in PowerShell.

Within PowerShell files, you can enclose code in functions, or script blocks. Functions are always named. Script blocks can be anonymous, or be assigned to variables, and can optionally return a value.

Variables and Collections

In PowerShell, variables are prefixed by a $ character:

$name = "Your Name"

Arrays are defined with round brackets:

@('First', 'Second')

Hash tables are defined with curly braces:

@{1='First', 2='Second'}

Conditionals

PowerShell supports the standard if/else syntax. Write the condition within round brackets, and follow it with a script block:

if ($file.Name -like "*.log"){
  Write-Host "Log: " $file.Name
}
elseif ($file.Name -like "*.txt") {
  Write-Host "Plain-Text: " $file.Name
}
else {
  Write-Host "Might Be a Binary: " $file.Name
}

PowerShell also supports switch/case statements:

switch (<variable>) {
value1 { <action1> } value2 { <action2> }
...
default { <default action}
}

Loops

The basic loop statement is foreach:

foreach ($file in $dir){
  Write-Host $file;
}

This is actually a shortcut for ForEach-Object. You can use ForEach-Object in pipelines:

Get-Service | Where-Object { $_.Name -ilike '*Web*' } | ForEach-Object { $_.Name + ' - ' + $.Status }

Functions

Functions are named script blocks. Use this syntax to declare a function:

function <name>(<parameter list>)
{
    #function body
}

Use the standard verb-noun format for function names, e.g. Get-Service.

PowerShell supports implicit return, but you may also include a return statement to have the function immediately end and return a value.

You may set the types and default values for parameters in the function definition:

function Some-Task($a = "bar", $b = "foo") {
    #function body
}

function Get-RandomNumber([int] $quantity) {
    #function body
}

Remember that you specify parameters by either position or name when you call a function:

Some-Task "this" -b "that"

To enable your function to work as part of a pipeline, define a process section inside the function, and optionally begin and end sections.

To declare a filter, use the keyword filter, rather than function.

Internally, each function is actually an instance of the .NET class System.Management.Automation.FunctionInfo, and filters are instances of System.Management.Automation.FilterInfo.

Error Handling

Every cmdlet must support the parameters ErrorAction, ErrorVariable, Debug, and Verbose. This means that you can specify the error handling behaviour for each command that you run by setting these parameters.

The ErrorVariable is a variable that will hold any error message that is generated. If more than one error is produced, the variable will be a collection.

The ErrorAction parameter accepts one of these options:

  • Continue - The default, where the error is printed but the operation continues
  • Stop - Raise an error, which will cause the operation to exit unless there is an error trap in place
  • SilentlyContinue - Continue without printing an error message
  • Inquire - Pause and prompt the user

For example:

del *.log -ErrorAction Inquire

To handle particular types of errors in your code, use error traps. These are the equivalent of exceptions in PowerShell.

trap [System.Management.Automation.PSInvalidCastException] {
  # code
}

Resources

Extra Modules

Common Commands

Unless otherwise noted, these are all valid for PowerShell for Windows 4.0 and above, and PowerShell Core.

Run Get-Alias to see a list of the PowerShell commands that have shortcuts. The Wikipedia page also lists common commands.

Integrated Help System

  • Update-Help - Update the help for installed PowerShell modules
  • Get-Help ITEM - View the help for the ITEM

PowerShell Modules

  • Find-Module NAME - Search the repositories for installable modules
  • Install-Module NAME - Install the specified module from an available repository
  • Uninstall-Module NAME - Delete the specified module from the system
  • Remove-Module NAME - Removes a module from the current session only
  • $PSVersionTable - Display the table of components versions for PowerShell itself

Network Interfaces

  • Get-NetAdapter - List network interfaces (Windows-only)
  • Get-NetAdapter ADAPTER - Show settings for network interface (Windows-only)
  • Set-NetAdapter INTERFACE - Set settings for network interface (Windows-only)

Network Clients

  • Resolve-DnsName NAME - Gets the DNS records for the specified NAME (Windows-only)
  • Invoke-Webrequest URL - HTTP request to URL
  • Test-Connection ADDRESS - ICMP ping to the specified address (Windows-only)
  • Send-MailMessage - Send an email (requires PowerShell for Windows 5.0 or above)

Use Copy-Item to transfer files over Windows file-sharing or PowerShell Remoting.

Services

  • Get-Process - List the running processes
  • Stop-Process PROCESS_ID - Stop a running process
  • Get-Service - List the registered services (Windows-only)
  • Restart-Service SERVICE-NAME - Restart the service SERVICE-NAME (Windows-only)
  • Start-Service SERVICE-NAME - Start the service SERVICE-NAME (Windows-only)
  • Stop-Service SERVICE-NAME - Stop the service SERVICE-NAME (Windows-only)
  • Get-EventLog LOG-NAME - Fetch the specified log (Windows-only)

System

  • $env:COMPUTERNAME - Gets the current system DNS hostname (Windows-only)
  • Rename-Computer -NewName NAME - Sets the system DNS hostname (Windows-only)
  • Get-Date - Gets the current system date and time
  • Set-Date DATE - Sets the system date and time
  • Get-WinSystemLocale - Gets the current system locale (Windows-only)
  • Set-WinSystemLocale NAME - Sets the system locale, e.g. en-GB (Windows-only)
  • Restart-Computer - Reboot the system (Windows-only)
  • Stop-Computer - Shutdown the system (Windows-only)
  • $PSVersionTable - Get PowerShell version
  • [System.Environment]::OSVersion.Version - Get operating system version (Windows-only)

Objects

  • Get-ChildItem OBJECT - List the child objects of an object
  • Get-Member OBJECT - List the members of an object
  • Select-Object PROPERTY1,PROPERTY2 - Shows the specified properties for a collection of objects
  • Where-Object { CODE } - Filters a collection of objects
  • Measure-Object -property - Show aggregate statistics for property
  • Sort-Object PROPERTY1 -descending - Sorts a collection of objects by the given property

Input and Output

  • Get-Content FILE - Output the contents of the file
  • Set-Content FILE TEXT - Write the text to the file
  • Add-Content FILE TEXT - Append the text to the file
  • Copy-Item SOURCE DESTINATION - Copies the specified item (file or directory)
  • Remove-Item ITEM - Delete the specified item (file or directory)
  • Compress-Archive -LiteralPath ITEM -DestPath ARCHIVE - Packs the specified item into a ZIP archive file
  • Expand-Archive ITEM - Unpacks the specified ZIP archive file