Home ¦ Posts ¦ Books ¦ Articles ¦ Talks ¦ Notes

Powershell

Introduction

If you open powershell on Windows and are coming from a Linux background, it's mildly pleasantly surprising to find commands like cat, ls, mkdir and cd work. However, there's no point in continuing to use those since learning Powershell itself is an intellectually rewarding experience I think. Let's jump right in with the things I usually end up doing.

Static Analysis

Use PSScriptAnalyzer

Environment variables

Set an environment variable from the command line or script:

$Env:AWS_PROFILE = "profilename"

Read an environment variable from the command line or script:

"The AWS profile is $Env:AWS_PROFILE"

Learn all about it here

Show all environment variables:

> Get-ChildItem Env:

Strings

A simple string:

> 'Hello'
Hello

Substitute variable values:

> '{0}-{1}' -f "hello", "world"
hello-world

Substitute the result of a command in a string:

> '{0}' -f $(Get-Location)
...

Learn more here

Variable substitution

Learn all about it here

For property substitution:

$Results = Get-ChildItem  -Filter *.xml | Select-Object FullName
Write-Output "Parsing:  $($result.FullName)"

Create an empty file

> New-Item <path>  -ItemType file

Time a command

> Measure-Command { Get-ChildItem | Out-Host }

The Out-Host pipe is required so as to not gobble up the output of your command.

Tail follow a file

> Get-Content -Path <file> -Wait

Display first/last N lines of a file

> Get-Content -Path -Head 10
> Get-Content -Path -Tail 10

Where is my current command/program being invoked from?

> Get-Command <cmd>

It's also alised to gcm.

Learn all about it here

Display directory contents

> Get-ChildItem

Show only directories:

> Get-ChildItem -Directory

Show only files:

> Get-ChildItem -File

Remove a file/directory

> Remove-Item <path>

To delete the contents of a directory as well recursively, use -Recurse

Learn all about it here

Run an external EXE and wait for it to finish

> <path to exe> | Out-Null

Learn more

System DNS

Get DNS settings:

> Get-DnsClientServerAddress

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
Ethernet 2                          11 IPv4    {172.34.0.2}

Current location management

Change to a path:

> Set-Location -Path <path>

Get current location:

> Get-Location

Push to a location temporarily:

> Push-Location -Path <path>

Pop out:

> Pop-Location

Learn all about it here.

Redirecting output

Learn all about it here.

Reading/parsing text/xml/json

> $lines = Get-Content <path>

lines is an array with each line of the file an array element

See this post for parsing XML files and this post for parsing JSON files.

Write output

> Write-Host "Hello World"

See this and this to learn more.

TLS/SSL Error

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Extracting a ZIP archive

> Expand-Archive <path to zip>

Learn all about it here

Find the hash value of a file

Calculate the sha256 sum:

> Get-FileHash <path to file>

Also supports other algorithms and input stream. Learn all about it here

Sleep

Sleep for n seconds:

> Start-Sleep -s n

Learn all about it here

Working with DNS clients/servers

Clear DNS cache:

> Clear-DnsClientCache

Get current DNS servers:

> Get-DnsClientServerAddress

https://docs.microsoft.com/en-us/powershell/module/dnsclient/get-dnsclientserveraddress?view=win10-ps

Set DNS address:

> Set-DnsClientServerAddress -InterfaceAlias ..

Learn all about it here

Add a DNS server to the existing addresses:

> $result = Get-DnsClientServerAddress -InterfaceAlias "vEthernet" # or InterfaceIndex
> Set-DnsClientServerAddress -InterfaceAlias "vEthernet" -ServerAddresses ("172.34.0.2", $result.ServerAddresses)

Working with list of things

Samples script to go over a list of things and doing something:

$repositories = @(
    "demo/repo1",
    "demo/repo2"    
)

foreach ($repo in $repositories)
{
    aws ecr create-repository --repository-name $repo
}

Sourcing stuff from other files

. ./<path-to-ps1> file

Update a AWS ECR policy using AWS CLI

The reason I have it here is the escaping for the JSON policy for powershell:

# Create repository policy to allow public pulling
# https://docs.aws.amazon.com/cli/latest/userguide/cli-using-param.html#quoting-strings
$policy=@"
{
     \"Version\": \"2008-10-17\",
     \"Statement\": [
         {
             \"Sid\": \"Allow public pulling of images\",
             \"Effect\": \"Allow\",
             \"Principal\": \"*\",
             \"Action\": [
                 \"ecr:GetDownloadUrlForLayer\",
                 \"ecr:BatchGetImage\",
                 \"ecr:BatchCheckLayerAvailability\"
             ]
         }
     ]
 }
"@

foreach ($repo in $repositories)
{
    aws ecr set-repository-policy --repository-name $repo --policy-text $policy
}

Data Structures

Lists

$repositories = @(
    "repo1",
    "repo2"

)

foreach ($repo in $repositories)
{
  Write-Host "Pulling ${repo}"  
}

Hash table

RepositoriesBuiltDirMap = @{
    "repo1" = "dir1"
    "repo2" = "dir2"    
}

$RepositoriesDockerfileMap.keys | ForEach-Object{
    echo "Key: ${_}"
    echo "Value: ${RepositoriesDockerfileMap[$_]}"
}

Learn all about them here

© Amit Saha. Built using Pelican. Customised theme based on the one by Giulio Fidente on github.