Categories
Experiment PowerShell Pwsh7+

Experiments of 2022-04

FdFind, Ansi Colors with Group-Object

# [3] main + UX for long exxtensions + Horizontal rules
fd --color=always --changed-within=10hours
| group { 
    $strExt = $_ | StripAnsi | gi | % Extension
    # QOL: don't let massive names break the table
    if($strExt.Length -gt 10) { $strExt.Substring(0, 10) } else {$strExt}
}
| %{ $_ ; hr }
| ft -AutoSize
# [1] Minimum required
fd --color=always --changed-within=10hours
| group { $_ | StripAnsi | gi | % Extension }
| ft -AutoSize
# [2] UX: Don't let super long extensions break break columns
fd --color=always --changed-within=10hours
| group {
    $strExt = $_ | StripAnsi | gi | % Extension
    if($strExt.Length -gt 10) { $strExt.Substring(0, 10) } else {$strExt}
}
| ft -AutoSize

Using wt‘s Parameters

https://github.com/Ninmonkey.Console/WtThemeTest
PS> ZD-Invoke-WtThemeTest -Random
PS> wt -w theme-test new-tab --title "Tango Light" --profile 'pwsh_nop' --colorScheme "Tango Dark"
PS> wt -w theme-test new-tab --title "Tango Light" --profile 'pwsh_nop' --colorScheme "BirdsOfParadise"

# or
ZD-Invoke-WtThemeTest -Random

Nested Formatting in Powershell

Using module Pansies
What not to do 🙂

CLI bat to preview results

# For every file fd finds, print the first 15 lines
PS> fd --exec-batch bat --line-range=:15 --paging=always

# forcing paging /on/off
PS> fd --exec-batch bat --line-range=:15 --paging=never

Regex Lazy vs Greedy Expressions

Using CSS Selectors

selector 'div.premium-box span.btn.btn-info'

Autocomplete changes based on the first Argument

Parsing Stdout Whitespace

Grouping On Errors

Type Resolution Is Scoped

Pwsh🐒> # test whether it's resolved by coerce to [type]
    'catman' -as 'type' -is 'type'
    'batman' -as 'type' -is 'type'
True
False
Pwsh🐒> # test whether it's resolved by coerce to [type]
    'catman' -as 'type' -is 'type'
    'batman' -as 'type' -is 'type'
True
False


# after 

Pwsh🐒> @(
    # Declaring a new type in inside a [ScriptBlock]
    & {
        class batman { [string]$Name }
        [batman]
    }

    # verses dotsourcing a type into the current scope
    . {
       class catman { [string]$Name }
       [catman]
    }) | ft -AutoSize

   Namespace: <4cf9efd5>

Access Modifiers Name   BaseType
------ --------- ----   --------
public class     batman object

   Namespace: <f2200555>

Access Modifiers Name   BaseType
------ --------- ----   --------
public class     catman object
Categories
Command Line Experiment Formatting Power BI Power Query VS Code

Experiments of 2021-10

Pwsh: Fuzzy Select Colors With Preview

PS> Get-ChildItem fg: | Where Name -match ‘red’
  • queries the color provider with partial matches
  • pipes to Out-Fzf or fzf for the preview and selection

Bitwise operators

Generated using a Pwsh script

ShouldProcess formatting

More Fzf

PSReadline: Auto-expand Aliases in the CLI

  • alt+shift+( surrounds selection, or the entire command in parenthesis
  • alt+shift+% runs Invoke-Formatter to format the code, including alias replacement

Pester5 ForEach | `code` snippet

Using Notebooks: for Github issue queries

Created a list of queries for the release of https://vscode.dev
ninmonkey/VS Code on the Web – Cheat Sheet – Custom urls.md

Power Query Web.Contents wrapper for Web API / REST calls

  • WebRequest_Simple.pq
  • enables ManualStatusHandling for better errors ( This is important for any REST APIs)
  • detects whether it’s Json or html, and returns a json record if existing
  • Always displays the response as plain-text as response_text
  • Lets you inspect request info, like headers used.

Power Query: Import from an external file

Experimenting with console formatting

Select a ton of properties, saving names as an array

Hashtables: Command line formatting

DAX: Syntax highlight bracket pairs



    "[dax-language]": {
        "editor.bracketPairColorization.enabled": true, //colorize the pairs
        "editor.guides.bracketPairs": true, // colorize vertical lines
        "editor.matchBrackets": "always",
        "editor.minimap.enabled": false,
        "editor.lineNumbers": "off",
    },
},

Pwsh: Prompt that summarizes recent errors

Pwsh: Colorized Directory Listing

  • Using terminal wt, Pwsh as the shell, and module: pansies for color
  • The current directory is a gradient, the boldest part is the most important part of the path.
  • cd-ing to a directory will summarize the new directory, without “spamming” the user when there’s a lot of items
    • Folders first, sorted by most recently modified
    • Files second, sorted most recently
    • Icon shows filetype

DAX: Conditionally Toggle Button using Measure

WordPress Image scaling

link to 1:1 image
link to 1:1 image
Categories
Command Line

Improving ‘diff’ readability on Windows | Tip

The output of diff -q path1 path2 is pretty verbose. This function

  • Converts full paths to relative
  • Differences are red.

