Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

Power Shell | Cheat Sheets

Cheat Sheet 1

Get-Command                                    # List of all the commands available to PowerShell
                                               # (native binaries in $env:PATH + cmdlets / functions from PowerShell modules)
Get-Command -Module Microsoft*                 # Lst of all the PowerShell commands exported from modules named Microsoft*
Get-Command -Name *item                        # List of all commands ending in "item"

Get-Help                                       # Get all help topics
Get-Help -Name about_Variables                 # Get help for a specific about_* topic (aka. man page)
Get-Help -Name Get-Command                     # Get help for a specific PowerShell function
Get-Help -Name Get-Command -Parameter Module   # Get help for a specific parameter on a specific command
###################################################
# Operators
###################################################

$a = 2                                                    # Basic variable assignment operator
$a += 1                                                   # Incremental assignment operator
$a -= 1                                                   # Decrement assignment operator

$a -eq 0                                                  # Equality comparison operator
$a -ne 5                                                  # Not-equal comparison operator
$a -gt 2                                                  # Greater than comparison operator
$a -lt 3                                                  # Less than comparison operator

$FirstName = 'Trevor'
$FirstName -like 'T*'                                     # Perform string comparison using the -like operator, which supports the wildcard (*) character. Returns $true

$BaconIsYummy = $true
$FoodToEat = $BaconIsYummy ? 'bacon' : 'beets'            # Sets the $FoodToEat variable to 'bacon' using the ternary operator

'Celery' -in @('Bacon', 'Sausage', 'Steak', 'Chicken')    # Returns boolean value indicating if left-hand operand exists in right-hand array
'Celery' -notin @('Bacon', 'Sausage', 'Steak')            # Returns $true, because Celery is not part of the right-hand list

5 -is [string]                                            # Is the number 5 a string value? No. Returns $false.
5 -is [int32]                                             # Is the number 5 a 32-bit integer? Yes. Returns $true.
5 -is [int64]                                             # Is the number 5 a 64-bit integer? No. Returns $false.
'Trevor' -is [int64]                                      # Is 'Trevor' a 64-bit integer? No. Returns $false.
'Trevor' -isnot [string]                                  # Is 'Trevor' NOT a string? No. Returns $false.
'Trevor' -is [string]                                     # Is 'Trevor' a string? Yes. Returns $true.
$true -is [bool]                                          # Is $true a boolean value? Yes. Returns $true.
$false -is [bool]                                         # Is $false a boolean value? Yes. Returns $true.
5 -is [bool]                                              # Is the number 5 a boolean value? No. Returns $false.
/pre>
###################################################
# Regular Expressions
###################################################

'Trevor' -match '^T\w*'                                   # Perform a regular expression match against a string value. # Returns $true and populates $matches variable
$matches[0]                                               # Returns 'Trevor', based on the above match

@('Trevor', 'Billy', 'Bobby') -match '^B'                 # Perform a regular expression match against an array of string values. Returns Billy, Bobby

$regex = [regex]'(\w{3,8})'
$regex.Matches('Trevor Bobby Dillon Joe Jacob').Value     # Find multiple matches against a singleton string value.
/pre>
###################################################
# Flow Control
###################################################

if (1 -eq 1) { }                                          # Do something if 1 is equal to 1

do { 'hi' } while ($false)                                # Loop while a condition is true (always executes at least once)

while ($false) { 'hi' }                                   # While loops are not guaranteed to run at least once
while ($true) { }                                         # Do something indefinitely
while ($true) { if (1 -eq 1) { break } }                  # Break out of an infinite while loop conditionally

for ($i = 0; $i -le 10; $i++) { Write-Host $i }           # Iterate using a for..loop
foreach ($item in (Get-Process)) { }                      # Iterate over items in an array

switch ('test') { 'test' { 'matched'; break } }           # Use the switch statement to perform actions based on conditions. Returns string 'matched'
switch -regex (@('Trevor', 'Daniel', 'Bobby')) {          # Use the switch statement with regular expressions to match inputs
  'o' { $PSItem; break }                                  # NOTE: $PSItem or $_ refers to the "current" item being matched in the array
}
switch -regex (@('Trevor', 'Daniel', 'Bobby')) {          # Switch statement omitting the break statement. Inputs can be matched multiple times, in this scenario.
  'e' { $PSItem }
  'r' { $PSItem }
}
/pre>
###################################################
# Variables
###################################################


$a = 0                                                    # Initialize a variable
[int] $a = 'Trevor'                                       # Initialize a variable, with the specified type (throws an exception)
[string] $a = 'Trevor'                                    # Initialize a variable, with the specified type (doesn't throw an exception)

Get-Command -Name *varia*                                 # Get a list of commands related to variable management

Get-Variable                                              # Get an array of objects, representing the variables in the current and parent scopes 
Get-Variable | ? { $PSItem.Options -contains 'constant' } # Get variables with the "Constant" option set
Get-Variable | ? { $PSItem.Options -contains 'readonly' } # Get variables with the "ReadOnly" option set

New-Variable -Name FirstName -Value Trevor
New-Variable FirstName -Value Trevor -Option Constant     # Create a constant variable, that can only be removed by restarting PowerShell
New-Variable FirstName -Value Trevor -Option ReadOnly     # Create a variable that can only be removed by specifying the -Force parameter on Remove-Variable

Remove-Variable -Name firstname                           # Remove a variable, with the specified name
Remove-Variable -Name firstname -Force                    # Remove a variable, with the specified name, that has the "ReadOnly" option set
/pre>
###################################################
# Functions
###################################################

function add ($a, $b) { $a + $b }                         # A basic PowerShell function

function Do-Something {                                   # A PowerShell Advanced Function, with all three blocks declared: BEGIN, PROCESS, END
  [CmdletBinding]()]
  param ()
  begin { }
  process { }
  end { }
}
/pre>
###################################################
# Working with Modules
###################################################

Get-Command -Name *module* -Module mic*core                 # Which commands can I use to work with modules?

Get-Module -ListAvailable                                   # Show me all of the modules installed on my system (controlled by $env:PSModulePath)
Get-Module                                                  # Show me all of the modules imported into the current session

$PSModuleAutoLoadingPreference = 0                          # Disable auto-loading of installed PowerShell modules, when a command is invoked

Import-Module -Name NameIT                                  # Explicitly import a module, from the specified filesystem path or name (must be present in $env:PSModulePath)
Remove-Module -Name NameIT                                  # Remove a module from the scope of the current PowerShell session

New-ModuleManifest                                          # Helper function to create a new module manifest. You can create it by hand instead.

New-Module -Name trevor -ScriptBlock {                      # Create an in-memory PowerShell module (advanced users)
  function Add($a,$b) { $a + $b } }

New-Module -Name trevor -ScriptBlock {                      # Create an in-memory PowerShell module, and make it visible to Get-Module (advanced users)
  function Add($a,$b) { $a + $b } } | Import-Module
/pre>
###################################################
# Module Management
###################################################

Get-Command -Module PowerShellGet                           # Explore commands to manage PowerShell modules

Find-Module -Tag cloud                                      # Find modules in the PowerShell Gallery with a "cloud" tag
Find-Module -Name ps*                                       # Find modules in the PowerShell Gallery whose name starts with "PS"

Install-Module -Name NameIT -Scope CurrentUser -Force       # Install a module to your personal directory (non-admin)
Install-Module -Name NameIT -Force                          # Install a module to your personal directory (admin / root)
Install-Module -Name NameIT -RequiredVersion 1.9.0          # Install a specific version of a module

Uninstall-Module -Name NameIT                               # Uninstall module called "NameIT", only if it was installed via Install-Module

Register-PSRepository -Name <repo> -SourceLocation <uri>    # Configure a private PowerShell module registry
Unregister-PSRepository -Name <repo>                        # Deregister a PowerShell Repository
/pre>
###################################################
# Filesystem
###################################################

New-Item -Path c:\test -ItemType Directory                  # Create a directory
mkdir c:\test2                                              # Create a directory (short-hand)

New-Item -Path c:\test\myrecipes.txt                        # Create an empty file
Set-Content -Path c:\test.txt -Value ''                     # Create an empty file
[System.IO.File]::WriteAllText('testing.txt', '')           # Create an empty file using .NET Base Class Library

Remove-Item -Path testing.txt                               # Delete a file
[System.IO.File]::Delete('testing.txt')                     # Delete a file using .NET Base Class Library
/pre>
###################################################
# Hashtables (Dictionary)
###################################################

$Person = @{
  FirstName = 'Trevor'
  LastName = 'Sullivan'
  Likes = @(
    'Bacon',
    'Beer',
    'Software'
  )
}                                                           # Create a PowerShell HashTable

$Person.FirstName                                           # Retrieve an item from a HashTable
$Person.Likes[-1]                                           # Returns the last item in the "Likes" array, in the $Person HashTable (software)
$Person.Age = 50                                            # Add a new property to a HashTable
/pre>
###################################################
# Windows Management Instrumentation (WMI) (Windows only)
###################################################

Get-CimInstance -ClassName Win32_BIOS                       # Retrieve BIOS information
Get-CimInstance -ClassName Win32_DiskDrive                  # Retrieve information about locally connected physical disk devices
Get-CimInstance -ClassName Win32_PhysicalMemory             # Retrieve information about install physical memory (RAM)
Get-CimInstance -ClassName Win32_NetworkAdapter             # Retrieve information about installed network adapters (physical + virtual)
Get-CimInstance -ClassName Win32_VideoController            # Retrieve information about installed graphics / video card (GPU)

Get-CimClass -Namespace root\cimv2                          # Explore the various WMI classes available in the root\cimv2 namespace
Get-CimInstance -Namespace root -ClassName __NAMESPACE      # Explore the child WMI namespaces underneath the root\cimv2 namespace
/pre>

###################################################
# Asynchronous Event Registration
###################################################

#### Register for filesystem events
$Watcher = [System.IO.FileSystemWatcher]::new('c:\tmp')
Register-ObjectEvent -InputObject $Watcher -EventName Created -Action {
  Write-Host -Object 'New file created!!!'
}                                                           

#### Perform a task on a timer (ie. every 5000 milliseconds)
$Timer = [System.Timers.Timer]::new(5000)
Register-ObjectEvent -InputObject $Timer -EventName Elapsed -Action {
  Write-Host -ForegroundColor Blue -Object 'Timer elapsed! Doing some work.'
}
$Timer.Start()
/pre>
###################################################
# PowerShell Drives (PSDrives)
###################################################

Get-PSDrive                                                 # List all the PSDrives on the system
New-PSDrive -Name videos -PSProvider Filesystem -Root x:\data\content\videos  # Create a new PSDrive that points to a filesystem location
New-PSDrive -Name h -PSProvider FileSystem -Root '\\storage\h$\data' -Persist # Create a persistent mount on a drive letter, visible in Windows Explorer
Set-Location -Path videos:                                  # Switch into PSDrive context
Remove-PSDrive -Name xyz                                    # Delete a PSDrive
/pre>
###################################################
# Data Management
###################################################

Get-Process | Group-Object -Property Name                   # Group objects by property name
Get-Process | Sort-Object -Property Id                      # Sort objects by a given property name
Get-Process | Where-Object -FilterScript { $PSItem.Name -match '^c' } # Filter objects based on a property matching a value
gps | where Name -match '^c'                                # Abbreviated form of the previous statement
/pre>
###################################################
# PowerShell Classes
###################################################

class Person {
  [string] $FirstName                                       # Define a class property as a string
  [string] $LastName = 'Sullivan'                           # Define a class property with a default value
  [int] $Age                                                # Define a class property as an integer
  
  Person() {                                                # Add a default constructor (no input parameters) for a class
  }
  
  Person([string] $FirstName) {                             # Define a class constructor with a single string parameter
    $this.FirstName = $FirstName
  }
  
  [string] FullName() {
    return '{0} {1}' -f $this.FirstName, $this.LastName
  }
}
$Person01 = [Person]::new()                                 # Instantiate a new Person object.
$Person01.FirstName = 'Trevor'                              # Set the FirstName property on the Person object.
$Person01.FullName()                                        # Call the FullName() method on the Person object. Returns 'Trevor Sullivan'


class Server {                                              # Define a "Server" class, to manage remote servers. Customize this based on your needs.
  [string] $Name
  [System.Net.IPAddress] $IPAddress                         # Define a class property as an IPaddress object
  [string] $SSHKey = "$HOME/.ssh/id_rsa"                    # Set the path to the private key used to authenticate to the server
  [string] $Username                                        # Set the username to login to the remote server with
  
  RunCommand([string] $Command) {                           # Define a method to call a command on the remote server, via SSH
    ssh -i $this.SSHKey $this.Username@$this.Name $this.Command
  }
}

$Server01 = [Server]::new()                                 # Instantiate the Server class as a new object
$Server01.Name = 'webserver01.local'                        # Set the "name" of the remote server
$Server01.Username = 'root'                                 # Set the username property of the "Server" object
$Server01.RunCommand("hostname")                            # Run a command on the remote server
/pre>
###################################################
# REST APIs
###################################################

$Params = @{
  Uri = 'https://api.github.com/events'
  Method = 'Get'
}
Invoke-RestMethod @Params                                   # Call a REST API, using the HTTP GET method

Learning Powershell in 5 Minutes

Comments

# Single line comments start with a number symbol.

<#
  Multi-line comments
  like so
#>
/pre>

Primitive Datatypes and Operators

####################################################
## 1. Primitive Datatypes and Operators
####################################################

# Numbers
3 # => 3

# Math
1 + 1   # => 2
8 - 1   # => 7
10 * 2  # => 20
35 / 5  # => 7.0

# Powershell uses banker's rounding,
# meaning [int]1.5 would round to 2 but so would [int]2.5
# Division always returns a float. 
# You must cast result to [int] to round.
[int]5 / [int]3       # => 1.66666666666667
[int]-5 / [int]3      # => -1.66666666666667
5.0 / 3.0   # => 1.66666666666667
-5.0 / 3.0  # => -1.66666666666667
[int]$result = 5 / 3 
$result # => 2

# Modulo operation
7

# Exponentiation requires longform or the built-in [Math] class.
[Math]::Pow(2,3)  # => 8

# Enforce order of operations with parentheses.
1 + 3 * 2  # => 7
(1 + 3) * 2  # => 8

# Boolean values are primitives (Note: the $)
$True  # => True
$False  # => False

# negate with !
!$True   # => False
!$False  # => True

# Boolean Operators
# Note "-and" and "-or" usage
$True -and $False  # => False
$False -or $True   # => True

# True and False are actually 1 and 0 but only support limited arithmetic.
# However, casting the bool to int resolves this.
$True + $True # => 2
$True * 8    # => '[System.Boolean] * [System.Int32]' is undefined
[int]$True * 8 # => 8
$False - 5   # => -5

# Comparison operators look at the numerical value of True and False.
0 -eq $False  # => True
1 -eq $True   # => True
2 -eq $True   # => False
-5 -ne $False # => True

# Using boolean logical operators on ints casts to booleans for evaluation.
# but their non-cast value is returned
# Don't mix up with bool(ints) and bitwise -band/-bor
[bool](0)     # => False
[bool](4)     # => True
[bool](-6)    # => True
0 -band 2     # => 0
-5 -bor 0     # => -5

# Equality is -eq (equals)
1 -eq 1  # => True
2 -eq 1  # => False

# Inequality is -ne (notequals)
1 -ne 1  # => False
2 -ne 1  # => True

# More comparisons
1 -lt 10  # => True
1 -gt 10  # => False
2 -le 2  # => True
2 -ge 2  # => True

# Seeing whether a value is in a range
1 -lt 2 -and 2 -lt 3  # => True
2 -lt 3 -and 3 -lt 2  # => False

# (-is vs. -eq) -is checks if two objects are the same type.
# -eq checks if the objects have the same values.
# Note: we called '[Math]' from .NET previously without the preceeding
# namespaces. We can do the same with [Collections.ArrayList] if preferred.
[System.Collections.ArrayList]$a = @()  # Point a at a new list
$a = (1,2,3,4)
$b = $a                                 # => Point b at what a is pointing to
$b -is $a.GetType()                     # => True, a and b equal same type
$b -eq $a                               # => True, a and b values are equal
[System.Collections.Hashtable]$b = @{}  # => Point a at a new hash table
$b = @{'one' = 1 
       'two' = 2}
$b -is $a.GetType()                     # => False, a and b types not equal

# Strings are created with " or ' but " is required for string interpolation
"This is a string."
'This is also a string.'

# Strings can be added too! But try not to do this.
"Hello " + "world!"  # => "Hello world!"

# A string can be treated like a list of characters
"Hello world!"[0]  # => 'H'

# You can find the length of a string
("This is a string").Length  # => 16

# You can also format using f-strings or formatted string literals.
$name = "Steve"
$age = 22
"He said his name is $name." 
# => "He said his name is Steve"
"{0} said he is {1} years old." -f $name, $age 
# => "Steve said he is 22 years old"
"$name's name is $($name.Length) characters long." 
# => "Steve's name is 5 characters long."

# Escape Characters in Powershell
# Many languages use the '\', but Windows uses this character for 
# file paths. Powershell thus uses '`' to escape characters
# Take caution when working with files, as '`' is a
# valid character in NTFS filenames.
"Showing`nEscape Chars" # => new line between Showing and Escape
"Making`tTables`tWith`tTabs" # => Format things with tabs