Missing ‘diff’ ?

If git is installed, you may need to update your %PATH% environment variable.

# in your profile
$Env:Path = "$Env:ProgramFiles\Git\usr\bin", $Env:Path -join ';'

Stand-Alone function Compare-Directory

This is an isolated version of <a href="https://github.com/ninmonkey/Ninmonkey.Console">Ninmonkey.Console: Compare-Directory</a> . I removed all dependencies except coloring is provided by the module PoshCode/Pansies.

function Invoke-NativeCommand {
    <#
    .synopsis
        wrapper to both call 'Get-NativeCommand' and invoke an argument list
    .example
        PS> # Use the first 'python' in path:
        Invoke-NativeCommand 'python' -Args '--version'
    #>

    param(
        # command name: 'python' 'ping.exe', extension is optional
        [Parameter(Mandatory, Position = 0)]
        [string]$CommandName,

        # Force error if multiple  binaries are found
        [Parameter()][switch]$OneOrNone,

        # native command argument list
        [Alias('Args')]
        [Parameter(Position = 1)]
        [string[]]$ArgumentList
    )

    $binCommand = Get-NativeCommand $CommandName -OneOrNone:$OneOrNone -ea Stop
    & $binCommand @ArgumentList
}

function Compare-Directory {
    <#
    .SYNOPSIS
    Compare Two directories using 'diff'
    .EXAMPLE
    Compare-Directory 'c:\foo' 'c:\bar\bat'
    #>
    [Alias('DiffDir')]
    param(
        # Path1
        [Parameter(Mandatory, Position = 0)]
        [string]$Path1,

        # Path2
        [Parameter(Mandatory, Position = 1)]
        [string]$Path2,

        # Output original raw text?
        [Parameter()][switch]$OutputRaw
    )

    $Base1 = $Path1 | Get-Item -ea Stop
    $Base2 = $Path2 | Get-Item -ea Stop
    $Label1 = $Base1 | Split-Path -Leaf | New-Text -fg 'green'
    $Label2 = $Base2 | Split-Path -Leaf | New-Text -fg 'yellow'

    "Comparing:
        Path: $Path1
        Path: $Path2
    " | Write-Information

    $stdout = Invoke-NativeCommand 'diff' -args @(
        '-q'
        $Base1
        $Base2
    )

    $outColor = $stdout
    $outColor = $outColor -replace [regex]::Escape($path1), $Label1
    $outColor = $outColor -replace [regex]::Escape($path2), $Label2
    $outColor = $outColor -replace 'Only in', (New-Text 'Only In' -fg 'red')
    $outColor = $outColor -replace 'Differ', (New-Text 'Differ' -fg 'red')

    if ($OutputRaw) {
        h1 'Raw' | Write-Information
        $stdout
        return
    }

    $outColor
}

function Get-NativeCommand {
    <#
    .synopsis
        wrapper that returns Get-Item on a native command
    .example
        # if you want an error when multiple options are found
        PS> Get-NativeCommand python -OneOrNone
    .example
        # note: this is important, $cmdArgs to be an array not scalar for '@' usage
        $binPy = Get-NativeCommand python
        $cmdArgs = @('--version')
        & $binPy @cmdArgs
    .example
    #>
    [cmdletbinding()]
    param(
        # Name of Native .exe Application
        [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
        [object]$CommandName,

        # One or None: Raise errors when there are more than one match
        [Parameter()][switch]$OneOrNone
    )

    process {
        try {
            $query = Get-Command -Name $CommandName -All -CommandType Application -ea Stop
            | Sort-Object Name

        } catch [CommandNotFoundException] {
            Write-Error "ZeroResults: '$CommandName'"
            return
        }

        if ($OneOrNone -and $query.Count -gt 1) {
            $query | Format-Table -Wrap -AutoSize -Property Name, Version, Source
            Write-Error "OneOrNone: Multiple results for '$CommandName'"
            return
        }

        if ($query.Count -gt 1) {
            $query = $query | Select-Object -First 1
        }

        Write-Debug "Using Item: $($query.Source)"
        $query
    }
}
Categories
Command Line PowerShell Quick Tips References And Cheat Sheets

Easy way to cache results on the Command Line | Power Shell Tip

Sometimes you’ll need to run a command with the same input with different logic.
This can be a hassle using a slow command like Get-ADUser or Get-ChildItem on a lot of files like ~ (Home) with -Depth / -Recurse

ls ~ -Depth 4 | Format-Table Name

PowerShell 7.0+

Powershell 7 added the Ternary Operator, and several operators for handling $null values.

All of these examples will only run Get-ChildItem the first time. Any future calls are cached.

Null-Coalesce ??= Assignment Operator

This is my favorite on the Command line. The RHS (Right Hand Side) skips evaluation if the left side is not $null

$AllFiles ??= ls ~ -Depth 4

Using the Null-Coalesce ?? Operator

$AllFiles = $AllFiles ?? ( ls ~ -Depth 4  )

Ternary Operator ? whenTrue : WhenFalse

$allFiles = $allFiles ? $allFiles : ( ls ~ -Depth 4 )

Windows PowerShell and Powershell < 7

Windows Powershell can achieve the same effect with an if statement

if(! $AllFiles) { $AllFiles = ls ~ -Depth 4 }