# Negate pound sign to prevent comment
# Note that the function of '#' is removed, but '#' is still present
`#Get-Process # => Fail: not a recognized cmdlet

# $null is not an object
$null  # => None

# $null, 0, and empty strings and arrays all evaluate to False.
# All other values are True
function Test-Value ($value) {
  if ($value) {
    Write-Output 'True'
  }
  else {
    Write-Output 'False'
  }
}

Test-Value ($null) # => False
Test-Value (0)     # => False
Test-Value ("")    # => False
Test-Value []      # => True 
# *[] calls .NET class; creates '[]' string when passed to function
Test-Value ({})    # => True
Test-Value @()     # => False

/pre>
####################################################
## 2. Variables and Collections
####################################################

# Powershell uses the "Write-Output" function to print
Write-Output "I'm Posh. Nice to meet you!"  # => I'm Posh. Nice to meet you!

# Simple way to get input data from console
$userInput = Read-Host "Enter some data: " # Returns the data as a string

# There are no declarations, only assignments.
# Convention is to use camelCase or PascalCase, whatever your team uses.
$someVariable = 5
$someVariable  # => 5

# Accessing a previously unassigned variable does not throw exception.
# The value is $null by default

# Ternary Operators exist in Powershell 7 and up
0 ? 'yes' : 'no'  # => no


# The default array object in Powershell is an fixed length array.
$defaultArray = "thing","thing2","thing3"
# you can add objects with '+=', but cannot remove objects.
$defaultArray.Add("thing4") # => Exception "Collection was of a fixed size."
# To have a more workable array, you'll want the .NET [ArrayList] class
# It is also worth noting that ArrayLists are significantly faster

# ArrayLists store sequences
[System.Collections.ArrayList]$array = @()
# You can start with a prefilled ArrayList
[System.Collections.ArrayList]$otherArray = @(4, 5, 6)

# Add to the end of a list with 'Add' (Note: produces output, append to $null)
$array.Add(1) > $null    # $array is now [1]
$array.Add(2) > $null    # $array is now [1, 2]
$array.Add(4) > $null    # $array is now [1, 2, 4]
$array.Add(3) > $null    # $array is now [1, 2, 4, 3]
# Remove from end with index of count of objects-1; array index starts at 0
$array.RemoveAt($array.Count-1) # => 3 and array is now [1, 2, 4]
# Let's put it back
$array.Add(3) > $null   # array is now [1, 2, 4, 3] again.

# Access a list like you would any array
$array[0]   # => 1
# Look at the last element
$array[-1]  # => 3

# Looking out of bounds returns nothing
$array[4]  # blank line returned

# You can look at ranges with slice syntax.
# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
$array[1..3]   # Return array from index 1 to 3 => [2, 4]
$array[2..-1]    # Return array starting from index 2 => [4, 3]
$array[0..3]    # Return array from beginning until index 3  => [1, 2, 4]
$array[0..2]   # Return array selecting every second entry => [1, 4]
$array.Reverse()  # mutates array to reverse order => [3, 4, 2, 1]
# Use any combination of these to make advanced slices

# Remove arbitrary elements from a array with "del"
$array.Remove($array[2])  # $array is now [1, 2, 3]

# Insert an element at a specific index
$array.Insert(1, 2)  # $array is now [1, 2, 3] again

# Get the index of the first item found matching the argument
$array.IndexOf(2)  # => 1
$array.IndexOf(6)  # Returns -1 as "outside array" 

# You can add arrays
# Note: values for $array and for $otherArray are not modified.
$array + $otherArray  # => [1, 2, 3, 4, 5, 6]

# Concatenate arrays with "AddRange()"
$array.AddRange($otherArray)  # Now $array is [1, 2, 3, 4, 5, 6]

# Check for existence in a array with "in"
1 -in $array  # => True

# Examine length with "Count" (Note: "Length" on arrayList = each items length)
$array.Count  # => 6


# Tuples are like arrays but are immutable.
# To use Tuples in powershell, you must use the .NET tuple class.
$tuple = [System.Tuple]::Create(1, 2, 3)
$tuple.Item(0)      # => 1
$tuple.Item(0) = 3  # Raises a TypeError

# You can do some of the array methods on tuples, but they are limited.
$tuple.Length       # => 3
$tuple + (4, 5, 6)  # => Exception
$tuple[0..2]        # => $null
2 -in $tuple        # => False


# Hashtables store mappings from keys to values, similar to Dictionaries.
$emptyHash = @{}
# Here is a prefilled dictionary
$filledHash = @{"one"= 1 
                "two"= 2 
                "three"= 3}

# Look up values with []
$filledHash["one"]  # => 1

# Get all keys as an iterable with ".Keys".
# items maintain the order at which they are inserted into the dictionary.
$filledHash.Keys  # => ["one", "two", "three"]

# Get all values as an iterable with ".Values".
$filledHash.Values  # => [1, 2, 3]

# Check for existence of keys or values in a hash with "-in"
"one" -in $filledHash.Keys  # => True
1 -in $filledHash.Values    # => False

# Looking up a non-existing key returns $null
$filledHash["four"]  # $null

# Adding to a dictionary
$filledHash.Add("five",5)  # $filledHash["five"] is set to 5
$filledHash.Add("five",6)  # exception "Item with key "five" has already been added"
$filledHash["four"] = 4 # $filledHash["four"] is set to 4, running again does nothing

# Remove keys from a dictionary with del
$filledHash.Remove("one") # Removes the key "one" from filled dict

/pre>
####################################################
## 3. Control Flow and Iterables
####################################################

# Let's just make a variable
$someVar = 5

# Here is an if statement.
# This prints "$someVar is smaller than 10"
if ($someVar -gt 10) {
    Write-Output "$someVar is bigger than 10."
}
elseif ($someVar -lt 10) {    # This elseif clause is optional.
    Write-Output "$someVar is smaller than 10."
}
else {                        # This is optional too.
    Write-Output "$someVar is indeed 10."
}


<#
Foreach loops iterate over arrays
prints:
    dog is a mammal
    cat is a mammal
    mouse is a mammal
#>
foreach ($animal in ("dog", "cat", "mouse")) {
    # You can use -f to interpolate formatted strings
    "{0} is a mammal" -f $animal
}

<#
For loops iterate over arrays and you can specify indices
prints:
   0 a
   1 b
   2 c
   3 d
   4 e
   5 f
   6 g
   7 h
#>
$letters = ('a','b','c','d','e','f','g','h')
for($i=0; $i -le $letters.Count-1; $i++){
    Write-Host $i, $letters[$i]
}

<#
While loops go until a condition is no longer met.
prints:
    0
    1
    2
    3
#>
$x = 0
while ($x -lt 4) {
    Write-Output $x
    $x += 1  # Shorthand for x = x + 1
}

# Switch statements are more powerful compared to most languages
$val = "20"
switch($val) {
  { $_ -eq 42 }           { "The answer equals 42"; break }
  '20'                    { "Exactly 20"; break }
  { $_ -like 's*' }       { "Case insensitive"; break }
  { $_ -clike 's*'}       { "clike, ceq, cne for case sensitive"; break }
  { $_ -notmatch '^.*$'}  { "Regex matching. cnotmatch, cnotlike, ..."; break }
  default                 { "Others" }
}

# Handle exceptions with a try/catch block
try {
    # Use "throw" to raise an error
    throw "This is an error"
}
catch {
    Write-Output $Error.ExceptionMessage
}
finally {
    Write-Output "We can clean up resources here"
}


# Writing to a file
$contents = @{"aa"= 12 
             "bb"= 21}
$contents | Export-CSV "$env:HOMEDRIVE\file.csv" # writes to a file

$contents = "test string here"
$contents | Out-File "$env:HOMEDRIVE\file.txt" # writes to another file

# Read file contents and convert to json
Get-Content "$env:HOMEDRIVE\file.csv" | ConvertTo-Json

/pre>
####################################################
## 4. Functions
####################################################

# Use "function" to create new functions
# Keep the Verb-Noun naming convention for functions
function Add-Numbers {
 $args[0] + $args[1]
}

Add-Numbers 1 2 # => 3

# Calling functions with parameters
function Add-ParamNumbers {
 param( [int]$firstNumber, [int]$secondNumber )
 $firstNumber + $secondNumber
}

Add-ParamNumbers -FirstNumber 1 -SecondNumber 2 # => 3 

# Functions with named parameters, parameter attributes, parsable documentation
<#
.SYNOPSIS
Setup a new website
.DESCRIPTION
Creates everything your new website needs for much win
.PARAMETER siteName
The name for the new website
.EXAMPLE
New-Website -Name FancySite -Po 5000
New-Website SiteWithDefaultPort
New-Website siteName 2000 # ERROR! Port argument could not be validated
('name1','name2') | New-Website -Verbose
#>
function New-Website() {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
        [Alias('name')]
        [string]$siteName,
        [ValidateSet(3000,5000,8000)]
        [int]$port = 3000
    )
    BEGIN { Write-Output 'Creating new website(s)' }
    PROCESS { Write-Output "name: $siteName, port: $port" }
    END { Write-Output 'Website(s) created' }
}
/pre>
####################################################
## 5. Modules
####################################################

# You can import modules and install modules
# The Install-Module is similar to pip or npm, pulls from Powershell Gallery
Install-Module dbaTools
Import-Module dbaTools

$query = "SELECT * FROM dbo.sometable"
$queryParams = @{
    SqlInstance = 'testInstance'
    Database    = 'testDatabase'
    Query       = $query
}
Invoke-DbaQuery @queryParams

# You can get specific functions from a module
Import-Module -Function Invoke-DbaQuery


# Powershell modules are just ordinary Posh files. You
# can write your own, and import them. The name of the
# module is the same as the name of the file.

# You can find out which functions and attributes
# are defined in a module.
Get-Command -module dbaTools
Get-Help dbaTools -Full

/pre>
####################################################
## 6. Classes
####################################################

# We use the "class" statement to create a class
class Instrument {
    [string]$Type
    [string]$Family
}

$instrument = [Instrument]::new()
$instrument.Type = "String Instrument"
$instrument.Family = "Plucked String"

$instrument

<# Output:
Type              Family        
----              ------        
String Instrument Plucked String
#>

/pre>
####################################################
## 6.1 Inheritance
####################################################

# Inheritance allows new child classes to be defined that inherit 
# methods and variables from their parent class.

class Guitar : Instrument
{
    [string]$Brand
    [string]$SubType
    [string]$ModelType
    [string]$ModelNumber
}

$myGuitar = [Guitar]::new()
$myGuitar.Brand       = "Taylor"
$myGuitar.SubType     = "Acoustic"
$myGuitar.ModelType   = "Presentation"
$myGuitar.ModelNumber = "PS14ce Blackwood"

$myGuitar.GetType()

<#
IsPublic IsSerial Name                                     BaseType                                               
-------- -------- ----                                     --------                                               
True     False    Guitar                                   Instrument  
#>

/pre>
####################################################
## 7. Advanced
####################################################

# The powershell pipeline allows things like High-Order Functions.

# Group-Object is a handy cmdlet that does incredible things.
# It works much like a GROUP BY in SQL.

<#
 The following will get all the running processes,
 group them by Name,
 and tell us how many instances of each process we have running.
 Tip: Chrome and svcHost are usually big numbers in this regard.
#>
Get-Process | Foreach-Object ProcessName | Group-Object

# Useful pipeline examples are iteration and filtering.
1..10 | ForEach-Object { "Loop number $PSITEM" }
1..10 | Where-Object { $PSITEM -gt 5 } | ConvertTo-Json

# A notable pitfall of the pipeline is it's performance when
# compared with other options.
# Additionally, raw bytes are not passed through the pipeline,
# so passing an image causes some issues.
# See more on that in the link at the bottom.

<#
 Asynchronous functions exist in the form of jobs.
 Typically a procedural language,
 Powershell can operate non-blocking functions when invoked as Jobs.
#>

# This function is known to be non-optimized, and therefore slow.
$installedApps = Get-CimInstance -ClassName Win32_Product

# If we had a script, it would hang at this func for a period of time.
$scriptBlock = {Get-CimInstance -ClassName Win32_Product}
Start-Job -ScriptBlock $scriptBlock

# This will start a background job that runs the command.
# You can then obtain the status of jobs and their returned results.
$allJobs = Get-Job
$jobResponse = Get-Job | Receive-Job


# Math is built in to powershell and has many functions.
$r=2
$pi=[math]::pi
$r2=[math]::pow( $r, 2 )
$area = $pi*$r2
$area

# To see all possibilities, check the members.
[System.Math] | Get-Member -Static -MemberType All


<#
 This is a silly one:
 You may one day be asked to create a func that could take $start and $end
 and reverse anything in an array within the given range
 based on an arbitrary array without mutating the original array.
 Let's see one way to do that and introduce another data structure.
#>

$targetArray = 'a','b','c','d','e','f','g','h','i','j','k','l','m'

function Format-Range ($start, $end, $array) {
    [System.Collections.ArrayList]$firstSectionArray = @()
    [System.Collections.ArrayList]$secondSectionArray = @()
    [System.Collections.Stack]$stack = @()
    for ($index = 0; $index -lt $array.Count; $index++) {
        if ($index -lt $start) {
            $firstSectionArray.Add($array[$index]) > $null
        }
        elseif ($index -ge $start -and $index -le $end) {
            $stack.Push($array[$index])
        }
        else {
            $secondSectionArray.Add($array[$index]) > $null
        }
    }
    $finalArray = $firstSectionArray + $stack.ToArray() + $secondSectionArray
    return $finalArray
}

Format-Range 2 6 $targetArray 
# => 'a','b','g','f','e','d','c','h','i','j','k','l','m'

# The previous method works, but uses extra memory by allocating new arrays.
# It's also kind of lengthy.
# Let's see how we can do this without allocating a new array.
# This is slightly faster as well.

function Format-Range ($start, $end) {
  while ($start -lt $end)
  {
      $temp = $targetArray[$start]
      $targetArray[$start] = $targetArray[$end]
      $targetArray[$end] = $temp
      $start++
      $end--
  }
  return $targetArray
}

Format-Range 2 6 # => 'a','b','g','f','e','d','c','h','i','j','k','l','m'

# Find commands
Get-Command about_* # alias: gcm
Get-Command -Verb Add
Get-Alias ps
Get-Alias -Definition Get-Process

Get-Help ps | less # alias: help
ps | Get-Member # alias: gm

Show-Command Get-WinEvent # Display GUI to fill in the parameters

Update-Help # Run as admin

Get-ExecutionPolicy -List
Set-ExecutionPolicy AllSigned
# Execution policies include:
# - Restricted: Scripts won't run.
# - RemoteSigned: Downloaded scripts run only if signed by a trusted publisher. 
# - AllSigned: Scripts need to be signed by a trusted publisher.
# - Unrestricted: Run all scripts.
help about_Execution_Policies # for more info

# Current PowerShell version:
$PSVersionTable

# Calling external commands, executables, 
# and functions with the call operator.
# Exe paths with arguments passed or containing spaces can create issues.
C:\Program Files\dotnet\dotnet.exe
# The term 'C:\Program' is not recognized as a name of a cmdlet,
# function, script file, or executable program.
# Check the spelling of the name, or if a path was included, 
# verify that the path is correct and try again

"C:\Program Files\dotnet\dotnet.exe"
C:\Program Files\dotnet\dotnet.exe    # returns string rather than execute

&"C:\Program Files\dotnet\dotnet.exe --help"   # fail
&"C:\Program Files\dotnet\dotnet.exe" --help   # success
# Alternatively, you can use dot-sourcing here
."C:\Program Files\dotnet\dotnet.exe" --help   # success

# the call operator (&) is similar to Invoke-Expression, 
# but IEX runs in current scope.
# One usage of '&' would be to invoke a scriptblock inside of your script.
# Notice the variables are scoped
$i = 2
$scriptBlock = { $i=5; Write-Output $i }
& $scriptBlock # => 5
$i # => 2

invoke-expression ' $i=5; Write-Output $i ' # => 5
$i # => 5

# Alternatively, to preserve changes to public variables
# you can use "Dot-Sourcing". This will run in the current scope.
$x=1
&{$x=2};$x # => 1

.{$x=2};$x # => 2


# Remoting into computers is easy.
Enter-PSSession -ComputerName RemoteComputer

# Once remoted in, you can run commands as if you're local.
RemoteComputer\PS> Get-Process powershell

<#
Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName                                             
-------  ------    -----      -----     ------     --  -- -----------                                             
   1096      44   156324     179068      29.92  11772   1 powershell                                              
    545      25    49512      49852             25348   0 powershell 
#>
RemoteComputer\PS> Exit-PSSession

<#
 Powershell is an incredible tool for Windows management and Automation.
 Let's take the following scenario:
 You have 10 servers.
 You need to check whether a service is running on all of them.
 You can RDP and log in, or PSSession to all of them, but why?
 Check out the following
#>

$serverList = @(
    'server1',
    'server2',
    'server3',
    'server4',
    'server5',
    'server6',
    'server7',
    'server8',
    'server9',
    'server10'
)

[scriptblock]$script = {
    Get-Service -DisplayName 'Task Scheduler'
}

foreach ($server in $serverList) {
    $cmdSplat = @{
        ComputerName  = $server
        JobName       = 'checkService'
        ScriptBlock   = $script
        AsJob         = $true
        ErrorAction   = 'SilentlyContinue'
    }
    Invoke-Command @cmdSplat | Out-Null
}

<#
 Here we've invoked jobs across many servers.
 We can now Receive-Job and see if they're all running.
 Now scale this up 100x as many servers :)
#>

Cheat Sheet 2

PowerShell Commands Cheat Sheet

cmdlets

Cmdlets are PowerShell’s internal commands. These cmdlets will return one or more objects to the pipeline where at the end of that pipeline, we mention some properties of the objects in the following table to see their values displayed on the screen.

CommandDescription
Get-HelpThis command allows you to get support with PowerShell.
Get-PSdriveThis command offers you a list of available PSDrives, such as c, env, hklm, hkcu, alias, etc.
Get-ChildItemIn any registry, children are the subkeys of the current key. To get the required details, you can use the following command.
Get-ChildItem -recurseRun this command to list all the children recursively of the current PSdrive, folder, or registry key.
Get-ChildItem -rec -forceUse this command To include the hidden folders (directories).
(Get-ChildItem).name or Get-ChildItem -nameRun any of these commands to get the list file and directory names in the current folder.
(Get-ChildItem).countUse this command to get the number of entries in the collection of objects returned by the Get-Children.

PSdrives

PSdrives are the collection of entities grouped together so they can be accessed as a filesystem drive. The “PSprovider” does this grouping.

By default, a PS session can access several PSdrives including c:, env:, alias:, and HKLM:, where c: refers to the usual Windows c-drive; env: is the space of Windows environmental variables; alias: is the collection of cmdlet aliases; and HKLM is a hive in the registry.

Any PS session will enter the user’s home folder. If you want to switch from a PS session to another PSdrive and retrieve the information from that drive, consider the following commands:

CommandsDescription
Switching to env-The prompt character will change to the “ENV:\>”. Set-Location env by running the following command: Set-Location env-
Env:\> Get-ChilditemThis command will get you all the environment variables.
Env:\> Get-Childitem userprofileUse this command to get the environment variables of “userprofile.”
Env:\> Set-Location alias:Run the following command to change the prompt character to “Alias.”
Alias:\> Get-ChilditemRun this command to get all the children of all aliases.
Alias:\> Set-Location C:\Use this command to get the “C:/>” prompt again, back to the default drive.
C:\Users\user_name>$alias:lsRun this command to find what alias “ls” stands for.

Pipelines

Cmdlets uses the pipelines to pass the objects but not the character streams like Unix. The pipeline character is | (ASCII 124), followed by a command that handles the output passed through the pipeline. The pipeline consists of the following three stages.

Get-ChildItem *.txt | Where-Object length -lt 1000 | Sort-Object length

The following table highlights some of the basic pipeline commands:

CommandDescription
(Get-Item /Users/praashibansal/Desktop).lastwritetime.yearEasily sets the value of the ‘lastwritetime.year’ property to the present date and time without affecting the file’s content.
(Get-ChildItem data.txt.rtf -name).name # -> nullProvides an empty result
"data.txt.rtf" | Rename-Item -NewName "data_new.txt.rtf"Changes the old file names and file extensions to the new ones
Get-ChildItem data.txt | Rename-Item -new {$_.name}A trivial renaming command that invokes an automatic variable
Get-ChildItem data.txt.rtf -name | Rename-Item -new {$_.name}If the piped object $_ doesn’t have the member property (name), you will receive an error, as parameter $_.name is null
Get-ChildItem | Select-Object basename | Sort-Object *Displays the list of the names of all the files that are present in the current folder sorted in alphabetical order.
Move-Item *.txt subdirectoryMoves all the files to the folder subdirectory
Get-ChildItem *.txt | Move-Item ..\Gives the error message that Move-Item lacks input

Alias

Cmdlets come with several aliases. The following table highlights a few of aliases, along with their descriptions:

CommandDescription
Add-ContentAppends value to a file
Get-ContentFinds file content in an array
Set-LocationChanges folder, key, or PS drive
Clear-HostClears console
Remove-ItemDelete files
Get-ChildItem -Path .\Lists Folder, Key, or PSDrive Children
Write-OutputSends the array to the console, pipeline, or redirect it to the file
Foreach-ObjectTraverses each object in a pipeline
Format-TableFormats the table with selected properties for each object in each column
Format-ListFormats the process properties by name
Get-AliasProvides Cmdlet Alias
Get-CommandProvides you with commands from the current session only
Get-MemberRetrieves all the object members
Get-ItemProperty .\data.txt | Format-ListProvides the specified item’s properties
Get-ItemPropertyValue -Path '.\data.txt' -Name LastWriteTimeGives the current value for a specified property while using the name parameter
Get-Variable m*Finds session variable names and sessions
New-Item -Path .\ -Name "testfile1.txt" -ItemType "file" -Value "This is a text string."Creates a new file, directory, symbolic link, registry key, or registry entry
Get-ProcessGives the entire list of all the running processes
Get-LocationProvides the current directory’s or registry key’s location
Rename-Item -Path “old_name” -NewName “new_name”Renames the old item name with the new name
Remove-Item .\testfile1.txtRemoves the specified directory, files, or registry keys
Remove-VariableRemoves the specified variable
Start-SleepSuspends an activity for a specified period of time

Operators

  • Arithmetic Operators
  • Operator Precedence
  • OperatorDescriptionExample
    +Adds integers; concatenates6 + 2
     strings, arrays, and hash tables.“file” + “name”@(1, “one”) + @(2.0, “two”)@{“one” = 1} + @{“two” = 2}
    +Makes a number out of an object123
    Subtracts one value from another6 – 2
    Calculates the opposite number– -6
      (Get-Date).AddDays(-1)
    *Multiply numbers or copy strings and arrays for a specified number of times6 * 2
      @(“!”) * 4
      “!” * 3
    /Divides two values6 / 2
    PrecedenceOperatorDescription
    1()Parentheses
    2For a negative number or unary operator
    3*, /,
    • Assignment Operators
  • Comparison Operators
  • OperatorDescription
    =Sets a variable’s value to the specified value
    +=Increases a variable’s value by the specified value or appends the specified value to the existing value
    -=Decreases a variable’s value by a specified value
    *=Multiplies a variable’s value by a specified value, or appends the specified value to the existing value
    /=Divides a variable’s value by a specified value
    TypeOperatorComparison test
    Equality-eqequals
     -nenot equals
     -gtgreater than
     -gegreater than or equal
     -ltless than
     -leless than or equal
    Matching-likestring matches wildcard pattern
     -notlikestring doesn’t match wildcard pattern
     -matchstring matches regex pattern
     -notmatchstring doesn’t match regex pattern
    Replacement-replacereplaces strings matching a regex pattern
    Containment-containscollection contains a value
     -notcontainscollection doesn’t contain a value
     -invalue is in a collection
     -notinvalue is not in a collection
    Type-isboth objects are the same type
     -isnotobjects are not the same type
    • Logical Operators
    OperatorDescriptionExample
    -andLogical AND. TRUE when both statements are true.(1 -eq 1) -and (1 -eq 2) FALSE
    -orLogical OR. TRUE when either of the statements is TRUE.(1 -eq 1) -or (1 -eq 2)TRUE
    -xorLogical EXCLUSIVE OR. TRUE when only one statement is TRUE.(1 -eq 1) -xor (2 -eq 2)FALSE
    -notLogical not. Negates the statement that follows.-not (1 -eq 1)FLASE
    !Same as -not!(1 -eq 1)FALSE
    • Redirection Operator
    OperatorDescriptionSyntax
    >Send specified stream to a filen>
    >>Append specified stream to a filen>>
    >&1Redirects the specified stream to the Success streamn>&1
    • Type Operators
    OperatorDescriptionExample
    -isNotReturns TRUE when the input not an instance of thespecified.NET type.(get-date) -isNot [DateTime]FALSE
    -asConverts the input to the specified .NET type.“5/7/07” -as [DateTime]Monday, May 7, 2007 00:00:00

    Some Other Operators

    OperatorDescription
    () Grouping OperatorAllows you to override operator precedence in expressions
    &() Subexpression OperatorGives you the result of one or more statements
    @( ) Array Subexpression OperatorReturns the results of one or more statements in the form of arrays.
    & Background OperatorThe pipeline before & is executed by this command in a Powershell job.
    [] Cast OperatorConverts objects to the specific type.

    Regular Expressions

    A regular expression is a pattern that is used to match text that includes literal characters, operators, and other constructs. PowerShell regular expressions are case-insensitive by default.

    MethodCase Sensitivity
    Select-Stringuse -CaseSensitive switch
    switch statementuse the -casesensitive option
    operatorsprefix with ‘c’ (-cmatch, -csplit, or -creplace)
    • Character Literals

    A regular expression can be a literal character or a string.

    • Character Groups

    These allow you to match any number of characters one time, while [^character group] only matches characters NOT in the group.

    • Character Range

    A pattern can also be a range of characters. The characters can be alphabetic [A-Z], numeric [0-9], or even ASCII-based [ -~] (all printable characters).

    • Numbers

    The \d character class will match any decimal digit. Conversely, \D will match any non-decimal digit.

    • Word Character

    The \w character class will match any word character [a-zA-Z_0-9]. To match any non-word character, use \W.

    • Wildcard

    The period (.) is a wildcard character in regular expressions. It will match any character except a newline (\n).

    • Whitespace

    Whitespace is matched using the \s character class. Any non-whitespace character is matched using \S. Literal space characters ‘ ‘ can also be used.

    • Escaping Characters

    The backslash (\) is used to escape characters so the regular expression engine doesn’t parse them.

    The following characters are reserved: []().\^$|?*+{}.

    > '3.141' -match '3\.\d{2,]'
    True
    • Substitution in Regular Expression.

    The regular expressions with the -replace operator allows you to dynamically replace text using captured text.

    <input> -replace <original>, <substitute>

    Flow Control

    • ForEach-Object

    ForEach-Object is a cmdlet that allows you to iterate through items in a pipeline, such as with PowerShell one-liners. ForEach-Object will stream the objects through the pipeline.

    Although the Module parameter of Get-Command accepts multiple values that are strings, it will only accept them via pipeline input using the property name, or parameter input.

    If you want to pipe two strings by value to Get-Command for use with the Module parameter, use the ForEach-Objectcmdlet:

    $ComputerName = 'DC01', 'WEB01'
    
    foreach ($Computer in $ComputerName) {
        Get-ADComputer -Identity $Computer
    }
    • For

    A “for” loop iterates while a specified condition is true.

    For example:

    for ($i = 1; $i -lt 5; $i++) {
    
    Write-Output "Sleeping for $i seconds"
    
    Start-Sleep -Seconds $i
    
    }
    • Do

    There are two different “do” loops in PowerShell. Do Until runs while the specified condition is false.

    Example 1:

    $number = Get-Random -Minimum 1 -Maximum 10
    
    do {
        $guess = Read-Host -Prompt "What's your guess?"
    
        if ($guess -lt $number) {
            Write-Output 'Too low!'
        } elseif ($guess -gt $number) {
            Write-Output 'Too high!'
        }
    }
    
    until ($guess -eq $number)

    Example 2:

    $number = Get-Random -Minimum 1 -Maximum 10
    
    do {
        $guess = Read-Host -Prompt "What's your guess?"
    
        if ($guess -lt $number) {
            Write-Output 'Too low!'
        } elseif ($guess -gt $number) {
            Write-Output 'Too high!'
        }
    }
    
    while ($guess -ne $number)
    • While

    Similar to the Do While loop, a While loop runs as long as the specified condition is true. The difference however, is that a While loop evaluates the condition at the top of the loop before any code is run. So, it doesn’t run if the condition evaluates to false.

    For example:

    $date = Get-Date -Date 'November 22'
    
    while ($date.DayOfWeek -ne 'Thursday') {
        $date = $date.AddDays(1)
    }
    
    Write-Output $date

    Variables

    PowerShell allows you to store all types of values. For example, it can store command results and command expression elements like names, paths, and settings. Here are some of PowerShell’s different variables.

    • User-created variables: These are created and maintained by the user. The variables you create at the PowerShell command line will only exist until the PowerShell window is open. When you close the PowerShell window, these variables are deleted. If you want to save a variable, you need to add it to your PowerShell profile. You can create variables and declare them with three different scopes: global, script, or local.
    • Automatic variables: These variables store the state of PowerShell and are created by PowerShell. Only PowerShell can change their values as required to maintain accuracy. Users can’t change these variables’ value. For example, the $PSHOME variable will store the path to the PowerShell installation directory.
    • Preference variables: These variables store user preferences for PowerShell and are created by PowerShell. These variables are populated with default values and can be changed by the users. For example, the $MaximumHistoryCount variable specifies the maximum number of entries in the session history.

    To create a new variable, you need to use an assignment statement and assign a value to the variable. There is no need to declare the variable before using it. The default value of all variables is $null.

    For example:

    $MyVariable = 1, 2, 3
    
    $MyVariable

    Function

    • Naming Your Function

    Use a Pascal case name with an approved verb and a singular noun to name a function. You can get a list of approved verbs by running Get-Verb:

    Get-Verb | Sort-Object -Property Verb
    • Creating a Simple Function

    Use a function keyword followed by the function name to create a simple function. Then, use an open and closing curly brace. The function will execute code contained within those curly braces.

    For example:

    function Get-Version {
        $PSVersionTable.PSVersion
    }

    Working with Modules

    A module is a package containing PowerShell members, such as cmdlets, providers, functions, workflows, variables, and aliases. You can implement package members in a PowerShell script, a compiled DLL, or both. PowerShell automatically imports the modules the first time you run any command in an installed module. You can use the commands in a module without setting up or profile configuration.

    • How to Use a Module

    To use any module, you need to first install them. Then, find the command that comes with the module and use them.

    • Installing a Module

    If you get a module as a folder, install it before you use it on the PowerShell command line. Some modules are preinstalled. You can use the following command to create a Modules directory for the current user:

    New-Item -Type Directory -Path $HOME\Documents\PowerShell\Modules

    Copy the entire module folder into the Modules directory. You can use any method to copy the folder, including Windows Explorer, Cmd.exe, and PowerShell.

    • Finding the Installed Modules

    Run the following to find the modules installed in a default module location (not imported).

    Get-Module -ListAvailable
    • Finding Commands in a Module

    Run the following command to find a module’s commands:

    Get-Command -Module <module-name>
    
    Get-Command -Module Microsoft.PowerShell.Archive
    • Importing a Module

    Run the following command with the proper module name:

    Import-Module <module-name>
    • Removing a Module Name

    You can run the following command with the proper module name:

    Remove-Module <module-name>
    • View Default Module Locations

    Use the following command to view default module locations:

    $Env:PSModulePath
    • Add a Default Module Location

    You can use the following command format:

    $Env:PSModulePath = $Env:PSModulePath + ";<path>"
    • Add a Default Module Location on Linux or MacOS

    Use the following to execute the same command as above, only with Linux or macOS:

    $Env:PSModulePath += ":<path>"

    Hash Tables

    A hash table is a complex data structure to store data in the form of key-value pairs. We also refer to a hash table as a dictionary or associative array. To understand a hash table, consider a series of IP addresses and the respective computer names. A hash stores this data in the form of key-value pairs, where IP addresses refer to keys and computer names to their corresponding values.

    The hash table syntax is as follows:@{ <name> = <value>; [<name> = <value> ] …}

    An ordered dictionary’s syntax is as follows:[ordered]@{ <name> = <value>; [<name> = <value> ] …}

    • Creating Hash Tables

    If you want to create a hash table, follow these steps:

    • Start the hash table with an at sign (@) and enclose it in curly braces ({}).
    • A hash table should contain at least one key-value pair, and hence, enter the data after creating a hash table.
    • Separate key from its value using an equal sign (=).
    • Separate the key/value pairs in a hash table with a semicolon (;).
    • Enclose the space between the keys in quotation marks. Values must be valid PowerShell expressions. Also, enclose strings in quotation marks, even if there are no spaces between them.
    • Save a hash table as a variable to manage it efficiently.
    • When assigning an ordered hash table to a variable, place the [ordered] attribute before the @ symbol. If you place it before the variable name, the command fails.

    For example:

    $hash = @{}
    
    $hash = @{ Number = 1; Shape = "Square"; Color = "Blue"}
    
    [hashtable]$hash = [ordered]@{
    
    Number = 1; Shape = "Square"; Color = "Blue"}
    
    $hash
    • Adding and Removing Keys and Values

    To add keys and values to a hash table, use the following command format:

    $hash[“<key>”] = “<value>”

    For example, you can add a “Time” key with a value of “Now” to the hash table with the following statement format:

    $hash["Time"] = "Now"

    Or

    $hash.Add("Time", "Now")

    Or, you can remove the key with this statement format:

    $hash.Remove("Time")

    Asynchronous Event Handling

    These cmdlets allow you to register and unregister event subscriptions and list the existing subscriptions. You can also list pending events and handle or remove them as desired.

    PowerShell eventing cmdlets

    Eventing Cmdlet nameDescription
    Register-ObjectEventThis cmdlet registers an event subscription for events generated by .NET objects
    Register-WmiEventRegisters an event subscription for events generated by WMI objects
    Register-EngineEventRegisters an event subscription for events generated by PowerShell itself
    Get-EventSubscriberGets a list of the registered event subscriptions in the session
    Unregister-EventRemoves one or more of the registered event subscriptions
    Wait-EventWaits for an event to occur. This cmdlet can wait for a specific event or any event. It also allows a timeout to be specified, limiting how long it will wait for the event. The default is to wait forever.
    Get-EventGets pending unhandled events from the event queue
    Remove-EventRemoves a pending event from the event queue
    New-EventThis cmdlet is called in a script to allow the script to add its own events to the event queue

    WordPress asking for FTP credentials

    If you’re asked to enter your FTP credentials when you try to install or update a plugin or theme in the WordPress dashboard, it’s because of a specific setting in the wp-config.php file. Follow the steps below to prevent WordPress from displaying this FTP prompt.

    1. Find the folder with your WordPress files and open the wp-config.php file.
    2. At the bottom of the wp-config.php file, above the line that says 
      /* That's all, stop editing! Happy publishing. */,
      add the following lines of code:
    defined('FS_METHOD')     or define('FS_METHOD', 'direct');
    defined('FS_CHMOD_DIR')  or define('FS_CHMOD_DIR',0755);
    defined('FS_CHMOD_FILE') or define('FS_CHMOD_FILE',0644);

    Power Shell | Inside Powershell

    Language

    Switches

    Basic Syntax

    Let’s start by taking a look at a basic switch statement.

    $i = 1;
    switch ($i)
    {
    1 {
    write-host “one”
    break
    }
    2 {
    write-host “two”
    write-host “two”
    break
    }
    default {
    write-host “other”
    break
    }
    }

    Notice we don’t use the Case: keyword at all.

    The default in PowerShell is to assume -eq is used between your input and typed case value. This means No Case Sensitivity and No Wild Cards:

    switch(“hello”) #will match uppercase
    {
    “HELLO” {write-host “Uppercase” -ForegroundColor Magenta;break}
    “hello” {write-host “lowercase” -ForegroundColor green;break}
    }
    switch(“hello”) #will NOT match h*
    {
    “h*” {write-host “wildcard” -ForegroundColor Magenta;break}
    “hello” {write-host “lowercase” -ForegroundColor green;break}
    }

    Expression Match

    We have a long-hand switch statement that lets us use whatever we want (-eq, -gt, -le, -like, straight up boolean values, etc.)

    Psudo-code:Switch($value) { {<bool expression>} {<code>} {<bool expression>} {<code>} default {<code>} }

    Real:

    switch(“hello”) #will match uppercase
    {
    “HELLO” {write-host “Uppercase” -ForegroundColor Magenta;break}
    “hello” {write-host “lowercase” -ForegroundColor green;break}
    }
    switch(“hello”) #will NOT match h*
    {
    “h*” {write-host “wildcard” -ForegroundColor Magenta;break}
    “hello” {write-host “lowercase” -ForegroundColor green;break}
    }

    Jump Statements aren’t necessary

    C# requires jump statements such as break, goto, or return. PowerShell does not!

    This is one of the coolest features in PowerShell. We actually allow for continuous case- checks.

    This means your switches can actually act more like a bunch of independent if statements. Notice the previous example, without any of the “break statements” and using a number that is less than 5, 10 and 15.

    $num = 4
    Switch($num)
    {
    {$num -lt 5} {write-host “less than 5!” -ForegroundColor Magenta}
    {$num -lt 10} {write-host “less than 10!” -ForegroundColor green}
    {$num -lt 15} {write-host “less than 15!” -ForegroundColor cyan}
    default {write-host “greater than or equal to 15” -ForegroundColor yellow}
    }

    Loops and $_

    It might be common for you to take a bunch of data, do a foreach loop through it and send each value through your switch:

    $nums = 1..15
    foreach($num in $nums)
    {
    Switch($num)
    {
    {$num -lt 5} {write-host “$num is less than 5!” -ForegroundColor Magenta}
    {$num -lt 10} {write-host “$num is less than 10!” -ForegroundColor green}
    {$num -lt 15} {write-host “$num is less than 15!” -ForegroundColor cyan}
    default {write-host “$num is greater than or equal to 15” -ForegroundColor yellow}
    }
    }

    However, PowerShell actually has a loop and $_ built right into your switch so we can chop off the foreach completely:

    $nums = 1..15
    Switch($nums)
    {
    {$_ -lt 5} {write-host “$_ is less than 5!” -ForegroundColor Magenta}
    {$_ -lt 10} {write-host “$_ is less than 10!” -ForegroundColor green}
    {$_ -lt 15} {write-host “$_ is less than 15!” -ForegroundColor cyan}
    default {write-host “$_ is greater than or equal to 15” -ForegroundColor yellow}
    }

    This lets us write some really concise and convenient little code blocks. The nice thing is that if our list has 1 object it still gets handled fine, and if it’s an empty collection it will just skip the whole switch!

    This, however, can lead to some confusion if you try to use “break” since our loop is also the whole switch statement:

    $nums = 1..15
    Switch($nums)
    {
    {$_ -lt 5} {write-host “$_ is less than 5!” -ForegroundColor Magenta;break}
    {$_ -lt 10} {write-host “$_ is less than 10!” -ForegroundColor green;break}
    {$_ -lt 15} {write-host “$_ is less than 15!” -ForegroundColor cyan;break}
    default {write-host “$_ is greater than or equal to 15” -ForegroundColor yellow}
    }

    view rawLoopSwitchSample3.ps1 hosted with ❤ by GitHub

    Uh-oh, not good.

    We also have “continue” in PowerShell and this will stop our current iteration of our loop (or switch) so we can use the looping feature and make it like a bunch of elseifs:

    $nums = 1..15
    Switch($nums)
    {
    {$_ -lt 5} {write-host “$_ is less than 5!” -ForegroundColor Magenta;continue}
    {$_ -lt 10} {write-host “$_ is less than 10!” -ForegroundColor green;continue}
    {$_ -lt 15} {write-host “$_ is less than 15!” -ForegroundColor cyan;continue}
    default {write-host “$_ is greater than or equal to 15” -ForegroundColor yellow}
    }

    Shortcuts

    In addition to the looping, we provide you a few other handy short cuts.

    If you just wanted a basic equality switch, but would want to use -ceq (case sensitivity), -like (wild cards), or -match (regex) we let you do that without writing an expression match via some parameters.

    Notice, weirdly, the parameters must come between the word “switch” and the parenthesis, they won’t work at the end of the parenthesis.

    switch -casesensitive (“hello”) #makes it a -ceq
    {
    “HELLO” {write-host “Uppercase” -ForegroundColor Magenta}
    “hello” {write-host “lowercase” -ForegroundColor green}
    “h*” {write-host “wildcard” -ForegroundColor Magenta}
    }
    switch -wildcard (“hello”) #makes it a -like
    {
    “HELLO” {write-host “Uppercase” -ForegroundColor Magenta}
    “hello” {write-host “lowercase” -ForegroundColor green}
    “h*” {write-host “wildcard” -ForegroundColor Magenta}
    }
    switch -wildcard -CaseSensitive (“hello”) #makes it a -clike
    {
    “HELLO” {write-host “Uppercase” -ForegroundColor Magenta}
    “hello” {write-host “lowercase” -ForegroundColor green}
    “h*” {write-host “wildcard” -ForegroundColor Magenta}
    }
    switch -regex (“hello”) #makes it a -match
    {
    “\w{5}” {write-host “5 characters” -ForegroundColor Magenta}
    “\w{6}” {write-host “6 characters” -ForegroundColor green}
    }

    CommandLets

    • Get-Alias
    • New-Alias
    • Set-Alias
    • Export-Alias
    • Import-Alias 

    Function

    To see the definition of mkdir use

    Get-Content Function:\mkdir

    Daily Azure: Migrate a Storge Account

    TL;DR

    Migration is done via azcopy:

    • download souce container to local folder
    • upload local folder to destination container

    Get AzCopy

    Here is the script install-azcopy.ps1:

    # Download and extract
    
    #
    $URI = "https://aka.ms/downloadazcopy-v10-windows"
    $DST = "~\AppData\Local\Programs\AZCopy\"
    
    Invoke-WebRequest -Uri $URI -OutFile AzCopy.zip -UseBasicParsing
    Expand-Archive ./AzCopy.zip ./AzCopy -Force
    
    # Move AzCopy
    mkdir ~\AppData\Local\Programs\AZCopy
    Get-ChildItem ./AzCopy/*/azcopy.exe | Move-Item -Destination "~\$DEST"
    
    # Add AzCopy to PATH
    $userenv = (Get-ItemProperty -Path 'HKCU:\Environment' -Name Path).path
    $newPath = "$userenv
    New-ItemProperty -Path 'HKCU:\Environment' -Name Path -Value $newPath -Force
    
    # Clean the kitchen
    del -Force AzCopy.zip
    del -Force -Recurse .\AzCopy\

    Copy Folder

    param (
        $FOLDER = "",
    
        [Parameter(Mandatory=$false)]
        [string]$TYPE   = "latest",
    
        [Parameter(Mandatory=$false)]
        [switch]$LOGIN
    )
    
    if ($TYPE -eq "latest") {
        $SRC_ROOT="<latest-folder>"
        $DST_ROOT="latest"
    } else {
        $SRC_ROOT="<history-folder>"
        $DST_ROOT="history"
    }
    
    
    $SRC_ACCCOUNT = "<source storage account>";
    $DST_ACCCOUNT = "<destination storage account>";
    
    $SRC_CONTAINER = "<source container>"
    $DST_CONTAINER = "<destination container>"
    
    
    $SRC_URL      = "https://${SRC_ACCCOUNT}.blob.core.windows.net/$SRC_CONTAINER/$SRC_ROOT/$FOLDER/"
    $DST_URL      = "https://${DST_ACCCOUNT}.blob.core.windows.net/$DST_CONTAINER/$DST_ROOT/"
    
    $TMP_FLDR     = "C:\TMP\Downloads"
    
    Write-Host  "== Copy     '$FOLDER'"
    Write-Host "       from  $SRC_URL"
    Write-Host  "        to  $DST_URL"
    
    #
    
    if ($LOGIN) {
        $ENV:AZCOPY_CRED_TYPE = "OAuthToken";
        $ENV:AZCOPY_CONCURRENCY_VALUE = "AUTO";
    
        azcopy login
    }
    
    Write-Host  "== Download ======================================================"
    Write-Host "       from  $SRC_URL"
    Write-Host  "        to  $TMP_FLDR\$CONTAINER"
    
    azcopy copy         $SRC_URL                                                                                      `
                        $TMP_FLDR                                                                                     `
                        --trusted-microsoft-suffixes=${SRC_ACCCOUNT}.blob.core.windows.net                            `
                        --overwrite=true                                                                              `
                        --check-md5=FailIfDifferent                                                                   `
                        --from-to=BlobLocal                                                                           `
                        --recursive                                                                                   `
                        --log-level=ERROR
    
    # Upload
    Write-Host  "== Upload   ======================================================"
    Write-Host  "      from  $TMP_FLDR\$CONTAINER"
    Write-Host  "        to  $DST_URL"
    
    azcopy copy         $TMP_FLDR\$CONTAINER                         `
                        $DST_URL                                     `
                        --overwrite=true                             `
                        --from-to=LocalBlob                          `
                        --blob-type BlockBlob                        `
                        --follow-symlinks                            `
                        --check-length=true                          `
                        --put-md5                                    `
                        --follow-symlinks                            `
                        --disable-auto-decoding=false                `
                        --recursive                                  `
                        --log-level=ERROR
    

    Call the script

    First call should use -login to authenticate

    .\copy.ps1 demo-folder-1 -login

    Then, following commands dont need the login

    .\copy.ps1 demo-folder-2

    WordPress – Working with CLI

    Working with CLI

    Basic work with posts

    Search post content.

    wp post list --s="text" --fields=ID,post_title,url

    Find posts with ping status “open”.

    wp post list --ping_status="open"

    And if you only want to get the post IDs:

    wp post list --ping_status="open" --fields=ID

    Update ping status to “closed” where the value is “open”.

    wp post update $(wp post list --ping_status="open" --format=ids) --ping_status="closed";

    Search and replace

    Search and replace post content.

    bashwp search-replace "old thing" "new thing" --all-tables

    Post meta

    List all metadata associated with a post.

    bashwp post meta list 1422 --format=json

    Get specific post meta for a post.

    bashwp post meta get 1422 "meta_key" --format=json

    Update post meta.

    bashwp post meta update 1422 "meta_key" "meta_value"

    Update post meta from a file.

    bashwp post meta update 1422 "post_meta" < file.json --format=json

    Delete post meta.

    bashwp post meta delete 1422 "post_meta"

    Delete all post meta by specific key. (With wp db query.)

    bashwp db query "DELETE FROM `wp_postmeta` WHERE `meta_key` = 'NAME_OF_YOUR_META_KEY'"
    

    List posts by meta key or value.

    bashwp post list --fields=ID,post_title,url --meta_key="meta_key"
    wp post list --fields=ID,post_title,url --meta_key="meta_key" --meta_compare="NOT EXISTS"
    wp post list --post_type="post_type" --fields=ID,post_title,url --meta_key="meta_key" --meta_compare="NOT EXISTS"
    wp post list --fields=ID,post_title,url --meta_key="_wp_page_template" --meta_value="page-templates/post-full-grid.php"

    The meta_compare flag also accepts "LIKE" as a value, so that you can do:

    phpwp post list --fields=ID,post_title,url --meta_key='meta_key' --meta_compare='LIKE' --meta_value='value'

    Update meta where it’s missing.

    bashwp post meta update $(wp post list --post_type="post_type" --meta_key="meta_key" --meta_compare="NOT EXISTS" --format=ids) "meta_key" "meta_value"

    Update post meta for all posts in a category.

    bashwp post meta update $(wp post list --category_name="category" --format=ids) "meta_key" "meta_value"

    Save meta value based on an existing meta value. In this example I’m looping through all post with a specific post type and saving the URL of the featured image to the post’s meta.

    bashfor id in $(wp post list --post_type="post_type" --fields=ID --meta_key="meta_key" --meta_compare="NOT EXISTS")
    do
        wp post meta update $id "meta_key" $(wp post meta pluck $(wp post meta get $id _thumbnail_id) _wp_attachment_metadata file)
    done

    Show specific meta value for posts based on a category.

    bashfor id in $(wp post list --post_type="post_type" --fields=ID --category="category name")
    do
        wp post meta get $id "meta_key"
    done

    Export/import all meta.

    bashwp post meta list 1422 --format=json > 1422_meta.json
    wp post update 1422 --meta_input= < 1422_meta.json

    Working with post terms

    Move posts from one tag to another.

    bashfor id in $(wp post list --tag=OLD_TAG --format=ids)
    do
        wp post term remove $id post_tag OLD_TAG --by=slug
        wp post term add $id post_tag NEW_TAG --by=slug
    done
    

    Delete Posts

    Delete all posts from a custom post type. (Adding --force will skip the trash and remove the posts completely.)

    bashwp post delete $(wp post list --post_type='activity' --format=ids) --force

    If you’re trying to delete too many posts at once, you might get an error like this:

    bashPHP Fatal error: Allowed memory size of xxx bytes exhausted

    Or perhaps this one:

    bashArgument list too long

    One way around this is to limit how many posts you’re deleting at once using the posts_per_page option, for example:

    bashwp post delete $(wp post list --post_type='activity' --posts_per_page=50000 --format=ids) --force

    Delete posts with specific meta key.

    bashwp post delete $(wp post list --format=ids --meta_key="meta_key")

    Delete posts with specific meta key and meta value.

    bashwp post delete $(wp post list --format=ids --meta_key="meta_key" --meta_value="meta_value")

    Delete posts where a specific meta key is missing.

    bashwp post delete $(wp post list --format=ids --meta_key="meta_key" --meta_compare="NOT EXISTS")

    Post revisions

    List all revisions.

    bashwp post list --post_type=revision

    List revisions for a specific post.

    bashwp post list --post_parent=1422 --post_type=revision

    Get more info on revisions for a specific post.

    bashfor id in $(wp post list --post_parent=1422 --post_type=revision --fields=ID)
    do
        wp post get $id
    done

    Site Options

    Change the site URL.

    bashwp option update home 'https://example.com'
    wp option update siteurl 'https://example.com'

    Plugins

    List active plugins.

    bashwp plugin list --status=active

    Activate/deactivate plugins.

    bashwp plugin activate plugin-1 plugin-2 plugin-3
    wp plugin deactivate plugin-1 plugin-2 plugin-3

    Users

    Update user password.

    wp user update USER_ID --user_pass="newpassword"

    WP CLI cheatsheet

    check database size

    Returns sizes of all database tables in a human friendly format.

    Reference:https://developer.wordpress.org/cli/commands/db/size/

    wp db size --human-readable --tables

     copy

    check db status

    Run health check on the database set in the wp-config.php file. It reports status of each database table separately in the output.

    Reference:https://developer.wordpress.org/cli/commands/db/check/

    wp db check

     copy

    check for updates

    Checks if WP-CLI is due for an update.

    wp cli check-update

     copy

    check version

    Return WP CLI version.

    wp cli version

     copy

    configure wordpress

    Creates config.php file. Requires mysql cli to be installed.

    wp config create --dbname=yourdbname --dbuser=root --prompt=dbpassword

     copy

    count all posts

    This command searches for all posts in the database and returns the count number.

    Reference:https://developer.wordpress.org/cli/commands/post/list/

    wp post list --format=count 

     copy

    download wordpress

    Download latest version of WordPress core files to current directory.

    wp core download

     copy

    edit config

    Opens wp-config.php file in the default text editor.

    wp config edit

     copy

    export

    Exports WXR file containing XML formatted data about your site including posts, comments and information about images and other attachments. Site option settings are excluded.

    Reference:https://developer.wordpress.org/cli/commands/export/

    wp export

     copy

    export single page

    By combining the following flags you can export a single page from WordPress. First set the post type you want to export (page) then set the ID of the post, and finally limit the command to only fetch a single post. Skipping comments is optional.

    Reference:https://developer.wordpress.org/cli/commands/export/

    wp export --skip_comments --post_type=page --post__in=4995 --max_num_posts=1

     copy

    generate salts

    This command will generate authentication unique keys and salts in your wp-config.php file.

    Reference:https://developer.wordpress.org/cli/commands/config/shuffle-salts/

    wp config shuffle-salts

     copy

    get media image sizes

    List all defined image sizes, their width, height and the crop details.

    Reference:https://developer.wordpress.org/cli/commands/media/image-size/

    wp media image-size

     copy

    import

    Imports WXR files.

    Reference:https://developer.wordpress.org/cli/commands/import/

    wp import yoursiteexample.wordpress.2021-09-22.000.xml

     copy

    import to sub-site

    You can import WXR data files to specific site in the multi-site installation. The –url flag identifies the site you want to migrate data to. Skipping authors is optional.

    Reference:https://developer.wordpress.org/cli/commands/import/

    wp import yoursiteexample.wordpress.2021-10-15.000.xml --authors=skip --url=http://yoursite.com/subsite

     copy

    install plugin

    Install a plugin in your WordPress site. By passing –activate flag you can enable your new plugin in one command.

    wp plugin install [pluginhandle] --activate

     copy

    list all pages

    This command is based on the “wp post list” used to return all posts but the “–post_type=page” flag changes the search scope to return only pages. By default the output if formatted as a table and includes page ID, title, slug, creation date, and the status.

    Reference:https://developer.wordpress.org/cli/commands/post/list/

    wp post list --post_type=page

     copy

    list all post meta

    Use post ID to return all related meta data. By default it returns data as a table but other formats are available, for example you can use this flag –format=json to get data as json.

    Reference:https://developer.wordpress.org/cli/commands/post/meta/list/

    wp post meta list <ID>

     copy

    list custom post type

    Returns a table of custom posts with a type specified using the –post_type flag.

    Reference:https://developer.wordpress.org/cli/commands/post/list/

    wp post list --post_type=movie

     copy

    list database table columns

    Lists all columns in a given database table. You will need to pass a table name as the argument. List of the default WordPress tables – wp_commentmeta, wp_comments, wp_links, wp_options, wp_postmeta, wp_posts, wp_term_relationships, wp_term_taxonomy, wp_termmeta, wp_terms, wp_usermeta, wp_users.

    Reference:https://developer.wordpress.org/cli/commands/db/columns/

    wp db columns {tabel name}

     copy

    list database tables

    Lists all tables in the database connected to your site.

    Reference:https://developer.wordpress.org/cli/commands/db/tables/

    wp db tables

     copy

    list post types

    Returns a table of all post types including custom posts.

    Reference:https://developer.wordpress.org/cli/commands/post-type/

    wp post-type list

     copy

    list posts

    Returns a table of all posts including ID, title, name, date and status.

    Reference:https://developer.wordpress.org/cli/commands/post/list/

    wp post list

     copy

    list sites

    If you’re running a multi-site WordPress installation you can return a handy table presenting blog ID, URL, and update dates of each site instance.

    Reference:https://developer.wordpress.org/cli/commands/site/list/

    wp site list

     copy

    list taxonomies

    Returns a table of all registered taxonomies including categories, post tags, navigation menus, themes, custom taxonomies and more.

    Reference:https://developer.wordpress.org/cli/commands/taxonomy/list/

    wp taxonomy list

     copy

    maintenance-mode activate

    Puts your site in a maintenance mode and returns “Briefly unavailable for scheduled maintenance. Check back in a minute.” message with a 503 server response.

    wp maintenance-mode activate

     copy

    maintenance-mode deactivate

    Takes your site out of maintenance mode.

    wp maintenance-mode deactivate

     copy

    maintenance-mode status

    Returns maintenance mode status of your site.

    wp maintenance-mode status

    open mysql cli

    Connects to the database set in your wp-config.php file using MySQL CLI.

    Reference:https://developer.wordpress.org/cli/commands/db/cli/

    wp db cli

    optimize database

    Runs MySQL optimizer on the connected database.

    Reference:https://developer.wordpress.org/cli/commands/db/optimize/

    wp db optimize

    regenerate thumbnails

    Regenerate all thumbnail image sizes stored in the media library. The –yes flag confirms your choice.

    wp media regenerate --yes

     copy

    scaffold plugin

    This command will generate basic files and structure for a new plugin. Use –skip-tests flag to omit php unit tests in the process.

    Reference:https://developer.wordpress.org/cli/commands/scaffold/plugin/

    wp scaffold plugin your-plugin-slug

     copy

    scaffold theme

    Generates un-styled main theme with all the necessary files and views to display content.

    Reference:https://developer.wordpress.org/cli/commands/scaffold/_s/

    wp scaffold _s your-theme-slug --theme_name="Theme Name" --author="Your Name"

     copy

    search string in DB

    You can search for a string in connected WordPress database. The –stats flag will append details about the search like matches found and tables searched.

    Reference:https://developer.wordpress.org/cli/commands/db/search/

    wp db search <string_to_find> --stats

    update all plugins

    Updates all installed plugins.

    wp plugin update --all

    update wp-cli

    Update WP-CLI to the latest version.

    wp cli update

    wp-cli info

    Prints information to the console about WP CLI and its environment such as version, OS, PHP, MySQL.

    JQ – Cheatsheet

    Installing jq

    On Mac OS

    brew install jq

    Useful arguments

    When running jq, the following arguments may become handy:

    ArgumentDescription
    --versionOutput the jq version and exit with zero.
    --sort-keysOutput the fields of each object with the keys in sorted order.

    Basic concepts

    The syntax for jq is pretty coherent:

    SyntaxDescription
    ,Filters separated by a comma will produce multiple independent outputs
    ?Will ignores error if the type is unexpected
    []Array construction
    {}Object construction
    +Concatenate or Add
    Difference of sets or Substract
    lengthSize of selected element
    |Pipes are used to chain commands in a similar fashion than bash

    Dealing with json objects

    DescriptionCommand
    Display all keysjq 'keys'
    Adds + 1 to all itemsjq 'map_values(.+1)'
    Delete a keyjq 'del(.foo)'
    Convert an object to arrayto_entries &#124; map([.key, .value])

    Dealing with fields

    DescriptionCommand
    Concatenate two fieldsfieldNew=.field1+' '+.field2

    Dealing with json arrays

    Slicing and Filtering

    DescriptionCommand
    Alljq .[]
    Firstjq '.[0]'
    Rangejq '.[2:4]'
    First 3jq '.[:3]'
    Last 2jq '.[-2:]'
    Before Lastjq '.[-2]'
    Select array of int by valuejq 'map(select(. >= 2))'
    Select array of objects by value** jq ‘.[] | select(.id == “second”)’**
    Select by type** jq ‘.[] | numbers’ ** with type been arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars

    Mapping and Transforming

    DescriptionCommand
    Add + 1 to all itemsjq 'map(.+1)'
    Delete 2 itemsjq 'del(.[1, 2])'
    Concatenate arraysjq 'add'
    Flatten an arrayjq 'flatten'
    Create a range of numbersjq '[range(2;4)]'
    Display the type of each itemjq 'map(type)'
    Sort an array of basic typejq 'sort'
    Sort an array of objectsjq 'sort_by(.foo)'
    Group by a key – opposite to flattenjq 'group_by(.foo)'
    Minimun value of an arrayjq 'min' .See also min, max, min_by(path_exp), max_by(path_exp)
    Remove duplicatesjq 'unique' or jq 'unique_by(.foo)' or jq 'unique_by(length)'
    Reverse an arrayjq 'reverse'

    XAMPP – Setup HTTPS/SSL localhost on macOS

    Original Post from here

    Preparation

    1. Check XAMPP SSL config

    Open /Applications/XAMPP/xamppfiles/etc/httpd.conf and make sure your settings are the same as below:

    LoadModule socache_shmcb_module lib/httpd/modules/mod_socache_shmcb.so
    LoadModule ssl_module modules/mod_ssl.so
    <IfModule ssl_module>
        <IfDefine SSL>
            Include etc/extra/httpd-ssl.conf
        </IfDefine>
    </IfModule>

    Test SSL config with this command:

    sudo /Applications/XAMPP/xamppfiles/xampp enablessl

    2. Backup httpd-ssl.conf

    • Go to: /Applications/XAMPP/xamppfiles/etc/extra
    • Copy httpd-ssl.conf & paste as httpd-ssl.conf.bak

    3. Edit httpd-ssl.conf

    • Open /Applications/XAMPP/xamppfiles/etc/extra/httpd-ssl.conf
    • Change default port from 8443 to 443
    #Listen 8443
    Listen 443
    • Find this line and remove everything below it
    ## SSL Virtual Host Context

    Setup HTTPS/SSL localhost

    Open Terminal

    4. Create SSL folder to store SSL files

    cd
    /Applications/XAMPP/xamppfiles/etc/
    mkdir ssl
    cd ssl

    5. Create SSL CSR & private key

    You can use any file name here (just replace localhost)

    openssl req -new -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.csr

    Enter info as below. Note: change localhost to your localhost domain name (ex: www.domain.name)

    Country Name (2 letter code) [AU]:VN
    State or Province Name (full name) [Some-State]:HCM
    Locality Name (eg, city) []:HCM
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:VN
    Organizational Unit Name (eg, section) []:VN
    Common Name (e.g. server FQDN or YOUR name) []:<strong>localhost</strong>
    Email Address []:abc@gmail.com

    There are 2 more information may be asked:

    • A challenge password
    • An optional company name

    Leave this information BLANK (just Enter, no need to input anything)

    6. Create .ext file

    touch localhost.ext

    Copy & paste below content to v3.ext file

    Note: change localhost to your localhost domain name

    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = localhost

    7. Create SSL CRT

    openssl x509 -req -sha256 -extfile localhost.ext -days 3650 -in localhost.csr -signkey localhost.key -out localhost.crt

    8. Add SSL CRT to macOS Keychain

    • Double click on localhost.crt on Finder
    • Select Keychain: System then click Add
    XAMPP - Setup HTTPS/SSL localhost on macOS
    • Find & double click on localhost cert in Keychain Access
    • Expand Trust, select When using this certificates: Always Trust
    XAMPP - Setup HTTPS/SSL localhost on macOS
    • Close the window and click Update Settings

    9. Config SSL in XAMPP virtual host

    Open /Applications/XAMPP/xamppfiles/etc/extra/httpd-vhosts.conf

    Update your config:

    from

    <VirtualHost *:80>
    	ServerName localhost
    	DocumentRoot "/Applications/XAMPP/xamppfiles/htdocs"
    </VirtualHost>

    to

    <VirtualHost *:443>
    	ServerName localhost
    	DocumentRoot "/Applications/XAMPP/xamppfiles/htdocs"
    
    	SSLEngine on
    	SSLCertificateFile "/Applications/XAMPP/xamppfiles/etc/ssl/localhost.crt"
    	SSLCertificateKeyFile "/Applications/XAMPP/xamppfiles/etc/ssl/localhost.key"
    </VirtualHost>

    10. Open Chrome and access https://localhost.

    WSL: Wrong Date

    When checking the date in WSl, it display the wrong date

    ❯ date
    Wed Jul 26 15:28:20 CEST 2023

    So setup the correct date, you could run either

    ❯ sudo hwclock -s

    or setup a timesync daemon (described here)

    Add these lines to the /etc/wsl.conf (note you will need to run your editor with sudo privileges, e.g: sudo nano /etc/wsl.conf):

    [boot]
    systemd=true
    

    And close out of the nano editor using CTRL+O to save and CTRL+X to exit. Now close your WSL distro windows and run wsl.exe --shutdown from PowerShell, then restart your WSL instance. Upon launch you should have systemd running.

    Now install systemd-timesyncd:

    sudo apt install systemd-timesyncd
    sudo systemctl edit systemd-timesyncd
    

    In the second step, when editing, add the two lines beginning with [Unit], as shown below:

    Now start it:

    sudo systemctl start systemd-timesyncd
    

    Check status with:

    timedatectl status
    timedatectl timesync-status

    Angular | Working with Angular Examples

    General

    On the Angular Website, there are a lot of examples.

    You could download each of them and look around. In this post, i will show you to do this at once for all examples.

    So, we will

    • get list of all examples
    • download zip files of examples
    • extract examples

    Preparation

    First, we define some variables for the Chrom Browser and the resulting output files.

    # Mac OS
    CHROME=/Applications/Chromium.app/Contents/MacOS/Chromium
    
    # Windows WSL
    CHROME='/mnt/c/Program Files/Google/Chrome/Application/chrome.exe'
    
    LISTOFZIPS=listofzips

    Download List of examples

    Next, we will download the list of examples from https://angular.io/guide/example-apps-list.

    This is not a static html file. The list will be created dynamically when viewing the page. So, only download the page with wget or curl does not help, because we need to run the JavaScript code in the browser to create the list.

    Therefore, we will use Chrome in headless mode: Load the page and dump the contents of the page (dom) into a file

    do_get_list() {
            "$CHROME" --headless --dump-dom https://angular.io/guide/example-apps-list | tr '>' '>\n ' >${LISTOFZIPS}.html
    
            echo "##. Download List of Examples"
            echo "    #Examples: ($(grep 'href="guide/' listofzips.html | wc -l))"
    }

    Then, we will extract all the links to the zip examples files.

    A quick look into the html file shows, that the html code with the links looks like this:

    We need the part in the href of the <a tag.

    • First, we will split the html file, so that every html tag will be on a separate line.
    • Then, we will cut out only the parts between apostrophes.
    • Then, we search all files containing “.zip” and the end of the line ($)
    do_extract() {
            cat ${LISTOFZIPS}.html                                          |\
            tr ' ' '\n'                                                     |\
            cut -d \" -f2                                                   |\
            grep -e '.zip$'                                                 > ${LISTOFZIPS}
    
            echo "generated/zips/component-overview/component-overview.zip" >> ${LISTOFZIPS}
    
            echo "##. Extract zip files ($(wc -l ${LISTOFZIPS}))"
            echo "    #Examples: ($(wc -l ${LISTOFZIPS}))"
    }

    The result will be the list of URL’s for each example.

    Download Examples

    Next, for each of these example $ZIP, we will download the zip from the Angular Website with wget -q https://angular.io/$ZIP

    do_download() {
            echo "##. Download Zips"
    
            (
                    rm    -rf zip
                    mkdir -p  zip
                    cd        zip
    
                    cat ../$LISTOFZIPS | while read ZIP
                    do
                            echo "Download $ZIP"
                            if [ ! -f $ZIP ]; then
                                    wget -q https://angular.io/$ZIP
                            fi
                    done
    
                    rm *.zip.1
            )
    }

    Extract ZIP Files

    do_unzip() {
            echo "##. Unzip"
    
            rm    -rf src
            mkdir -p  src
    
            find zip -type f -exec basename {} \; | \
            while read FILE
            do
                    FLDR=${FILE/.zip/}
                    echo unzip zip/$FILE -d src/$FLDR
                    unzip zip/$FILE -d src/$FLDR
            done
    }

    Upgrade all node modules to current version

    We will need toe tool npm-check-updates for this.

    Install it with

    npm install -g npm-check-updates

    ncu updates all packages to the latest version. Some Angular Examples require an earlier version of Typescript, so, after upgrade i changes the Typescript Version to 4.9.5

    do_upgrade() {
    	echo "##. Upgrade"
    
    	(
    		cd src
    		ls | \
    		while read FLDR
    		do 
    			echo "     $FLDR"
    			(
    				cd $FLDR
    				ncu -u
    				#     "typescript": "~4.9.3"
    				sed -i '1,$s/"typescript": ".*"/"typescript": "~4.9.5"/' package.json
    				# pnpm install
    			)
    		done
    	)
    }

    Appendix

    The code for the complete script is here:

    #!/bin/bash
    
    # Mac OS
    CHROME=/Applications/Chromium.app/Contents/MacOS/Chromium
    
    # Windows WSL
    CHROME='/mnt/c/Program Files/Google/Chrome/Application/chrome.exe'
    
    LISTOFZIPS=listofzips
    
    do_get_list() {
            "$CHROME" --headless --dump-dom https://angular.io/guide/example-apps-list | tr '>' '>\n ' >${LISTOFZIPS}.html
    
            echo "##. Download List of Examples"
            echo "    #Examples: ($(grep 'href="guide/' listofzips.html | wc -l))"
    }
    
    do_extract() {
            cat ${LISTOFZIPS}.html                                          |\
            tr ' ' '\n'                                                                     |\
            cut -d \" -f2                                                           |\
            grep -e '.zip$'                                                         > ${LISTOFZIPS}
    
            echo "generated/zips/component-overview/component-overview.zip" >> ${LISTOFZIPS}
    
            echo "##. Extract zip files ($(wc -l ${LISTOFZIPS}))"
            echo "    #Examples: ($(wc -l ${LISTOFZIPS}))"
    }
    
    do_download() {
            echo "##. Download Zips"
    
            (
                    rm    -rf zip
                    mkdir -p  zip
                    cd        zip
    
                    cat ../$LISTOFZIPS | while read ZIP
                    do
                            echo "Download $ZIP"
                            if [ ! -f $ZIP ]; then
                                    wget -q https://angular.io/$ZIP
                            fi
                    done
    
                    rm *.zip.1
            )
    }
    
    do_unzip() {
            echo "##. Unzip"
    
            rm    -rf src
            mkdir -p  src
    
            find zip -type f -exec basename {} \; | \
            while read FILE
            do
                    FLDR=${FILE/.zip/}
                    echo unzip zip/$FILE -d src/$FLDR
                    unzip zip/$FILE -d src/$FLDR
            done
    }
    
    do_upgrade() {
    	echo "##. Upgrade"
    
    	(
    		cd src
    		ls | \
    		while read FLDR
    		do 
    			echo "     $FLDR"
    			(
    				cd $FLDR
    				ncu -u
    				#     "typescript": "~4.9.3"
    				sed -i '1,$s/"typescript": ".*"/"typescript": "~4.9.5"/' package.json
    				# pnpm install
    			)
    		done
    	)
    }
    
    
    case "$1" in
            "get")       do_get_list;;
            "extract")   do_extract;;
            "download")  do_download;;
            "unzip")     do_unzip;;
            "upgrade")   do_upgrade;;
            *)
    
                    echo "run $0 get|extract|download|unzip";;
    esac
    Copyright © 2024 | Powered by WordPress | Aasta Blog theme by ThemeArile